1

我目前正在使用 C++ 重新创建一个内存修改器应用程序,原来是在 C# 中。

所有功劳归于我一直在 YouTube 上关注的教程“gimmeamilk” (视频 1 of 8)。我强烈推荐任何尝试创建类似应用程序的人使用这些教程。

我遇到的问题是我的 VirtualQueryEx 似乎永远运行。我正在扫描的进程是“notepad.exe”,我通过命令行参数传递给应用程序。

std::cout<<"Create scan started\n";
#define WRITABLE (PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY) //These are all the flags that will be used to determin if a memory block is writable.
MEMBLOCK * mb_list = NULL;          //pointer to the head of the link list to be returned
MEMORY_BASIC_INFORMATION meminfo;   //holder for the VirtualQueryEx return struct
unsigned char *addr = 0;            //holds the value to pass to VirtualQueryEx

HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS,false, pid);
if(hProc) 
{
    while(1)
    {
        if(VirtualQueryEx(hProc,addr, &meminfo, sizeof(meminfo)) == 0) 
        {
            break;
        }


        if((meminfo.State & MEM_COMMIT) && (meminfo.Protect & WRITABLE)) //((binary comparison of meminfos state and MEM_COMMIT, this is basically filtering out memory that the process has reserved but not used)())
        {
            MEMBLOCK * mb = create_memblock(hProc, &meminfo);
            if(mb)
            {
                mb->next = mb_list;
                mb_list = mb;
            }
        }
        addr = (unsigned char *)meminfo.BaseAddress + meminfo.RegionSize;//move the adress along by adding on the length of the current block

    }
}
else
{
    std::cout<<"Failed to open process\n";
}
std::cout<<"Create scan finished\n";

return mb_list;

此代码的输出导致

Create scan started on process:7228

然后它不会向控制台返回任何其他内容。不幸的是,通过 Youtube 视频链接到的示例源代码不再可用。(7228会根据notepad.exe的当前pid变化)

编辑回复问题@Hans Passant 我还是不明白,我认为我在做的是

Starting a infinite loop
{
   Testing using vqx if the address is valid and populating my MEM_BASIC_etc..
   {
        (has the process commited to using that addr of memory)(is the memory writeable)
        {
            create memblock etc
        } 
   }
   move the address along by the size of the current block
}

我的程序是 x32,记事本也是(据我所知)。

我的问题是因为我使用的是 x64 位操作系统,因此我实际上正在检查一个块的一半(这里的块意味着操作系统在内存中分配的单元)并导致它循环?

非常感谢您的帮助!我想了解我的问题并解决它。

4

1 回答 1

0

您的问题是您正在编译一个 32 位程序并使用它来解析 64 位程序的内存。您将“addr”定义为无符号字符指针,在本例中为 32 位。它不能包含 64 位地址,这是您的问题的原因。

如果您的目标进程是 64 位,请将您的程序也编译为 64 位。对于 32 位目标进程,编译为 32 位。这通常是处理外部进程内存的最佳技术,也是最快的解决方案。

根据您的操作,您还可以使用 #ifdef 和其他条件来根据目标使用 64 位变量,但原始解决方案通常更容易。

于 2020-03-28T22:13:51.587 回答