⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dasmdlg.cpp

📁 自己写的一个调试器模型的源码, 有单步功能和反汇编引擎.
💻 CPP
字号:
// DasmDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Dasm.h"
#include "DasmDlg.h"
#include "Disasm.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

HHOOK g_hookKey;
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDasmDlg dialog

CDasmDlg::CDasmDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CDasmDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CDasmDlg)
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CDasmDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDasmDlg)
	DDX_Control(pDX, IDC_LIST, m_list);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CDasmDlg, CDialog)
	//{{AFX_MSG_MAP(CDasmDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_COMMAND(IDR_MENU_OPEN, OnMenuOpen)
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
	ON_WM_KEYDOWN()
	ON_COMMAND(IDR_MENU_STEPONE, OnMenuStepone)
	ON_COMMAND(ID_VK_F8, OnVkF8)
	ON_BN_CLICKED(IDC_BTN_STEPF8, OnBtnStepf8)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDasmDlg message handlers

LRESULT CALLBACK MyKeyDown(int nCode, WPARAM wParam, LPARAM lParam)
{

	if (nCode == WM_KEYDOWN)
	{
		if (wParam == VK_F8)
		{
			MessageBox(NULL, "单步步过!", NULL, MB_OK);
		}
	}
	return CallNextHookEx(g_hookKey, nCode, wParam, lParam);

}

BOOL CDasmDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	CMenu Menu;
	Menu.LoadMenu(IDR_MENU_MAIN);
	SetMenu(&Menu);

	InitList();



	

	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CDasmDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CDasmDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CDasmDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CDasmDlg::InitList()
{
	LONG   lStyle;   
	lStyle   =   GetWindowLong(m_list.m_hWnd,   GWL_STYLE);//获取当前窗口style   
	lStyle   &=   ~LVS_TYPEMASK;   //清除显示方式位   
	lStyle   |=   LVS_REPORT;   //设置style   
	SetWindowLong(m_list.m_hWnd,   GWL_STYLE,   lStyle);//设置style   
	
	DWORD   dwStyle   =   m_list.GetExtendedStyle();   
	dwStyle   |=   LVS_EX_FULLROWSELECT;//选中某行使整行高亮(只适用与report风格的listctrl)   
	dwStyle   |=   LVS_EX_GRIDLINES;//网格线(只适用与report风格的listctrl)   
    
	m_list.SetExtendedStyle(dwStyle);   //设置扩展风格 
	
	m_imageList.Create(16,16,TRUE,2,2);
	HICON hIcon = AfxGetApp()->LoadIcon(IDI_ICON1);
	m_imageList.Add(hIcon);
	
	//m_list.SetImageList(&m_imageList,LVSIL_SMALL);
	
	m_font.CreateFont(16, 0,0,0,FW_NORMAL, 0,0,0,
		DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS,
		DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Fixedsys");
	m_list.SetFont(&m_font);
	//------------------------------------------------------------------------------------
	m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
	m_list.SetBkColor(RGB(255,255,255));
	m_list.SetTextColor(RGB(0,0,0));
	m_list.SetTextBkColor(RGB(255,255,255));

	m_list.InsertColumn(0, "", LVCFMT_LEFT, 20);
	m_list.InsertColumn(1, "地址", LVCFMT_LEFT, 100);
	m_list.InsertColumn(2, "机器码", LVCFMT_LEFT, 100);
	m_list.InsertColumn(3, "反汇编", LVCFMT_LEFT, 450);
	m_list.InsertColumn(4, "注释", LVCFMT_LEFT, 200);
	

}

UINT StartDebugThread(void *p)
{
	CDasmDlg *pDlg = (CDasmDlg*)p;
	
	_STARTUPINFOA si;
	_PROCESS_INFORMATION pi;

	WORD Flage;
	DEBUG_EVENT DebugD;
	CONTEXT context;
	BOOL bRet;
	Flage = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS;
	
	
	GetStartupInfo(&si);
	bRet = CreateProcess(pDlg->m_peFile.m_strFileName, NULL, NULL, NULL, FALSE, Flage, NULL, NULL, &si, &pi);
	
	if (bRet == NULL)
	{
		MessageBox(NULL, "建立被调试进程失败!", "Error", MB_OK);
		return 0;
	}


	DWORD rip = 0x00403310;
	BYTE codebuf[30] = {0};
	for (;;)
	{
		if(WaitForDebugEvent(&DebugD, INFINITE))
		{
			switch(DebugD.dwDebugEventCode)
			{
				
			case CREATE_PROCESS_DEBUG_EVENT:
				{	
					pDlg->MessageBox("调试进程已创建!");
					pDlg->m_DebugEvent = DebugD;
					pDlg->m_si = si;
					pDlg->m_pi = pi;

					/*::ReadProcessMemory(pi.hProcess, (LPCVOID)rip, codebuf, 1, NULL);
					codebuf[10] = 0xCC; //int3 机器码
					::WriteProcessMemory(pi.hProcess, (LPVOID)rip, &codebuf[10], 1, NULL);

					pDlg->DasmGoto(rip);*/
					ContinueDebugEvent(DebugD.dwProcessId,DebugD.dwThreadId,DBG_CONTINUE);
				}
				break;
				
			case EXIT_PROCESS_DEBUG_EVENT:
				MessageBox(NULL, "被调试进程终止!", "", MB_OK);
				break;
				
			case EXCEPTION_DEBUG_EVENT:
				{
					switch(DebugD.u.Exception.ExceptionRecord.ExceptionCode)
					{
					case EXCEPTION_BREAKPOINT:
						/*context.ContextFlags = CONTEXT_CONTROL|CONTEXT_INTEGER;
						::GetThreadContext(pi.hThread, &context);
						
						if (context.Eip == rip + 1)
						{
							::ReadProcessMemory(pi.hThread, (LPCVOID)rip, &codebuf[10], 1, NULL);
							if (codebuf[10] == 0xCC)
							{
								pDlg->MessageBox("发现int3");
								context.EFlags |= 0x100;  //开始单步
								context.Eip = rip;	//重新执行
								::WriteProcessMemory(pi.hThread, (LPVOID)rip, codebuf, 1, NULL);
								::SetThreadContext(pi.hThread, &context);
								codebuf[10] = 0x00;
							}
							
						}*/
						/*context.ContextFlags = CONTEXT_CONTROL;
						::GetThreadContext(pi.hThread, &context);
						context.EFlags |= 0x100;  //开始单步
						context.Eip = rip;
						::SetThreadContext(pi.hThread, &context);*/
						ContinueDebugEvent(DebugD.dwProcessId,DebugD.dwThreadId,DBG_CONTINUE);
						
						break;
					case EXCEPTION_SINGLE_STEP:
						/*SuspendThread(pDlg->m_hDebugThread->m_hThread);
						context.ContextFlags = CONTEXT_CONTROL|CONTEXT_INTEGER;
						::GetThreadContext(pi.hThread, &context);
						context.EFlags |= 0x100;
						
						if (context.Eip < 0x60000000)
							pDlg->DasmGoto(context.Eip);
						
						::SetThreadContext(pi.hThread, &context);*/
					     ContinueDebugEvent(pi.dwProcessId,pi.dwThreadId,DBG_CONTINUE);
						
						break;
					}
				}
				break;
			case CREATE_THREAD_DEBUG_EVENT:
				MessageBox(NULL, "创建新线程!\n", "", MB_OK);
				break;
			case EXIT_THREAD_DEBUG_EVENT:
				MessageBox(NULL, "线程退出!\n", "", MB_OK);
				break;
			case RIP_EVENT:
				ContinueDebugEvent(DebugD.dwProcessId,DebugD.dwThreadId, DBG_TERMINATE_PROCESS);
				break;
			default:
				ContinueDebugEvent(DebugD.dwProcessId,DebugD.dwThreadId, DBG_EXCEPTION_NOT_HANDLED);
				break;
			}
		}
	}
	
	CloseHandle(pi.hProcess);
	CloseHandle(pi.hThread);
	return 0;
}

UINT StartDasm(void *p)
{
	CDasmDlg *pDlg = (CDasmDlg*)p;
	pDlg->DasmShow();
	pDlg->ShowToList();

	
	pDlg->m_hDebugThread = AfxBeginThread((AFX_THREADPROC)StartDebugThread, pDlg);	
	return 0;
}

void CDasmDlg::OnMenuOpen() 
{
	// TODO: Add your command handler code here

	m_peFile.OpenFile();

	m_peFile.LoadFile();
	if (!m_peFile.IsPeFile())
	{
		MessageBox("不是有效的PE文件!");
		return;
	}
	
	AfxBeginThread((AFX_THREADPROC)StartDasm, this);	
}

void CDasmDlg::DasmShow()
{
	PIMAGE_FILE_HEADER      pFH=NULL;
	PIMAGE_SECTION_HEADER   pSH=NULL;
	PIMAGE_OPTIONAL_HEADER  pOH=NULL;

	pFH = m_peFile.GetFileHeader();
	pOH = m_peFile.GetOptionalHeader();
	pSH = m_peFile.GetFirstSectionHeader();

	for(int i=0;i<pFH->NumberOfSections;i++)
	{
		char *pOpCode = (char*)(pSH->PointerToRawData + (char*)m_peFile.m_stMapFile.ImageBase);
		HDisasm(pOpCode,pSH->VirtualAddress+pOH->ImageBase,pSH->SizeOfRawData);
		pSH++;
	}
	
	m_peFile.UnLoadFile();
}

void CDasmDlg::HDisasm(LPVOID ImageBase, DWORD Address, DWORD length)
{
	DISASSEMBLY Disasm; // Creates an Disasm Struct
	// Pointer to linear address
	char *Linear="";
	// Index of opcoded to decode
    DWORD Index=0;
	
	DASM_CODE dasmCode;

	
	Linear=(char*)ImageBase;     // Points to the address of array to decode.
    Disasm.Address=Address; // Common Entry Point (usually default..)
    FlushDecoded(&Disasm);     // reset all content
	
	for(Index=0;Index<length;Index++)
    {
		// Decode instruction
        Decode(&Disasm,Linear,&Index);
		
		// Upper case Assembly (Optional)
        CharUpper(Disasm.Assembly);
		// Show Decoded instruction, size, remarks...
        //ShowDecoded(Disasm);

		dasmCode.strAddr.Format("%08X", Disasm.Address);
		dasmCode.strOpcode.Format("%s", Disasm.Opcode);
		dasmCode.strDisassemble.Format("%s", Disasm.Assembly);
		dasmCode.strComment.Format("%d", Disasm.OpcodeSize+Disasm.PrefixSize);

		
		/*
		g_stDisasmList.push_back(Disasm);
		g_stPCHList.push_back(pszaddr);
		g_stPCHList.push_back(pszopcode);
		g_stPCHList.push_back(pszdisassemble);
		g_stPCHList.push_back(pszcomment);
		*/
		AddDasmCode(&dasmCode);

		// Calculate total Size of an instruction + Prefixes, and
		// Fix the address of IP 
        Disasm.Address+=Disasm.OpcodeSize+Disasm.PrefixSize;
		// Clear all information
        FlushDecoded(&Disasm);
    }
}

void CDasmDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default

	CDialog::OnTimer(nIDEvent);
}

void CDasmDlg::AddDasmCode(PDASM_CODE pDasmCode)
{
	m_lstDasmCode.push_back(*pDasmCode);
}

void CDasmDlg::ShowToList()
{
	int i;
	std::list<DASM_CODE>::iterator it;
	for (i = 0, it = m_lstDasmCode.begin(); it != m_lstDasmCode.end(); it++, i++)
	{
		m_list.InsertItem(i, NULL);
		m_list.SetItemText(i, 1, it->strAddr);
		m_list.SetItemText(i, 2, it->strOpcode);
		m_list.SetItemText(i, 3, it->strDisassemble);
		m_list.SetItemText(i, 4, it->strComment);
	}
}

void CDasmDlg::OnButton2() 
{
	int index = FindListString("00402000");
	m_list.EnsureVisible(index + 29, FALSE);
	m_list.EnsureVisible(index, FALSE);
	m_list.SetItemState(index, LVIS_SELECTED, LVIS_SELECTED);
	m_list.SetFocus();
}

int CDasmDlg::FindListString(CString s)
{
	for (int i = 0; i < m_list.GetItemCount(); i++)
	{
		if (s == m_list.GetItemText(i, 1))
		{
			return i;
		}
	}
	return -1;
}

void CDasmDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	// TODO: Add your message handler code here and/or call default
	
	CDialog::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CDasmDlg::OnMenuStepone() 
{
	// TODO: Add your command handler code here
	
}

void CDasmDlg::OnVkF8() 
{
	// TODO: Add your command handler code here
	
}

void CDasmDlg::OnBtnStepf8() 
{
	// TODO: Add your control notification handler code here

	ResumeThread(m_hDebugThread->m_hThread);
	

}

void CDasmDlg::DasmGoto(DWORD addr)
{
	CString s;
	s.Format("%08X", addr);

	int index = FindListString(s);
	if (index != -1)
	{
		m_list.EnsureVisible(index, FALSE);
		m_list.SetItemState(index, LVIS_SELECTED, LVIS_SELECTED);
		m_list.SetFocus();
	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -