在ProcessMemory中扫描所有地址

时间:2011-07-10 05:52:38

标签: windows memory-management

我对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

我做错了什么?

但我想要它做的是找到所有地址,并打印出它们的值。我意识到打印出来可能会有很多,但我只是想看看结果。

非常感谢任何帮助,谢谢!

5 个答案:

答案 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_READPROCESS_QUERY_INFORMATION传递给OpenProcess。这应该避免必须像Soren所提到的那样在调试模式下设置目标进程。