Хотя это не упоминается в тегах, на основании упоминания ReadProcessMemory
, я собираюсь предположить, что вы хотите это для Windows.
Для этого достаточно использовать VirtualQuery
, чтобы выяснить, какие части вашего адресного пространства можно использовать (особенно важно в 64-битных системах, где допустимые адреса намного реже, чем в 32-разрядных системах) ,
кода с использованием VirtualQuery, чтобы найти доступные для поиска блоков может выглядеть примерно так:
#include <iostream>
#include <vector>
#include <string>
#include <windows.h>
#include <algorithm>
#include <iterator>
template <class InIter1, class InIter2, class OutIter>
void find_all(InIter1 buf_begin, InIter1 buf_end, InIter2 pat_begin, InIter2 pat_end, OutIter output) {
for (auto pos = buf_begin;
buf_end != (pos = std::search(pos, buf_end, pat_begin, pat_end));
++pos)
{
*output++ = (void *)pos;
}
}
template <class outIter>
void find_locs(std::string const &pat, outIter output) {
unsigned char *p;
MEMORY_BASIC_INFORMATION info;
for (p = nullptr;
VirtualQuery(p, &info, sizeof(info)) == sizeof(info);
p += info.RegionSize)
{
if (info.State == MEM_COMMIT &&
(info.Type == MEM_MAPPED || info.Type == MEM_PRIVATE))
{
find_all(p, p + info.RegionSize, pat.begin(), pat.end(), output);
}
}
}
int main(int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "Usage: %s <pattern>", argv[0]);
return 1;
}
find_locs(argv[1], std::ostream_iterator<void *>(std::cout, "\n"));
}
Ожидать этого оказаться несколько «ложных» матчей. В частности, даже если строка, которую вы ищете, не встречается нигде в пространстве памяти процесса, будет одна копия как часть argv
и (по крайней мере) еще одна для временного std::string
, которая передается в find_locs
, так что ожидайте голый минимум двух совпадений для любой строки, которую вы можете передать.
Возможно, вы также захотите прочитать документы за MEMORY_BASIC_INFORMATION
. Я выбрал подмножество блоков, которые (я уверен) безопасен для чтения (т. Е. Те, которые были зафиксированы и сопоставлены или закрыты), но в зависимости от того, что вы ищете, вы можете изменить это на ограничивать его поиском только через текст программы, а не текст и данные.
Эта строка 's = (char *) i;' уже приведет к неопределенному поведению. 'i' не является строкой с нулевым завершением. – juanchopanza
Да, я понял это, но вопрос в том, как я могу это исправить? Или любой другой способ предотвратить его сбой? – John
'VirtualQuery' может сказать вам, какие области адресного пространства поддерживаются фактической памятью. Или вы можете исследовать с помощью 'IsBadReadPtr'. Или вы можете продолжить работу и получить доступ к памяти под блоком '__try/__ except' и соответствующим образом обрабатывать исключения SEH. –