首页 > 代码库 > 调试器开发实例_调试器事件处理(一.事件到达)
调试器开发实例_调试器事件处理(一.事件到达)
上一章既然说到了调试循环事件,那么接下来我们该说说对调试器事件的处理了.
调试器的事件处理虽然有很多,但是并不是每一个都用得上的,接下来的文章中我们挑选一些经常用到的来给大家说说.
CREATE_PROCESS_DEBUG_EVENT
创建进程之后的第一个调试事件,CREATE_PROCESS_DEBUG_INFO结构体描述了该类调试事件的详细信息。
该结构体有三个字段是句柄,分别是hFile,hProcess和hThread,同样要记得使用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