Техника снятия дампа с защищенных приложений


             

Дамп извне


Прежде, чем читать адресное пространство чужого процесса, до него еще предстоит добраться. Windows изолирует процессы друг от друга на случай непреднамеренного удара по памяти (который сильно досаждал пользователям Windows3.x), но предоставляет специальный набор API-функций для межпроцессорного взаимодействия. Классический путь: получаем обработчик процесса который мы собрались дампить вызовом OpenProcess

и передаем его функции ReadProcessMemory

вместе с остальными параметрами (откуда и сколько байт читать). При этом необходимо учитывать, что некоторые страницы могут быть помечены защитой как недоступные и перед обращением к ним необходимо вызвать функцию VirtualProtectEx, разрешив полный доступ (PAGE_EXECUTE_READWRITE) или, по крайней мере, открыв страницы только на чтение (PAGE_READONLY).

Естественно, функции OpenProcess/ReadProcessMemory/VirtualProtectEx могут быть перехвачены защитой и тогда вместо дампа мы получим error, а то и reboot. Низкоуровневые функции NtOpenProcess/NtReadVirtualMemory/NtProtectVirtualMemory перехватываются с той же легкостью, к тому же некоторые защиты изменяют маркер безопасности процесса, запрещая открытие его памяти на чтение даже администратору!

Считается, что снятие дампа на уровне ядра открывает большие возможности для хакерства и противостоять этому никак невозможно, поскольку драйвер работает с наивысшим уровнем привилегий, который позволяет _все_. На самом деле, война драйверов за ядро только начинается. На голом процессоре далеко не уедешь и драйвер-дампер вынужден обращаться к сервисным функциям ядра. Причем, никаких документированных функций для чтения памяти чужого процесса (за исключением вышеупомянутых) в системе нет!

Чтобы читать память процесса напрямую, драйвер должен к нему подключиться, вызвав функцию KeAttachProcess или ее современный аналог KeStackAttachProcess, появившийся и впервые документированный в Windows 2000. Пользоваться обоими функциями следует с величайшей осторожностью и прежде, чем подключаться к другому процессу, необходимо отсоединится от текущего, вызывав KeDetachProcess/KeStackDeattachProcess.


Содержание  Назад  Вперед