在另一个进程的内存中搜索字符串的每次出现 [英] Searching for every occurrence of a string in another process's memory
问题描述
我正在尝试检索某个特定字符串的每次出现,例如"ExampleString".我目前拥有的东西将在进程的内存中找到该字符串的第一个匹配项,但找不到后续的字符串.我尝试使用vector
存储所有结果,但仍然只能找到一个结果.
I am attempting to retrieve every occurrence of a certain string, say "ExampleString". What I currently have will find the first occurrence of the string in a process's memory but it won't find the subsequent strings. I tried to use a vector
to store all the results but it only finds one result still.
下面是我用来获取内存位置向量的函数.同样,它适用于第一个位置.
Below is the function I am using to get the vector of memory locations. Again, it works for the first location.
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;
}
推荐答案
这是我几年前编写的一些代码,基本上可以满足您的要求:
Here's some code I wrote years ago to do essentially what you're asking for:
#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;
}
我确实值得一提的是,您的代码看起来与大多数代码具有相同的一般思想-区别主要在于细节,至少乍一看似乎很琐碎(但我想并不是这样)令人惊讶的是,鉴于您的代码足够接近至少可以找到一个初始出现的地方.
I do think it's worth noting that it looks like your code has most of the same general ideas as this does--the differences are primarily in details that probably look pretty trivial, at least at first glance (but I guess that's not surprising, given that your code is close enough to at least find an initial occurrence).
这篇关于在另一个进程的内存中搜索字符串的每次出现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!