一个简单的创建被调试进程的案例
通过这个简单的案例,我们可以明白以下几点:
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] = {'\0'}; // 存储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\n", DllName); 64 } 65 else { 66 printf("DLLNAME: %s\n", 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 }