Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 进程的读取进程内存不会返回所有内容_C++_Windows_Winapi_Memory_Readprocessmemory - Fatal编程技术网

C++ 进程的读取进程内存不会返回所有内容

C++ 进程的读取进程内存不会返回所有内容,c++,windows,winapi,memory,readprocessmemory,C++,Windows,Winapi,Memory,Readprocessmemory,我正在尝试扫描第三方应用程序的内存。我已经找到地址了;现在位于0x0643FB78。问题是,我永远无法到达那里,因为LPMODULEENTRY32->modBaseAddr是0x00400000,LPMODULEENTRY32->modBaseSize只是0x006FF000,因此我可以扫描这个模块的最大地址是0x00AFF000 这是否意味着我寻找的地址确实存在于另一个进程/模块/线程/某物中?不过,我很有信心,我的流程中确实包含了地址。那么我应该如何访问内存呢?谢谢。一个进程由内存页组成,这

我正在尝试扫描第三方应用程序的内存。我已经找到地址了;现在位于
0x0643FB78
。问题是,我永远无法到达那里,因为
LPMODULEENTRY32->modBaseAddr
0x00400000
LPMODULEENTRY32->modBaseSize
只是
0x006FF000
,因此我可以扫描这个模块的最大地址是
0x00AFF000


这是否意味着我寻找的地址确实存在于另一个进程/模块/线程/某物中?不过,我很有信心,我的流程中确实包含了地址。那么我应该如何访问内存呢?谢谢。

一个进程由内存页组成,这些内存页映射了特定的保护。这些页面封装在模块中。每个模块都有一个底座和一个尺寸。然而,ReadProcessMemory完全从您这里提取了这一点。无论内存在哪个模块中,您都应该能够读取内存

在这种情况下,内存不在正在查看的模块中。如果确实需要找到它所属的位置,可以使用CreateToolHelp32Snapshot、Module32First和Module32Next遍历模块,检查基数和大小


发布一些代码,我们可以帮助您找出哪里出了问题。为什么你这么肯定你要找的地址就是你说的地址?由于ASLR,地址通常使用基本模块+偏移量指定。如何处理目标流程?要使用ReadProcessMemory,您需要具有特定的访问权限。

至少在我看来,如果涉及到
LPMODULEENTRY
,那么您可能从错误的方向开始。我将使用
VirtualQueryEx
遍历目标进程中的内存块。这将为您提供有关该过程中每个块的
内存\u基本信息
。然后,您可以使用
ReadProcessMemory
并扫描各个块以找到您要查找的内容

下面是我编写的一些旧代码,用于执行大致相同的操作,但查找的是字符串而不是指针:

#include <iostream>
#include <vector>
#include <string>
#include <windows.h>
#include <algorithm>
#include <iterator>

template <class InIter1, class InIter2, class OutIter>
void find_all(unsigned char *base, InIter1 buf_start, InIter1 buf_end, InIter2 pat_start, InIter2 pat_end, OutIter res) {
    for (InIter1 pos = buf_start;
        buf_end!=(pos=std::search(pos, buf_end, pat_start, pat_end));
        ++pos)
    {
        *res++ = base+(pos-buf_start);
    }
}

template <class outIter>
void find_locs(HANDLE process, std::string const &pattern, outIter output) {

    unsigned char *p = NULL;
    MEMORY_BASIC_INFORMATION info;

    for ( p = NULL;
        VirtualQueryEx(process, p, &info, sizeof(info)) == sizeof(info);
        p += info.RegionSize ) 
    {
        std::vector<char> buffer;

        if (info.State == MEM_COMMIT && 
            (info.Type == MEM_MAPPED || info.Type == MEM_PRIVATE)) 
        {
            SIZE_T bytes_read;
            buffer.resize(info.RegionSize);
            ReadProcessMemory(process, p, &buffer[0], info.RegionSize, &bytes_read);
            buffer.resize(bytes_read);
            find_all(p, buffer.begin(), buffer.end(), pattern.begin(), pattern.end(), output);
        }
    }
}

int main(int argc, char **argv) {
    if (argc != 3) {
        fprintf(stderr, "Usage: %s <process ID> <pattern>", argv[0]);
        return 1;
    }

    int pid;
    sscanf(argv[1], "%i", &pid);

    std::string pattern(argv[2]);

    HANDLE process = OpenProcess( 
        PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, 
        false,
        pid);

    find_locs(process, pattern, 
        std::ostream_iterator<void *>(std::cout, "\n"));

    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
模板
void find_all(unsigned char*base、InIter1 buf_start、InIter1 buf_end、InIter2 pat_start、InIter2 pat_end、OutIter res){
对于(初始位置=buf_开始;
buf_end!=(pos=std::search(pos,buf_end,pat_start,pat_end));
++pos)
{
*res++=base+(pos-buf_启动);
}
}
模板
无效查找位置(句柄进程、标准::字符串常量和模式、输出){
无符号字符*p=NULL;
内存\基本信息\信息;
for(p=NULL;
VirtualQueryEx(进程、p和信息,sizeof(信息))==sizeof(信息);
p+=信息区域大小)
{
向量缓冲区;
如果(info.State==MEM_COMMIT&&
(info.Type==MEM_-MAPPED | | info.Type==MEM_-PRIVATE))
{
读取的字节大小;
缓冲区大小(信息区域大小);
ReadProcessMemory(进程、p和缓冲区[0]、info.RegionSize和字节读取);
调整缓冲区大小(字节\读取);
查找所有(p,buffer.begin(),buffer.end(),pattern.begin(),pattern.end(),output);
}
}
}
int main(int argc,字符**argv){
如果(argc!=3){
fprintf(stderr,“用法:%s”,argv[0]);
返回1;
}
int-pid;
sscanf(argv[1]、“%i”和pid);
std::字符串模式(argv[2]);
句柄进程=OpenProcess(
处理(VM)读取|处理(QUERY)信息,,
假,,
pid);
查找位置(流程、模式、,
std::ostream_迭代器(std::cout,“\n”);
返回0;
}

MODULEENTRY为您提供代码地址。你肯定对数据更感兴趣?它可以出现在任何地方,具体取决于Windows分配堆的位置。或者数据部分,希望如此,因为如果该地址实际上在堆中,您将几乎没有希望获得可重复的地址。使用VirtualQueryEx()枚举地址空间中的分配。太好了,这肯定会让我走上正确的道路。谢谢你。@Jerry Coffin-+1给了我一个很好的答案。我想进一步问两件事:1)一旦我将页面内容读入char vector
std::vector buffer
——我应该如何“处理”它?我的意思是,它包含ASCII字符还是UTF-8/UTF-16编码字符?如果内存中包含ASCII字符,如何将它们转换为Unicode(我想应该是UTF-16)?2) 使用
std::vector::iterator pos
的确切目的是什么?非常感谢你的帮助@GuyAvraham:数据是从目标进程逐字复制的,所以它是以目标进程使用的任何格式
pos
是早期版本代码的遗留版本,它根本没有被使用。谢谢,这是我所缺乏的洞察力。我接受了杰瑞的回答,因为他有代码样本。