最近对调试器的原理感兴趣,自己写了一个简单的demo
打开调试进程:
要调试一个进程,需要在使用CreateProcess打开一个文件时,将第6个参数设为DEBUG_PROCESS。
BOOL WINAPI CreateProcess( _In_opt_ LPCTSTR lpApplicationName, _Inout_opt_ LPTSTR lpCommandLine, _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ BOOL bInheritHandles, _In_ DWORD dwCreationFlags, //设为DEBUG_PROCESS _In_opt_ LPVOID lpEnvironment, _In_opt_ LPCTSTR lpCurrentDirectory, _In_ LPSTARTUPINFO lpStartupInfo, _Out_ LPPROCESS_INFORMATION lpProcessInformation );
例如:
STARTUPINFO sInfo;
PROCESS_INFORMATION pInfo;
ZeroMemory(&sInfo, sizeof(sInfo));
sInfo.cb = sizeof(sInfo);
sInfo.dwFlags = STARTF_USESHOWWINDOW;
sInfo.wShowWindow = SW_SHOWNORMAL;
ZeroMemory(&pInfo, sizeof(pInfo));
CreateProcess(szProcessPath, NULL, NULL, NULL, FALSE, DEBUG_PROCESS, NULL, NULL, &sInfo, &pInfo);
G_Process = pInfo.hProcess;//记录主线程句柄
G_hThread = pInfo.hThread;//记录进程句柄
EnterDebugLoop(); //进入调试循环的函数
调试循环:
对于调试循环,msdn上已经有十分清晰的说明了
https://msdn.microsoft.com/en-us/library/windows/desktop/ms681675(v=vs.85).aspx
我们这里将几个比较重要的事件列举一下
void EnterDebugLoop(const LPDEBUG_EVENT DebugEv) { DWORD dwContinueStatus = DBG_CONTINUE; // exception continuation for(;;) { // Wait for a debugging event to occur. The second parameter indicates // that the function does not return until a debugging event occurs. WaitForDebugEvent(DebugEv, INFINITE); switch (DebugEv->dwDebugEventCode) { case EXCEPTION_DEBUG_EVENT: //异常事件,断点,异常都会触发并在这个事件中处理 switch(DebugEv->u.Exception.ExceptionRecord.ExceptionCode) { case EXCEPTION_ACCESS_VIOLATION: //STATUS_ACCESS_VIOLATION ((DWORD )0xC0000005L) // First chance: Pass this on to the system. // Last chance: Display an appropriate error. break; case EXCEPTION_BREAKPOINT: // ((DWORD )0x80000003L) 即INT3断点 // First chance: Display the current // instruction and register values. break; case EXCEPTION_DATATYPE_MISALIGNMENT: // First chance: Pass this on to the system. // Last chance: Display an appropriate error. break; case EXCEPTION_SINGLE_STEP: // First chance: Update the display of the // current instruction and register values. break; case DBG_CONTROL_C: // First chance: Pass this on to the system. // Last chance: Display an appropriate error. break; default: // Handle other exceptions. break; } break; case CREATE_THREAD_DEBUG_EVENT: //线程建立 dwContinueStatus = OnCreateThreadDebugEvent(DebugEv); break; case CREATE_PROCESS_DEBUG_EVENT: //调试进程建立 dwContinueStatus = OnCreateProcessDebugEvent(DebugEv); break; case EXIT_THREAD_DEBUG_EVENT: //线程退出 // Display the thread‘s exit code. dwContinueStatus = OnExitThreadDebugEvent(DebugEv); break; case EXIT_PROCESS_DEBUG_EVENT: //调试进程退出 // Display the process‘s exit code. dwContinueStatus = OnExitProcessDebugEvent(DebugEv); break; case LOAD_DLL_DEBUG_EVENT: //dll加载 dwContinueStatus = OnLoadDllDebugEvent(DebugEv); break; case UNLOAD_DLL_DEBUG_EVENT: //dll卸载 dwContinueStatus = OnUnloadDllDebugEvent(DebugEv); break; case OUTPUT_DEBUG_STRING_EVENT: //输出调试信息,这个事件当被调试进程使用OutputDebugString等API时会触发 dwContinueStatus = OnOutputDebugStringEvent(DebugEv); break; case RIP_EVENT: dwContinueStatus = OnRipEvent(DebugEv); break; } // Resume executing the thread that reported the debugging event. ContinueDebugEvent(DebugEv->dwProcessId, DebugEv->dwThreadId, dwContinueStatus); } }
反汇编引擎:
反汇编引擎是调试器最核心的部分之一,它将我们获得的机器码翻译成汇编语言。
这里我仍使用OD的反调试引擎,这个引擎只能对x86平台下的程序进行处理,如果需要调试64位的程序,需要自己找到支持64位的反汇编引擎。
下载以及文档地址:http://www.ollydbg.de/srcdescr.htm#_Toc531975954
下一节将介绍如何使用以及写出一个最基本的调试器。
原文:http://www.cnblogs.com/Windogs/p/4373532.html