Получить модуль исполняемого файла в 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
структура когда-либо изменится.