windows内核研究(软件调试-调试事件采集)
软件调试
调试事件采集
前面有说到在调试器和被调试之间会创建一个_DEBUG_OBJECT对象来进行关联
调试事件的种类
被调试进程会把一个个的调试事件写到_DEBUG_OBJECT中的一个成员链表中,调试器就通过它们建立的
_DEBUG_OBJECT调试对象获取调式事件,但并不是进程的任何操作都会被写入到调试事件当中
//
// Debug Message API Number
//
typedef enum _DBGKM_APINUMBER
{DbgKmExceptionApi = 0, // 异常DbgKmCreateThreadApi = 1, // 创建线程DbgKmCreateProcessApi = 2, // 创建进程DbgKmExitThreadApi = 3, // 线程退出DbgKmExitProcessApi = 4, // 进程退出DbgKmLoadDllApi = 5, // 加载DLLDbgKmUnloadDllApi = 6, // 卸载DLLDbgKmErrorReportApi = 7, // 已废弃DbgKmMaxApiNumber = 8, // 最大值
} DBGKM_APINUMBER;
那就有一个问题,是谁在为我们添加调试事件呢?
调试事件采集函数
- 创建进程、线程必经之路:
- PspUserThreadStartup
- DbgkCreateThread ->
DbgkpSendApiMessage()
- DbgkCreateThread ->
- PspUserThreadStartup
- 退出线程、进程必经之路:
- PspExitThread
- DbgkExitThread/DbgkExitProcess ->
DbgkpSendApiMessage()
- DbgkExitThread/DbgkExitProcess ->
- PspExitThread
- 加载模块的必经之路:
- NtMapViewOfSection
- DbgkMapViewOfSection ->
DbgkpSendApiMessage()
- DbgkMapViewOfSection ->
- NtMapViewOfSection
- 卸载模块的必经之路:
- NtUnMapViewOfSection
- DbgkUnMapViewOfSection ->
DbgkpSendApiMessage()
- DbgkUnMapViewOfSection ->
- NtUnMapViewOfSection
- 异常的必经之路:
- KiDispatchException
- DbgkForwardException ->
DbgkpSendApiMessage()
- DbgkForwardException ->
- KiDispatchException
答案就是在你加载DLL,卸载DLL,创建进程结束进程的必经之路上调用这个方法
DbgkpSendApiMessage(x,x)参数说明
第一个参数:消息结构,每种消息都有自己的消息结构共有7种类型
第二个参数:要不要把本进程内除了自己之外的其他线程挂起