当以艺术眼光看程序,寻找程序后面的原理,做到化而不忘
全部博文(57)
分类: Windows平台
2014-06-24 10:47:10
什么是调试
Windows提供了调试API用于对进程进行调试,调试事件主要为:
#define
EXCEPTION_DEBUG_EVENT 1
#define CREATE_THREAD_DEBUG_EVENT 2
#define CREATE_PROCESS_DEBUG_EVENT 3
#define EXIT_THREAD_DEBUG_EVENT 4
#define EXIT_PROCESS_DEBUG_EVENT 5
#define LOAD_DLL_DEBUG_EVENT 6
#define UNLOAD_DLL_DEBUG_EVENT 7
#define OUTPUT_DEBUG_STRING_EVENT 8
#define
RIP_EVENT
9
其出现顺序为:
CREATE_PROCESS_DEBUG_EVENT
LOAD_DLL_DEBUG_EVENT x n // 静态载入的DLL
CREATE_THREAD_DEBUG_EVENT & EXIT_THREAD_DEBUG_EVENT // 多线程程序中成对出现
LOAD_DLL_DEBUG_EVENT & UNLOAD_DLL_DEBUG_EVENT // 动态载入 DLL 时成对出现
EXCEPTION_DEBUG_EVENT x n // 随机出现
OUTPUT_DEBUG_STRING_EVENT x n // 程序写调试信息时出现
EXIT_PROCESS_DEBUG_EVENT
可以看出,所谓的调试事件,其本质也就是一些进程和线程的关键时刻点通知用户,让用户采取一些措施控制进程或线程的流程。换句话说,这些调试事件其本质也就是在进程和线程的各个关键时刻,以事件方式告诉用户,允许用户对其进行进行一些控制,让用户参与到控制进程和线程创建的行为中来。所以,与其说是对进程或线程调试,不如说是对其进行控制,从这个意义上来说,调试的本质就是进程或线程的交互式控制过程。
和DLL对比一下:
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
可以明显看出来,调试事件和DLL的ul_reason_for_call有着异曲同工之妙,都是通知用户,你可以在里面做点事了,好事坏事不管了。从这个角度来说,DLL也是被“调试”了。
接着说,这些关键的时刻是谁来发出这些事件呢?使用调试API时和DLL加载原因,我们可以认为是父进程创建子进程过程中发出这些事件。
为什么发出这些事件?为了与用户进行交互,这只是其表面原因,我觉得其更深入原因是,它对用户有影响,换句话说,这些事件的影响力太大了,影响到了用户,所以理所当然要提供给用户接口以接收用户的反馈,所以可以这样说:事件的本质就是影响力。那么,在原则上我们也可以添加一些新的事件,只要我们觉得这些事件影响力足够大,需要其它模块参与。再进一步讲,只要你觉得软件行为影响到了其它模块,都可以将其作为一事件发出,这也是事件驱动机制的本质之一。