Получить модуль исполняемого файла в PyKD

В PyKD я могу получить имя процесса исполняемого файла следующим образом:

0:017> !py
...
>>> getProcessExeName()
u'C:\\Windows\\SysWOW64\\rundll32.exe'

и я могу получить информацию о модуле с

>>> print module("rundll32")
Module: rundll32
Start: 7f0000 End: 7fe000 Size: e000
Image: C:\Windows\SysWOW64\rundll32.exe
Symbols: e:\debug\symbols\rundll32.pdb\EFAE0C870C2846EDB63B9A7274CD50422\rundll32.pdb
Timestamp: 4a5bc637
Check Sum: 11cf2

Как мне преобразовать имя процесса в имя модуля?

Это не так просто, как извлечь имя файла, так как имена файлов со специальными символами, такими как Notepad++.exe превращается в notepad__ как имя модуля.

Предыстория: я хочу автоматизировать анализ дампа, и сначала я проверяю, является ли это моя программа, а во-вторых, я хочу проверить версию сбойной программы, для которой мне нужна информация о модуле. Я хочу сделать его немного более универсальным и рассмотреть случай, когда пользователь переименовывает исполняемый файл.

Версии (если это имеет значение): PyKD 0.3.0.25, 32 бит, WinDbg 6.2.9200, Python 2.7.8

1 ответ

Решение

Ваша проблема на самом деле более коварна, чем вы описываете. Я видел, где модули, загруженные с использованием их короткого (совместимого с MSDOS) имени, искажаются еще больше.

Единственное, что я могу придумать, чтобы ответить на ваш вопрос, это немного взломать. Если вы предполагаете, что модуль, занимающий самое низкое адресное пространство, является модулем исполняемого файла, то вы можете использовать lm с 1m флаг, чтобы перечислить все модули, но использовать только первый.

Это означает, что вы можете сделать:

0:001> !py c:\test.py
Module: notepad__
Start: 10000 End: 21c000 Size: 20c000
Image: C:\Program Files (x86)\Notepad++\notepad++.exe
Symbols: export symbols
Timestamp: 55ad8d3e
Check Sum: 0

куда test.py является:

from pykd import *

exeModuleName = dbgCommand("lm1m").split('\n')[0]
exeModule = module(exeModuleName)
print exeModule

Это все еще опирается на предположение. Хотя я заметил, что это верно для всех версий Windows вплоть до NT 4.0, но это не всегда так. Например, я бы не удивился, если бы рандомизация разметки адресного пространства ( ASLR) полностью нарушила это предположение для любого процесса, связанного с ним.


РЕДАКТИРОВАТЬ:

Немного более безопасный способ сделать это - посмотреть на PEB для ImageBaseAddress, Это начальный адрес модуля для базового модуля. Вы можете построить пикд module наберите из базового адреса вот так:

from pykd import *

peb = typedVar("ntdll!_PEB", getProcessOffset())
exeModule = module(peb.ImageBaseAddress)
print exeModule

Это должно работать более надежно и более предсказуемо, если _PEB структура когда-либо изменится.

Другие вопросы по тегам