Умение работать с памятью сторонних процессов - полезный навык адепта Темной стороны Силы. Таким способом можно найти нужные данные, хранящиеся в памяти, например, расшифрованные файлы, изображения, пароли, и еще много чего вкусного. Также этот навык пригодится при создании распаковщиков, лоадеров для программ и трейнеров для различных игр. Я привел лишь несколько примеров, на практике их можно найти гораздо больше.
Для построения карты памяти процесса используется функция
VirtualQueryEx и специальная структура
MEMORY_BASIC_INFORMATION. В FASM она как обычно не определена, придется сделать это самостоятельно в сегменте данных:
; Структура для чтения памяти процесса
struct MEMORY_BASIC_INFORMATION
BaseAddress dd ?
AllocationBase dd ?
AllocationProtect dd ?
RegionSize dd ?
State dd ?
Protect dd ?
Type dd ?
ends
; Структура для чтения памяти процесса
mbi MEMORY_BASIC_INFORMATION
Для работы с памятью процесса при помощи функции VirtualQueryEx нам надо знать хэндл этого процесса. Для дочерних, которые мы запустили сами, все просто: это значение hProcess из структуры PROCESS_INFORMATION. Если процесс порожден не нами, то для получения его хэндла, зная ID процесса, надо воспользоваться функцией
OpenProcess, обязательно с флагом PROCESS_QUERY_INFORMATION. Возможно, что перед этим потребуется
повысить привилегии нашего процесса, активировав SeDebugPrivilege.
Теперь у нас есть все инструменты и условия для работы, можно приступать к самому действу. Переменные, используемые в примере: ptMemory - указатель на текущий блок памяти, hProcess - хэндл исследуемого процесса, структура mbi определена выше.
...
; Начало памяти процесса
mov [ptMemory],0
.scan_memory:
; Получить данные о памяти процесса
invoke VirtualQueryEx, [hProcess], [ptMemory], mbi,\
sizeof.MEMORY_BASIC_INFORMATION
; Сканирование закончено?
or eax,eax
jz .stop_scan
...
; Здесь можно выполнять все необходимые действия с блоком памяти:
; проверить или изменить его атрибуты, записать дамп памяти на
; диск, поискать нужные сигнатуры и данные...
...
; Прибавить к указателю размер прочитанного региона
mov eax,[mbi.RegionSize]
add [ptMemory],eax
jmp .scan_memory
.stop_scan:
...
Блоки памяти процесса идут подряд, без разрывов, информация о каждом прочитанном блоке записывается в структуру mbi. Наиболее полезные для нас данные - это базовый адрес блока памяти mbi.BaseAddress и его размер mbi.RegionSize, а остальные, например, тип блока
или флаги Memory Protection, помогают более точно определить нужный участок памяти. Все возможные значения флагов подробно описаны в MSDN.
В приложении консольная программа с исходниками. После запуска она предлагает выбрать исполняемый файл, запускает его и показывает на экране его карту памяти с указанием адресов, размеров, типа и атрибутов каждого блока.