我对C ++很陌生,我决定制作一个简单的“扫描仪”,扫描进程的所有地址并打印值。我开始使用计算器appliaction,这是我的代码
编辑:我将代码更改为
int main()
{
HWND h_wnd = FindWindow("Calculator", 0);
DWORD pid;
GetWindowThreadProcessId(h_wnd, &pid);
HANDLE h_calc = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
int someValue;
for(int i = 0; i < 1000; i++) {
void *address = (void*)i;
ReadProcessMemory(h_calc, address, &someValue, 4, 0);
cout << "Address: " << address << " " << someValue << endl;
}
system("pause");
return EXIT_SUCCESS;
}
这就是我得到的每个地址
Address: 000003DB -858993460
Address: 000003DC -858993460
Address: 000003DD -858993460
Address: 000003DE -858993460
Address: 000003DF -858993460
Address: 000003E0 -858993460
Address: 000003E1 -858993460
Address: 000003E2 -858993460
Address: 000003E3 -858993460
Address: 000003E4 -858993460
Address: 000003E5 -858993460
Address: 000003E6 -858993460
Address: 000003E7 -858993460
我做错了什么?
但我想要它做的是找到所有地址,并打印出它们的值。我意识到打印出来可能会有很多,但我只是想看看结果。
非常感谢任何帮助,谢谢!
答案 0 :(得分:1)
而不是,
int addr = 0xFFFFFF;
你不能选择,
void *addr = 0;
出于地址目的。
答案 1 :(得分:1)
你真的没有做错什么,只是你的结果不那么有趣(数据方面......并不意味着侮辱)。
值-858993460
只是0xcccccccc
,Microsoft编译器使用它来检测内存溢出。通常情况下,您分配的值之外的内存会被初始化为一个特殊值,这样如果您得到它,您就会立即知道您正在访问某些您不想要(或不应该)的地方。许多人使用的另一种模式是0xDEADBEEF
,只是因为它是一个奇怪的值,当用十六进制打印时可以解释出来。
答案 2 :(得分:1)
OpenProcess和ReadProcessMemeory仅适用于调试模式下的进程:
有关详细信息,请参阅此处http://msdn.microsoft.com/en-us/library/ms684320(v=vs.85).aspx手册
检查这两个电话的返回值,看看你得到了什么。
答案 3 :(得分:0)
您的问题是因为您将i
强制转换为某个地址,但是当i小于1kb时,它永远不会出现在进程地址空间中。您需要做的是获取进程的HANDLE / HMODULE,然后从中获取基本进程内存地址(取决于您要扫描的内存,这可以从PE获取,用于代码,数据,文本部分等或者通过psapi获取保留的系统内存),然后从void* address = (void*)((UINT_PTR)base + i);
开始。将i限制为内存部分的大小也是一个好主意,可选择舍入到页面boundery。
答案 4 :(得分:0)
由于没有任何流程使用整个virtual adress space,因此您首先要做的是确定哪些pages能够和不能被读取。
Windows提供VirtualQueryEx功能,允许您扫描进程的内存以获取地址范围的状态。因此,您将要做的是在循环中调用此函数并使用MEM_COMMIT
属性打印范围的内容。细节遗漏为作业:)
您可能还会发现EnumProcessModules功能很有用。它枚举了进程中加载的每个可执行文件及其基址。同样,细节被遗漏为作业。
此外,如果您只想使用ReadProcessMemory函数,那么我相信您只需要将PROCESS_VM_READ
和PROCESS_QUERY_INFORMATION
传递给OpenProcess。这应该避免必须像Soren所提到的那样在调试模式下设置目标进程。