![](/img/trans.png)
[英]Converting BYTE* from MODULEENTRY32's modBaseAddr to a std::string
[英]With MODULEENTRY32 and MODULEINFO, what are the steps to scan for a specific INT value in a separate process?
我列举了一个流程模块,并有一个MODULEINFO
。 从那里我有一个基地址,模块的大小和入口点。 如果我有一个单独的进程,在main()
定义了一个整数int x = 4
,我可以使用MODULEINFO
内容扫描该整数的地址吗? 不会在堆栈上存在x
,它与模块exe分开吗?
我尝试使用基地址和SizeOfImage
成员创建循环,将基地址转换为byte*
,然后添加1个字节然后将其转换为int*
以搜索特定值,但是我得到的每个值都是“0”。 我相信我的方法(严重)不正确。
如果有可能扫描一个int
值,任何人都可以指出我这样做的大方向吗?
是 - 在堆栈上分配局部变量(无论如何)。 要查看它们的值,您需要按调试器的顺序编写一些内容,例如在程序运行时暂停程序(并且包含感兴趣的变量的函数处于活动状态),然后遍历堆栈以查找值。
由于您显然使用的是Windows,因此您可能希望查看的功能包括:
您可能还想查看dbghlp API ,可能从以下开始:
还有更多需要考虑的因素,但这可能足以至少得到一些启动。 我之前发布了一个演示StackWalk64的答案,以及一些Sym *的东西 。
下面是一些代码,其中包含一个将生成子进程的调试器的骨架,然后记录它生成的调试事件:
#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\n", (wchar_t *)file_name);
else
printf("Loading %s\n", 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\n",
r.ExceptionCode,
r.ExceptionAddress);
break;
}
case EXCEPTION_BREAKPOINT:
printf("Breakpoint reached\n");
break;
case EXCEPTION_DATATYPE_MISALIGNMENT:
if ( !event.u.Exception.dwFirstChance)
printf("Misaligned data exception.\n");
break;
case EXCEPTION_SINGLE_STEP:
printf("Single Step...\n");
break;
case DBG_CONTROL_C:
if ( !event.u.Exception.dwFirstChance)
printf("Control+C pressed\n");
break;
break;
}
case CREATE_THREAD_DEBUG_EVENT:
printf("Client created a thread\n");
break;
case CREATE_PROCESS_DEBUG_EVENT:
printf("Create-Process\n");
break;
case EXIT_THREAD_DEBUG_EVENT:
printf("Thread exited.\n");
break;
case UNLOAD_DLL_DEBUG_EVENT:
printf("DLL being unloaded\n");
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\n", string);
else
printf("Debug string: %s\n", 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;
}
它使用以下child_process
标头:
#ifndef CHILD_PROCESS_H_INC_
#define CHILD_PROCESS_H_INC_
#include <windows.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#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
该类的实现如下:
#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;
}
这还不足以做你想做的一切,但至少它应该给你一个大方向的开始。
哦,一个免责声明:很久以前我写了大部分代码。 如果我今天要写的话,我肯定会有不同的部分。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.