【问题标题】:Scanning process memory causes crash扫描进程内存导致崩溃
【发布时间】:2012-12-17 08:18:29
【问题描述】:

我已将我的 DLL 注入到进程中,我尝试扫描内存以查找与我的值相同的地址,但在我获得第一个地址后导致崩溃,它应该是 10 个地址

for(DWORD i = MEM_START; i< MEM_END ;i++)
{
    VirtualQuery((void*)i,pMemInfo,sizeof(MEMORY_BASIC_INFORMATION));
    if(pMemInfo->AllocationProtect == PAGE_READONLY || PAGE_EXECUTE_WRITECOPY || PAGE_READWRITE || PAGE_WRITECOMBINE)
    {
        if(*(DWORD*)i==1337)
        {
           addresses.push_back(i);
        }
    } 
}

我认为我的保护检查是错误的,但不太确定。

【问题讨论】:

  • 您能解释一下您正在尝试解决的问题,您认为扫描内存会有所帮助吗?作为一种工程技术,内存扫描本质上是不可靠的,访问保护页面可能会使应用程序崩溃。
  • 嗯,应用程序有多个管理器,它们的值都为 0810312,并且指针总是在变化,所以我不能使用它们来获取正确的地址,是的,这些是唯一具有 0810312 作为其 int 值的地址

标签: c++ memory allocation wow64 virtualquery


【解决方案1】:

虚拟内存扫描器

MEMORY_BASIC_INFORMATION mbi = {0};
unsigned char *pAddress   = NULL,
              *pEndRegion = NULL;

DWORD   dwFindData          = 0xBAADF00D,
        dwProtectionMask    = PAGE_READONLY | PAGE_EXECUTE_WRITECOPY 
                              | PAGE_READWRITE | PAGE_WRITECOMBINE;

while( sizeof(mbi) == VirtualQuery(pEndRegion, &mbi, sizeof(mbi)) ){
    pAddress = pEndRegion;
    pEndRegion += mbi.RegionSize;
    if ((mbi.AllocationProtect & dwProtectionMask) && (mbi.State & MEM_COMMIT)){
         for (pAddress; pAddress < pEndRegion ; pAddress++){
             if (*pAddress == dwFindData){
                 // dostaff  
             }
         }
    }
}

【讨论】:

  • 我一调用它仍然会导致崩溃
  • 我注入 dll 的应用程序是 32 位的,扫描工作在第一个结果上,但之后它到达未分配或受保护的内存然后崩溃,我插入了中断;当它找到第一个地址但似乎虚拟查询正在崩溃时,如果我使用 break 在我的原始代码上,它将打印出一个地址
【解决方案2】:

是的,有几个错误。您需要使用 |运算符而不是 ||。 i 的值没有意义,您必须使用 MEMORY_BASIC_INFORMATION.AllocationBase 来查找区域的开始位置。和 .RegionSize 知道它有多大。传递给 VirtualQuery 的下一个值应该是 .AllocationBase + .RegionSize 以查找下一个区域。

【讨论】:

    【解决方案3】:

    || 运算符不是这样工作的。您可能会发现改用 switch 语句更具可读性。

    for (DWORD i = MEM_START; i < MEM_END ;i++)
    {
        VirtualQuery((void*)i, pMemInfo, sizeof(MEMORY_BASIC_INFORMATION));
        switch (pMemInfo->AllocationProtect)
        {
        case PAGE_READONLY:
        case PAGE_EXECUTE_WRITECOPY:
        case PAGE_READWRITE:
        case PAGE_WRITECOMBINE:
            if(*(DWORD*)i==1337)
            {
               addresses.push_back(i);
            }
        } 
    }
    

    【讨论】:

    • @HansPassant 这在另一个方向上有点过于简单了,尽管我同意看起来| 应该适用于他的用例。
    • 仍然不知道如何执行此操作..,总是导致崩溃
    猜你喜欢
    • 2014-11-22
    • 2016-02-21
    • 1970-01-01
    • 1970-01-01
    • 2011-07-08
    • 1970-01-01
    • 2015-08-15
    • 2021-03-28
    • 1970-01-01
    相关资源
    最近更新 更多