С++ операция указателя, эквивалентная ReadProcessMemory

Мне нужно прочитать память программы из другого приложения. У меня есть весь процесс и приложение "соединение" на месте.

У меня есть функция, которая ищет шаблон в памяти открытого процесса, и которая благодаря сигнатуре возвращает действительную точку входа в интересующую меня функцию.

Проблема в том, что инструкция по сборке, которая приводит меня к данным (которые я не могу найти по смещению или подписи), выглядит следующим образом:

H5Calc.exe+12DDC5B - E8 10F1FFFF           - call H5Calc.exe+12DCD70

Я искал вокруг и обнаружил, что это может служить моей цели:

return (MainClass*) *(DWORD*) PatternPointer;

но проблема в том, что приведенная выше строка будет работать при использовании «инъекции», а я использую ReadProcessMemory, поскольку мне это не разрешено.

Итак, может кто-нибудь помочь "перевести"

(MainClass*) *(DWORD*) PatternPointer;

операцию указателя в вызове ReadProcessMemory с учетом ассемблерной инструкции? Учитывая, что я открываю из другого приложения, у меня нет доступа к области памяти H5Calc, если не с помощью ReadProcessMemory (которую я могу регулярно вызывать для других операций).

Любая помощь приветствуется.

Спасибо.


person Alpha cockroach    schedule 29.10.2013    source источник
comment
ReadProcessMemory(hProc, (void *)0x12DCD70, &data, sizeof data, NULL);, может быть? (при условии, что data является DWORD или указателем, конечно.)   -  person    schedule 29.10.2013
comment
Я согласен, что это кажется логичным, но я не могу понять, как получить '12dcd70' ни из 'e8 10f1ffff', ни из 1sddc5b <= this one the address i get to from the signature :(   -  person Alpha cockroach    schedule 29.10.2013
comment
это справа от кода, который вы разместили...   -  person    schedule 29.10.2013
comment
правда, но это отладочная информация от отладчика. При использовании моей процедуры поиска шаблонов эта информация неизвестна, и у меня есть доступ только к последовательности байтов e8 10f1ffff0.   -  person Alpha cockroach    schedule 29.10.2013
comment
в этом случае вот как вы можете это сделать.   -  person    schedule 29.10.2013
comment
Пожалуйста, сделайте ответ из вашего комментария, чтобы я мог принять его и закрыть вопрос.   -  person Alpha cockroach    schedule 30.10.2013


Ответы (2)


Вы можете рассчитать фактический адрес, как описано здесь, т.е. е. вы берете адрес инструкции, следующей за прыжком, т.е.

0x12DDC5B + 5 = 0x12DDC60

затем вы берете смещение, которое представляет собой 32-битное целое число со знаком с прямым порядком байтов 2, поэтому

"0x10 0xF1 0xFF 0xFF" = 0xFFFFF110 - 0x100000000 = -0xEF0

Затем вы добавляете смещение к базовому адресу, вычисленному выше, чтобы получить

0x12DDC60 + (-0xEF0) = 0x12DCD70

В C это будет выглядеть примерно так:

unsigned char *jmp_ptr = (unsigned char *)0x12DDC5B;
int offset; // or use ptrdiff_t if it's 32 bits wide
ReadProcessMemory(hProc, jmp_ptr + 1, &offset, sizeof offset, NULL);
unsigned char *target_ptr = jmp_ptr + 5 + offset;

(примените стилистические сочетания для получения кода C++. Также проверьте возвращаемое значение функции и т. д.)

Теперь вы можете передать полученный адрес другому вызову ReadProcessMemory(), чтобы получить указатель на экземпляр:

MainClass *instance = NULL;
ReadProcessMemory(hProc, target_ptr, &instance, sizeof instance, NULL);
person Community    schedule 30.10.2013
comment
Это работает отлично, однако теперь у меня есть похожая проблема: H5Calc.exe+989E2A - 8B 0D 888C1D03 - mov ecx,[H5Calc.exe+2DD8C88] При отладке памяти я думаю, что это должно привести меня к 002BC768, но вышеприведенная логика, похоже, не применима. (блин, разве мы не можем ставить разрывы строк в комментариях?). Я понимаю, что инструкция MOV поддерживает как значения, так и адреса с правой стороны, но я не понимаю, как интерпретировать 888C1D03. - person Alpha cockroach; 03.11.2013
comment
@Alphacockroach Я предполагаю, что инструкция mov не имеет той же схемы двоичного кодирования, что и инструкция call. - person ; 03.11.2013

Вы можете использовать общую память между процессами. Если вы хотите знать, как это сделать, я могу опубликовать код. Windows API использует CreateFileMapping() и MapViewOfFile(). Тогда оба процесса смогут видеть одну и ту же память.

person resigned    schedule 29.10.2013
comment
спасибо, но мне сейчас не нужна реальная связь между процессами. Мне просто нужно было понять, как интерпретировать ASM, и уметь использовать readprocessmemory для выполнения необходимых операций. - person Alpha cockroach; 30.10.2013