首页 > 代码库 > 调试器开发实例_调试器事件处理(一.事件到达)

调试器开发实例_调试器事件处理(一.事件到达)

 

上一章既然说到了调试循环事件,那么接下来我们该说说对调试器事件的处理了.

调试器的事件处理虽然有很多,但是并不是每一个都用得上的,接下来的文章中我们挑选一些经常用到的来给大家说说.

CREATE_PROCESS_DEBUG_EVENT

 创建进程之后的第一个调试事件,CREATE_PROCESS_DEBUG_INFO结构体描述了该类调试事件的详细信息。

该结构体有三个字段是句柄,分别是hFilehProcesshThread,同样要记得使用CloseHandle关闭它们!


EXIT_PROCESS_DEBUG_EVENT  

被调试进程结束时引发此类调试事件,EXIT_PROCESS_DEBUG_INFO结构体描述了它的详细信息。或许你能做的只有输出dwExitCode这个字段的值。


CREATE_THREAD_DEBUG_EVENT(对应的还有卸载事件,因用的不多,所以忽略之)

 创建一个线程之后引发此类调试事件,CREATE_THREAD_DEBUG_INFO结构体描述了它的详细信息。同样要记住用CloseHandle关闭hThread字段!

 

LOAD_DLL_DEBUG_EVENT(对应的还有卸载事件,因用的不多,所以忽略之)  

加载一个DLL模块之后引发该类调试事件,LOAD_DLL_DEBUG_INFO结构体描述了它的详细信息。lpImageName这个字段可能会使你想在调试器中输出DLL的文件名,然而这行不通。

MSDN上的解释是,lpImageName的值是文件名字符串在被调试进程的进程空间内的地址,但是这个值可能为NULL,即使不为NULL,通过ReadProcessMemory读取到的内容也可能是NULL

所以,想通过这个字段获取DLL的文件名并不可靠。

 

EXCEPTION_DEBUG_EVENT(该事件很重要)  

发生异常时引发此类调试事件,EXCEPTION_DEBUG_INFO结构体描述了它的详细信息。对这种调试事件的处理是最麻烦的,因为异常的种类非常多,对每种异常的处理也不相同。另外,此类调试事件也是实现断点和单步执行的关键。 

现在打开我们上一章的代码,对其进行稍微的修改与调整,增加可以自己选择需要调试的进程,与事件函数的完成 具体代码如下:(部分代码)

 

 1 void StartDebug() 2 { 3     BOOL waitEvent = TRUE; 4     DEBUG_EVENT debugEvent; 5     while (waitEvent == TRUE && WaitForDebugEvent(&debugEvent, INFINITE))  6     { 7         switch (debugEvent.dwDebugEventCode)  8         { 9         case CREATE_PROCESS_DEBUG_EVENT:10             DebugEvent->OnProcessCreated(&debugEvent.u.CreateProcessInfo);11             break;12         case CREATE_THREAD_DEBUG_EVENT:13             DebugEvent->OnThreadCreated(&debugEvent.u.CreateThread);14             break;15         case EXIT_PROCESS_DEBUG_EVENT:16             DebugEvent->OnProcessExited(&debugEvent.u.ExitProcess);17             waitEvent = FALSE;18             break;19         case LOAD_DLL_DEBUG_EVENT:20             DebugEvent->OnDllLoaded(&debugEvent.u.LoadDll);21             break;22         case EXCEPTION_DEBUG_EVENT:23             DebugEvent->OnException(&debugEvent.u.Exception);24             break;            25         case UNLOAD_DLL_DEBUG_EVENT:26             break;27         case EXIT_THREAD_DEBUG_EVENT:28             break;            29         case OUTPUT_DEBUG_STRING_EVENT:30             break;31         default:32             printf("Unknown debug event!");33             break;34         }35         if (waitEvent == TRUE) 36         {37             ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId, DBG_CONTINUE);38         }39         else 40         {41             break;42         }43     }44 }

大体调整好后,我们在每个调试事件上输出一段信息,来测试下消息到达的情况

 

 1 void CDebugEvent::OnProcessCreated(const CREATE_PROCESS_DEBUG_INFO*) 2 { 3     printf("OnProcessCreated 进程创建事件到达!"); 4 } 5  6 void CDebugEvent::OnThreadCreated(const CREATE_THREAD_DEBUG_INFO*) 7 { 8      printf("OnThreadCreated 线程创建事件到达!"); 9 }10 11 void CDebugEvent::OnException(const EXCEPTION_DEBUG_INFO*)12 {13     printf("OnException 异常事件到达");14 }15 16 void CDebugEvent::OnProcessExited(const EXIT_PROCESS_DEBUG_INFO*)17 {18      printf("OnProcessExited 进程退出事件");19 }20 21 void CDebugEvent::OnDllLoaded(const LOAD_DLL_DEBUG_INFO*)22 {23      printf("OnDllLoaded dll卸载事件");24 }

 

运行我们的程序 输出信息如下
OnProcessCreated 进程创建事件到达!
OnDllLoaded dll装载事件
OnDllLoaded dll装载事件
OnDllLoaded dll装载事件
OnDllLoaded dll装载事件
OnDllLoaded dll装载事件
OnDllLoaded dll装载事件
OnDllLoaded dll装载事件
OnDllLoaded dll装载事件 ……略,(由于应用程序默认会载入多个系统dll,所以该事件会多次到达)

安全工具开发之调试器实现 第二课:调试器事件处理(一.事件到达) 到此结束,希望大家多多支持

附件地址:http://pan.baidu.com/s/1bnzpSq7