c++ - 在另一个进程的内存中搜索字符串的每次出现

标签 c++ memory readprocessmemory

我正在尝试检索某个字符串的每次出现,例如“ExampleString”。我目前所拥有的将在进程内存中找到该字符串的第一次出现,但不会找到后续字符串。我尝试使用 vector 来存储所有结果,但它仍然只找到一个结果。

下面是我用来获取内存位置 vector 的函数。同样,它适用于第一个位置。

std::vector<char*> GetAddressOfData(DWORD pid, const char *data, size_t len) {
    HANDLE process = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, pid);

    std::vector<char*> locations;
    int cur = 0;
    if(process){
        SYSTEM_INFO si;
        GetSystemInfo(&si);

        MEMORY_BASIC_INFORMATION info;
        std::vector<char> chunk;
        char* p = 0;
        while(p < si.lpMaximumApplicationAddress){
            if(VirtualQueryEx(process, p, &info, sizeof(info)) == sizeof(info)){
                p = (char*)info.BaseAddress;
                chunk.resize(info.RegionSize);
                SIZE_T bytesRead;
                if(ReadProcessMemory(process, p, &chunk[0], info.RegionSize, &bytesRead)){
                    for(size_t i = 0; i < (bytesRead - len); ++i){
                        if(memcmp(data, &chunk[i], len) == 0) {
                            cur++;
                            locations.resize(cur);
                            locations[cur-1] = (char*)p + i;
                            std::cout << "Found*: " << (void*)locations[cur-1] << "\n";
                        }
                    }
                }
                p += info.RegionSize;
            }
        }
    }
    return locations;
}

最佳答案

这是我几年前编写的一些代码,基本上可以满足您的要求:

#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;
        std::vector<char>::iterator pos;

        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;
}

我确实认为值得注意的是,您的代码看起来与此具有大部分相同的一般思想 - 差异主要在于细节,至少乍一看可能看起来相当微不足道(但我想这不是令人惊讶的是,考虑到您的代码足够接近,至少可以找到初始出现的情况)。

关于c++ - 在另一个进程的内存中搜索字符串的每次出现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36878017/

相关文章:

关于编写代码的 C++ 建议

java - 这是内存泄漏吗?

c++ - 获取进程的基址

Python-将字节地址(从ReadProcessMemory)转换为字符串?

C++/CPP 读取添加的十六进制地址

c++ - 运算符重载 : cannot add two pointers

c++ - 尝试在终端(MacOSX)中编译两个.cpp文件(来自XCode)时的“Duplicate symbol”

c++ - 使 QML 项/控件接受事件,从而不将它们转发给父级

使用字符串文字处理 char * init 时崩溃,但使用 malloc 时不崩溃

C语言: pointer returned by malloc() and casting