【问题标题】:`VirtualAllocEx` returns same address when specifying different start addresses?指定不同的起始地址时,`VirtualAllocEx` 返回相同的地址?
【发布时间】:2016-02-24 13:56:04
【问题描述】:

我试图让 calc.exe 显示一个消息框,但 calc.exe 总是在我执行我的程序时崩溃。所以我尝试将代码注入到我自己的进程中,以便查看调试消息。这样做会给我一个指向pData->msg的异常“访问冲突...无法执行...”。然后我发现pThreadpData 得到了相同的地址。这怎么可能?我实际上将VirtualAllocExlpAddress 设置为pPagepPage + 128 以获取不同的起始地址。

// Allocate page
void *pPage = VirtualAllocEx(hProcess, NULL, 256, MEM_RESERVE, PAGE_EXECUTE_READWRITE);

// Commit memory for thread procedure
void *pThread = VirtualAllocEx(hProcess, pPage, 128, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

// Commit memory for thread data
void *pData = VirtualAllocEx(hProcess, (void*)((long long)pPage + 128), 128, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

// WriteProcessMemory, do stuff

// Release memory
VirtualFreeEx(hProcess, pPage, 256, MEM_RELEASE);

【问题讨论】:

    标签: c++ winapi virtualalloc


    【解决方案1】:

    VirtualAllocEx 分配内存的部分可分割内存页面大小为 4096 字节。

    dwSize [in] 区域的大小,以字节为单位。如果 lpAddress 参数为 NULL,则该值向上舍入到下一页边界。否则,分配的页面包括包含从 lpAddress 到 lpAddress+dwSize 范围内的一个或多个字节的所有页面。这意味着跨越页面边界的 2 字节范围会导致两个页面都包含在分配的区域中。

    lpAddress [输入,可选] 为要分配的页面区域指定所需起始地址的指针。 如果您要保留内存,该函数会将此地址向下舍入到最接近的分配粒度倍数。

    尝试使用堆函数(HeapAlloc、HeapFree、HeapCreate)。

    或者你可以这样做:

    // Allocate page
    void *pPage = VirtualAllocEx(hProcess, NULL, 256, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    
    // Commit memory for thread data
    void *pData = (char*)pPage + 128;
    
    // WriteProcessMemory, do stuff
    
    // Release memory
    VirtualFreeEx(hProcess, pPage, 256, MEM_RELEASE);
    

    【讨论】:

    • 所以我只需要偏移线程数据的写入地址而不是内存分配?
    • 其实你应该知道dwSize == 256意味着分配了4096字节。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-01
    • 1970-01-01
    • 2018-02-20
    • 1970-01-01
    • 2015-09-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多