dwThreadId DWORD dwContinueStatus 该函数通知被调试程序继续运行。
使用例 // process to continue // thread to continue // continuation status DEBUG_EVENT dbe BOOL rc CreateProcessNULL pszCmd NULL NULL FALSE DEBUG_ONLY_THIS_PROCESS NULL szPath ampst amppro whileWaitForDebugEventampdbe INFINITE // 如果是退出消息调试监视结束 ifdbe. dwDebugEventCode EXIT_PROCESS_DEBUG_EVENT break // 进入调试监视处理 rc OnDebugEventampdbe ifrc ContinueDebugEventdbe.dwProcessId dbe.dwThreadId DBG_CONTINUE else ContinueDebugEventdbe.dwProcessId dbe.dwThreadId DBG_ DBG_EXCEPTION_NOT_HANDLED // 调试消息处理程序 BOOL WINAPI OnDebugEventDEBUG_EVENT pEvent // 我们还没有对目标进程进行操作所以先返回 TRUE。
return TRUE 上面这些程序就是一个最简单的调试程序了。
不过它基本上没有什么用途。
你还没有在目 标进程中设置断点你就不能完成对 API 函数监视的任务。
对目标进程设置断点 对目标进程设置断点 我们的 目标是监视 API 函数的输入输出那么首先应该知道 DLL 模块中提供了哪些 API 函以及这些 API 的入口地址。
在前面将过广义的 API 还包括未导出的内部函数。
如果你 有 DLL 模块的调试版本和调试连接文件pdb 文件也可以根据调试信息得到内部函数的 信息。
?? 得到函数名及函数入口地址 通过程序得到函数的入口地址有很多种方法。
对于用 VC 编译出来的 DLL如果是 Debug 版本 可以通过 ImageHlp 库函数得到调试信息 分析出函数的入口地址。
如果没有 Debug 版本也可以通过分析导出函数表得到函数的入口地址。
1用 Imagehlp 库函数得到 Debug 版本的函数名和函数入口地址。
可以利用 Imagehlp 库函数分析 Debug 信息关联的函数为 SymInitialize、 SymEnumerateSymbols 和 UnDecorateSymbolName。
详细可以参考 MSDN 中关于 这些函数 的说明和用法。
不过用 Imagehlp 只能分析出用 VC 编译的程序对 CBuilder 编译的程序不能用这种方法分析。
2DLL 的导出表得到函数导出函数名和函数的入口地址。
在大多数情况下我们还是希望监视的是 Release 版本的输入输出参数毕竟 Debug 版 本不是我们最终提供给用户的产品。
Debug 和 Release 的编译条件不同导致产生的结果不 同在很多 BBS 中都讨论过。
所以我认为跟踪监视 Release 版本更加有实用价值。
通过分析 DLL 导出表得到导出函数名在 MSDN 上就有源代码。
关于导出表的说明大家可以 参考关于 PE 结构的文章。
3通过 OLE 函数取得 COM 接口 你也可以通过 OLE 函数分析 DLL 提供的接口函数。
接口函数不是通过 DLL 导出表导 出的。
你可以通过 LoadTypeLib 函数来分析 COM 接口得到 COM 记录接口的入口地址这样 你就可以监视 COM 接口的调用了。
这是 API HOOK 没法实现的。
在这里我不打算分析分 析 COM 接口的方式了。
在 MSDN 上通过搜索 LoadTypeLib sample 关键词你就可以找 到相关的源代码进行修改实现你的目标。
这里是通过计算机自动分析目标模块得到 DLL 导出函数的方案作为我们监视的目的 而 言 这些工作只是为了得到一系列的函数名和函数地址而已。
函数名只是一个让我们容易识 别函数的名称而已该函数入口地址才是我们真正关心的目标。
换句话 说如果你能够确 保某一个地址一定是一个函数包括内部函数的入口地址你就完全可以给这个函数定义 自己的名称将它加入你的函数管理表中同样可以实 现监视该函数的输入输出参数的功 能。
这也是实现 Exe 内部函数的监视功能的原因。
如果你有 Exe 编译时生成的 Map 文件你 可以在编译时选择生成 Map 文 件你就可以通过分析 Map 文件得到内部函数的 入口 地址将内部函数加入到你的函数管理表中。
一个函数的名称对于监视功能来讲究竟是 FunA 还是 FunB 并没有什么意义但名称是 FunA 还是 FunB 的名称对于监视者分析监 视结果是有意义的你完全可以将 MessageBox 的函数在输出监视结果 是以 FunA 的名 称输出所以在监视一些内部无名称的函数时你完全可以定义你自己的名字。
?? 在函数入口地址处设置断点 设置断点非常简单只要将 0xCCint 3写入指定的地址就可以了。
这样程序运行到指定 地址时将产生调试中断信息通知调试程序。
修改指定进程的内存数据可以通过 WriteProcessMemory 函数来完成。
由于一般情况下作为程序代码段都被保护起来了所 以还有一个函数也会用到。
VirtualProtectEx。
在实际情况下当调试断点发生时调试 程序还应该将原来的代码写回被调试程序。
unsigned char SetBreakPointDWORD pAdd unsigned char code unsigned char b BOOL rc DWORD dwRead dwOldFlg // 0x80000000 以上的地址为系统共有区域不可以修改 if pAdd gt 0x80000000 pAdd 0 return code // 取得原来的代码 rc ReadProcessMemory_ghDebug pAdd ampb sizeofBYTE ampdwRead // 原来的代码和准备修改的代码相同没有必要再修改 ifrc 0 b code return code // 修改页码保护属性 VirtualProtectEx_ghDebug pAdd sizeofunsigned char PAGE_READWRITE ampdwOldFlg // 修改目标代码 WriteProcessMemory_ghDebug pAdd ampcode sizeofunsigned char ampdwRead // 恢复页码保护属性 VirtualProtectEx_ghDebug pAdd sizeofunsigned char dwOldFlg ampdwOldFlg return b 在设置断点时你必须将原来的代码保存起来 这样在恢复断点时就可以将代码还原了。
般 一 用法为设置断点 m_code SetBreakPoint pFunAdd 0xCC 恢复断点 SetBreakPoint pFunAdd m_code 记住每个函数入口地址的代码都可能不同你 应该为每个断点地址保存一个原来的代码在恢复时就不会发生错误了。
好了现在目标程序中已经设置好了断点当目标程序调用设置了断点的函数时将产生一 个调试中断信息通知调试程序。
我们就要在调试程序中编写我们的调试中断程序了。
编写调试中断处理程序 被调试程序产生中断时将产生一个 EXCEPTION_DEBUG_EVENT 信息通知调试程序进 行处理。
同时将填充 EXCEPTION_DEBUG_INFO 结构。
typedef struct _EXCEPTION_DEBUG_INFO EXCEPTION_RECORD ExceptionRecord DWORD dwFirstChance EXCEPTION_DEBUG_INFO LPEXCEPTION_DEBUG_INFO typedef struct _EXCEPTION_RECORD DWORD ExceptionCode DWORD ExceptionFlags struct _EXCEPTION_RECORD ExceptionRecord PVOID ExceptionAddress DWORD NumberParameters ULONG_PTR ExceptionInformationEXCEPTION_MAXIMUM_PARAMETERS EXCEPTION_RECORD PEXCEPTION_RECORD 在该结构中 我们比较感兴趣的是产生中断的地址 ExceptionAddress 和产生中断的信息 代码 ExceptionCode。
在信息代码中与我们任务相关的信息代码为 EXCEPTION_BREAKPOINT断点中断信息代码 EXCEPTION_SINGLE_STEP单步中断信息代码 断点中断是由于我们在前面设置断点 0xCC 代码运行时产生的。
由于产生中断后我们 必 须将原来的代码写回被调试程序中继续运行。
但是代码一旦被写回目标程序这样当目 标程序再次调用该函数时将不会产生中断我们就只能实现一次监视 了。
所以我们必须 在将原代码写回被调试程序后 应该让被调试程序已单步的方式运行 再次产生一个单步中 断的调试信息。
在单步中断处理中我们再次将 0xCC 代码写入函数的入口地址这样就 可以保证再次调用时产生中断。
首先在进行中断处理前我们必须作些准备工作管理起线程 ID
上一篇:
安装并配置vCenter_5_vCenter_Server_Heartbeat
下一篇:
2015农民入党申请书格式范文