教学文库网 - 权威文档分享云平台
您的当前位置:首页 > 精品文档 > 互联网资料 >

Win32调试API原理(2)

来源:网络收集 时间:2026-04-08
导读: view plain 1. typedef struct _DEBUG_EVENT { 2. DWORD dwDebugEventCode; 3. DWORD dwProcessId; 4. DWORD dwThreadId; 5. union { 6. EXCEPTION_DEBUG_INFO Exception; 7. CREATE_THREAD_DEBUG_INFO CreateThrea

view plain

1. typedef struct _DEBUG_EVENT { 2. DWORD dwDebugEventCode; 3. DWORD dwProcessId; 4. DWORD dwThreadId; 5. union {

6. EXCEPTION_DEBUG_INFO Exception; 7. CREATE_THREAD_DEBUG_INFO CreateThread; 8. CREATE_PROCESS_DEBUG_INFO CreateProcessInfo; 9. EXIT_THREAD_DEBUG_INFO ExitThread; 10. EXIT_PROCESS_DEBUG_INFO ExitProcess; 11. LOAD_DLL_DEBUG_INFO LoadDll; 12. UNLOAD_DLL_DEBUG_INFO UnloadDll;

13. OUTPUT_DEBUG_STRING_INFO DebugString; 14. RIP_INFO RipInfo; 15. } u;

16. } DEBUG_EVENT;

在dwDebugEventCode中的值标记了所发生的调试事件的类型。dwProcessId的值是调试事件所发生的进程的标识符。dwThreadId的值是调试事件所发生的线程的标识符。u结构包含了关于调试事件的更多信息,根据上面dwDebugEventCode的不同,它可以是表3-2中所示的结构。

表3-2 事件信息与u结构成员 dwDebugEventCode u的解释 名为CreateProcessInfo的CREATE_PROCESS_DEBUG_EVENT CREATE_PROCESS_DEBUG_INFO结构 名为ExitProcess的EXIT_PROCESS_DEBUG_EVENT EXIT_PROCESS_DEBUG_INFO结构 名为CreateThread的CREATE_THREAD_DEBUG_EVENT CREATE_THREAD_DEBUG_INFO结构 名为ExitThread的EXIT_THREAD_DEBUG_EVENT EXIT_THREAD_DEBUG_EVENT 结构 LOAD_DLL_DEBUG_EVENT 名为LoadDll的LOAD_DLL_DEBUG_INFO 结构 名为UnloadDll的UNLOAD_DLL_DEBUG_INFOUNLOAD_DLL_DEBUG_EVENT 结构 名为Exception的EXCEPTION_DEBUG_INFOEXCEPTION_DEBUG_EVENT 结构 OUTPUT_DEBUG_STRING_EVENT RIP_EVENT 名为DebugString的OUTPUT_DEBUG_STRING_INFO 结构 名为RipInfo的RIP_INFO 结构 那么如何访问这些数据呢?假设程序调用了WaitForDebugEvent函数并返回,那么要做的第一件事就是检查dwDebugEventCode字段中的值,根据它来判断debugger进程中发生了哪种类型的调试事件。比如说,如果dwDebugEventCode字段的值为

CREATE_PROCESS_DEBUG_EVENT,就可认为u的成员为CreateProcessInfo 并可通过u.CreateProcessInfo来访问。

下面是常用的CREATE_PROCESS_DEBUG_INFO结构的简要说明。

CREATE_PROCESS_DEBUG_INFO结构定义:

view plain

1. typedef struct _CREATE_PROCESS_DEBUG_INFO {

2. HANDLE hFile; // 进程文件的句柄,利用它可对

文件进行操作

3. HANDLE hProcess; // 进程的句柄,在进程空间中进行

读写操作时要用到它

4. HANDLE hThread; // 主线程的句柄,在读取、设置线

程环境时都要用到它

5. LPVOID lpBaseOfImage; // 进程执行的映像基地址 6. DWORD dwDebugInfoFileOffset; 7. DWORD nDebugInfoSize; 8. LPVOID lpThreadLocalBase;

9. LPTHREAD_START_ROUTINE lpStartAddress; 10. LPVOID lpImageName; 11. WORD fUnicode;

12. } CREATE_PROCESS_DEBUG_INFO, *LPCREATE_PROCESS_DEBUG_INFO;

3.1.3 如何在调试时创建并跟踪一个进程

这是使用Win32调试API的第一步。可以通过以下方式创建进程。

1. 如何创建一个新进程以供调试

通过CreateProcess创建新进程时,如果在dwCreationFlags标志字段中设置了

DEBUG_PROCESS或DEBUG_ONLY_THIS_PROCESS标志,将创建一个用以调试的新进程。如果是以DEBUG_PROCESS标志创建新进程,调试器将会接收到目标进程及由目标进程创建的所有子进程发生的所有调试事件,一般来说这是没有必要的。建议可以指定DEBUG_ONLY_THIS_PROCESS和DEBUG_PROCESS的组合标志来禁止它,如果设置了DEBUG_ONLY_THIS_PROCESS标志,调试器将只会收到目标进程的调试事件,而对其子进程的调试事件不予理睬。当进程创建成功后,可以通过查看

PROCESS_INFORMATION结构来获取被创建进程及其主线程的进程标识符和线程标识符。

由于操作系统将调试对象标记为在特殊模式下运行,所以,可以使用IsDebuggerPresent函数查看进程是否在调试器下运行。

2. 如何将调试器捆绑到一个正在运行的进程上

利用DebugActiveProcess函数可以将调试器捆绑到一个正在运行的进程上,如果执行成功,则效果类似于利用DEBUG_ONLY_THIS_PROCESS标志创建的新进程。

要注意的是,在NT内核下当试图通过DebugActiveProcess函数将调试器捆绑到一个创建时带有安全描述符的进程上时,将被拒绝。在Windows 9x中则简单得多,只有当指定了一个无效的进程标识符时调用才会失败。所以看上去NT内核的系统要更安全。

将调试器捆绑到一个进程上一般是比较好的一种做法,但是有时除了利用CreateProcess函数来载入进程外没有其他的办法。那么到底该用哪种方法呢?这涉及读者将要进行的工作。比如要做一个简单的游戏修改器时,用临时捆绑调试器的方法可能比较好,如果要做一些不同寻常的工作的话,利用载入的方法可能更好,因为它获得目标进程及其线程的所有控制权,这样就可以为所欲为了。

3.1.4 调试循环体

用调试API建立一个简单的调试程序是非常简单的,所有要做的只是创建一个用来调试的新进程,然后执行相关代码来监视所有的调试事件。笔者把监视所有的调试事件的这部分代码称为“调试循环体”,为什么呢?因为它的实现非常简单,看上去就像一个“while”循环,所需要做的只是使用WaitForDebugEvent和ContinueDebugEvent函数。就像上面说的,WaitForDebugEvent在一段时间内等待目标进程中调试事件的发生,如果在这段时间没有调试事件发生,那么函数将返回FALSE。如果在指定时间内调试事件发生了,那么函数将返回TRUE,并且它会把所发生的调试事件及其相关信息填写入一个DEBUG_EVENT结构。然后调试器会检查这些信息,并据此做出相应的反应。在对这些事件做出相应的操作后,就可以使用ContinueDebugEvent函数来恢复线程的执行,并等待下一个调试事件的发生。要注意的一点是WaitForDebugEvent只能使用在创建的或是捆绑上的进程中的某个线程上。 WaitForDebugEvent – ContinueDebugEvent循环的C语言示例:

view plain

1. PROCESS_INFORMATION pi;

2. STARTUP_INFO si; 3. DEBUG_EVENT devent;

4. If (CreateProcess( 0 , \ , 0 , 0 ,FALSE ,DEBUG_ONLY_THI

S_PROCESS , 0 ,0 ,&si , π)) 5. {

6. while(TRUE) 7. {

8. if (WaitForDebugEvent( &devent , 150))

//在150毫秒内等待调试事件 9. {

10. switch (devent.dwDebugEventCode) 11. {

12. case CREATE_PROCESS_DEBUG_EVENT: 13. //在此填入你的处理程序 14. break;

15. case EXIT_PROCESS_DEBUG_EVENT: 16. //在此填入你的处理程序 17. break;

18. case EXCEPTION_DEBUG_EVENT: …… 此处隐藏:4046字,全部文档内容请下载后查看。喜欢就下载吧 ……

Win32调试API原理(2).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.jiaowen.net/wendang/442529.html(转载请注明文章来源)
Copyright © 2020-2025 教文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:78024566 邮箱:78024566@qq.com
苏ICP备19068818号-2
Top
× 游客快捷下载通道(下载后可以自由复制和排版)
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能出现无法下载或内容有问题,请联系客服协助您处理。
× 常见问题(客服时间:周一到周五 9:30-18:00)