一个简单的创建被调试进程的案例

通过这个简单的案例,我们可以明白以下几点:

1. 创建被调试进程之后,被调试进程的进程线程的句柄与ID如何获取(PROCESS_INFORMATION)。

2. DEBUG_EVENT 的数据结构,u是对应的事件种类的数据结构。

3. 等待被调试进程的大体流程:使用 WaitForDebugEvent,等待被调试事件;使用ContinueDebugEvent,继续执行被调试事件。

4. 加载DLL时如果输出DLL名字:这里有个坑,必须连续两次从目标进程中读取,第一次读取地址,第二次通过该地址获取DllName,即文件名。

 1 #include "pch.h"
 2 #include <iostream>
 3 #include <Windows.h>
 4 #include <string>
 5 
 6 using namespace std;
 7 
 8 int main()
 9 {
10     CHAR DllName[MAX_PATH] = {''}; // 存储DLL的缓冲区
11     SIZE_T nNumberOfBytesRead = 0;    // 读取的字节数
12     DWORD dwAddrImageName = 0;
13     STARTUPINFO si = { sizeof(si) };
14     PROCESS_INFORMATION pi;
15     string path;
16 
17     LPCSTR x = "C:\Users\97905\Desktop\记事本.exe";
18     if (CreateProcessA(
19         x, // 进程名字  
20         NULL, // 命令行为空
21         NULL, // 进程安全描述符
22         NULL, // 线程安全描述符
23         FALSE, // 不可继承
24         DEBUG_ONLY_THIS_PROCESS | DEBUG_PROCESS, // 调试模式启动
25         NULL, // 使用父进程的环境块
26         NULL, // 与父进程有相同的目录
27         (LPSTARTUPINFOA)&si, // 必须初始化
28         &pi // 被创建进程的句柄,线程等有关信息
29     )) {
30         cout << "创建被调试进程成功!" << endl;
31     }
32     else {
33         cout << "创建被调试进程失败,退出" << endl;
34         exit(0);
35     }
36 
37     // 等待调试事件
38     DEBUG_EVENT de; // 申请调试事件
39     // 循环读取调试事件
40     while (WaitForDebugEvent(&de, INFINITE) != 0) {
41         if (pi.dwProcessId == de.dwProcessId) {
42             switch (de.dwDebugEventCode) {
43             case EXCEPTION_DEBUG_EVENT: // 异常事件
44                 cout << "EXCEPTION_DEBUG_EVENT:" << endl;
45                 //ContinueDebugEvent(de.dwProcessId, de.dwThreadId
46                 break;
47             case CREATE_THREAD_DEBUG_EVENT: // 线程创建事件
48                 cout << "CREATE_THREAD_DEBUG_EVENT" << endl;
49                 break;
50             case CREATE_PROCESS_DEBUG_EVENT: // 进程创建事件
51                 cout << "EXCEPTION_DEBUG_EVENT" << endl;
52                 break;
53             case EXIT_THREAD_DEBUG_EVENT: // 线程退出事件
54                 cout << "EXIT_THREAD_DEBUG_EVENT" << endl;
55                 break;
56             case EXIT_PROCESS_DEBUG_EVENT: // 进程退出事件
57                 cout << "EXIT_PROCESS_DEBUG_EVENT" << endl;
58                 break;
59             case LOAD_DLL_DEBUG_EVENT: // DLL加载事件
60                 ReadProcessMemory(pi.hProcess, de.u.LoadDll.lpImageName, &dwAddrImageName, sizeof(dwAddrImageName), &nNumberOfBytesRead);
61                 ReadProcessMemory(pi.hProcess, (void*)dwAddrImageName, DllName, sizeof(DllName), &nNumberOfBytesRead);
62                 if (de.u.LoadDll.fUnicode) {
63                     wprintf(L"DLLNAME: %s
", DllName);
64                 }
65                 else {
66                     printf("DLLNAME: %s
", DllName);
67                 }
68                 break;
69             case UNLOAD_DLL_DEBUG_EVENT: // 卸载DLL事件
70                 cout << "UNLOAD_DLL_DEBUG_EVENT" << endl;
71                 break;
72             case OUTPUT_DEBUG_STRING_EVENT: // 输出DEBUG字符串事件
73                 cout << "OUTPUT_DEBUG_STRING_EVENT: " << de.u.DebugString.fUnicode << endl;
74                 break;
75             }
76             ContinueDebugEvent(de.dwProcessId, de.dwThreadId, DBG_CONTINUE);
77         }
78     }
79 }
原文地址:https://www.cnblogs.com/onetrainee/p/11960107.html