With MODULEENTRY32 and MODULEINFO, what are the steps to scan for a specific INT value in a separate process?
我已经枚举了一个进程模块,并且有一个
我尝试使用基地址和
如果可以扫描
是的-局部变量(无论如何非静态变量)都分配在堆栈上。要查看它们的值,您需要按照调试器的顺序编写一些内容,例如在程序运行时暂停程序(并且包含所关注变量的函数处于活动状态),然后遍历堆栈以查找值。
由于您显然使用的是Windows,因此您可能需要查看的功能包括:
-
WaitForDebugEvent (或WaitForDebugEventEx ) -
ContinueDebugEvent -
Stackwalk64
您可能还需要查看dbghlp API,可能从以下内容开始:
-
SymInitialize -
SymFromName -
SymCleanup
还有很多需要考虑的地方,但这至少足以使您有所作为。我之前发布了一个答案,该答案演示了StackWalk64和一些Sym *东西。
这是一些带有调试器基本框架的代码,该代码将生成一个子进程,然后记录其产生的调试事件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | #include <windows.h> #include <stdio.h> #include"child_process.h" void dispatch_child_event(DEBUG_EVENT const &event, child_process const &child) { char *file_name; char buffer[512]; switch ( event.dwDebugEventCode ) { case LOAD_DLL_DEBUG_EVENT: file_name = child.get_string(event.u.LoadDll.lpImageName); if ( event.u.LoadDll.fUnicode) printf("Loading %S\ ", (wchar_t *)file_name); else printf("Loading %s\ ", file_name); break; case EXCEPTION_DEBUG_EVENT: switch (event.u.Exception.ExceptionRecord.ExceptionCode) { case EXCEPTION_ACCESS_VIOLATION: { if ( event.u.Exception.dwFirstChance) break; EXCEPTION_RECORD const &r = event.u.Exception.ExceptionRecord; printf("Access Violation %x at %0#p\ ", r.ExceptionCode, r.ExceptionAddress); break; } case EXCEPTION_BREAKPOINT: printf("Breakpoint reached\ "); break; case EXCEPTION_DATATYPE_MISALIGNMENT: if ( !event.u.Exception.dwFirstChance) printf("Misaligned data exception.\ "); break; case EXCEPTION_SINGLE_STEP: printf("Single Step...\ "); break; case DBG_CONTROL_C: if ( !event.u.Exception.dwFirstChance) printf("Control+C pressed\ "); break; break; } case CREATE_THREAD_DEBUG_EVENT: printf("Client created a thread\ "); break; case CREATE_PROCESS_DEBUG_EVENT: printf("Create-Process\ "); break; case EXIT_THREAD_DEBUG_EVENT: printf("Thread exited.\ "); break; case UNLOAD_DLL_DEBUG_EVENT: printf("DLL being unloaded\ "); break; case OUTPUT_DEBUG_STRING_EVENT: { OUTPUT_DEBUG_STRING_INFO const &d = event.u.DebugString; char *string = child.get_debug_string(d.lpDebugStringData, d.nDebugStringLength); if ( d.fUnicode) printf("Debug string: %S\ ", string); else printf("Debug string: %s\ ", string); break; } } } int main(int argc, char **argv) { DEBUG_EVENT event; if ( argc < 2 ) { fprintf(stderr,"Usage: Trace [executable|PID]"); return EXIT_FAILURE; } child_process child(argv[1]); do { WaitForDebugEvent(&event, INFINITE); dispatch_child_event(event, child); ContinueDebugEvent( event.dwProcessId, event.dwThreadId, DBG_CONTINUE ); } while ( event.dwDebugEventCode != EXIT_PROCESS_DEBUG_EVENT); return 0; } |
它使用以下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #ifndef CHILD_PROCESS_H_INC_ #define CHILD_PROCESS_H_INC_ #include <windows.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include #include <io.h> #include"syserror.h" struct no_spawn { no_spawn() { system_error("Spawning Program"); } }; class child_process { HANDLE process_; HANDLE thread_; mutable char buffer[FILENAME_MAX]; public: child_process(char const *filename); char *get_string(void *string_name, DWORD num = 0) const; char *get_debug_string(void *string, DWORD num) const; HANDLE process() { return process_; } HANDLE thread() { return thread_; } ~child_process() { CloseHandle(process()); } }; #endif |
该类的实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | #include"child_process.h" static BOOL find_image(char const *name, char *buffer) { // Try to find an image file named by the user. // First search for the exact file name in the current // directory. If that's not found, look for same base name // with".com",".exe" and".bat" appended, in that order. // If we can't find it in the current directory, repeat // the entire process on directories specified in the // PATH environment variable. // #define elements(array) (sizeof(array)/sizeof(array[0])) static char *extensions[] = {".com",".exe",".bat",".cmd"}; int i; char temp[FILENAME_MAX]; if (-1 != _access(name, 0)) { strcpy(buffer, name); return TRUE; } for (i=0; i<elements(extensions); i++) { strcpy(temp, name); strcat(temp, extensions[i]); if ( -1 != _access(temp, 0)) { strcpy(buffer, temp); return TRUE; } } _searchenv(name,"PATH", buffer); if ( buffer[0] != '\\0') return TRUE; for ( i=0; i<elements(extensions); i++) { strcpy(temp, name); strcat(temp, extensions[i]); _searchenv(temp,"PATH", buffer); if ( buffer[0] != '\\0') return TRUE; } return FALSE; } child_process::child_process(char const *filename) { if (isdigit(filename[0])) { DWORD id = atoi(filename); process_ = OpenProcess(PROCESS_ALL_ACCESS, false, atoi(filename)); DebugActiveProcess(id); } else { char buf[FILENAME_MAX]; PROCESS_INFORMATION pi = {0}; STARTUPINFO si = {0}; si.cb = sizeof(si); if (!find_image(filename, buf)) throw no_spawn(); BOOL new_process_ = CreateProcess(buf, NULL, NULL, NULL, FALSE, DEBUG_ONLY_THIS_PROCESS, NULL, NULL, &si, &pi); if (!new_process_) throw no_spawn(); CloseHandle(pi.hThread); process_ = pi.hProcess; thread_ = pi.hThread; } } char *child_process::get_string(void *string_name, DWORD num) const { // string_name is a pointer to a pointer to a string, with the pointer and the // string itself located in another process_. We use Readprocess_Memory to read // the first pointer, then the string itself into our process_ address space. // We then return a pointer (in our address space) to the string we read in. // char *ptr; SIZE_T bytes_read; if ( 0 == num ) num = sizeof(buffer); if ( string_name == NULL ) return NULL; ReadProcessMemory(process_, string_name, &ptr, sizeof(ptr), &bytes_read); if (NULL == ptr ) return NULL; ReadProcessMemory(process_, ptr, buffer, num, &bytes_read); return buffer; } char *child_process::get_debug_string(void *string, DWORD num) const { static char buffer[FILENAME_MAX]; SIZE_T bytes_read; if ( string == NULL ) return NULL; ReadProcessMemory(process_, string, buffer, num, &bytes_read); return buffer; } |
这还不足以做您想要的一切,但是至少它应该为您提供一个大致的方向。
哦,免责声明:我很久以前就编写了大部分代码。如果今天要写的话,有些地方我肯定会做不同的事情。