In PyKD I can get the executable's process name like this:
0:017> !py
...
>>> getProcessExeName()
u'C:\\Windows\\SysWOW64\\rundll32.exe'
and I can get module information with
>>> 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
How do I convert from the process name to the module name?
It's not as simple as extracting the file name, since file names with special characters like Notepad++.exe
converts to notepad__
as module name.
Background: I want to automate dump analysis and first I check whether it's my program at all and second I want to check the version of the crashed program for which I need the module information. I want to make it a bit more universal and consider the case that the user renames the executable.
Versions (if that matters): PyKD 0.3.0.25, 32 bit, WinDbg 6.2.9200, Python 2.7.8
Your issue is actually more insidious than you describe. I've seen where modules loaded using their short (MSDOS compatible) name are mangled even more.
The only thing I can come up with to answer your question is a bit of a hack. If you assume that the module occupying the lowest address space is the executable's module, then you can use lm
with the 1m
flag to list all modules but only use the first one.
This means you can do:
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
Where test.py
is:
from pykd import *
exeModuleName = dbgCommand("lm1m").split('\n')[0]
exeModule = module(exeModuleName)
print exeModule
This is still relies on an assumption. Although, I have observed it to be true for all versions of Windows back to NT 4.0, that may not always be the case. For example, I would not be the least bit surprised if Address Space Layout Randomization (ASLR) completely broke this assumption for any process linked with it enabled.
EDIT:
A little bit safer way to do this is to look at the PEB
for the ImageBaseAddress
. This is the module start address for the base module. You can construct a pykd module
type out of the base address like so:
from pykd import *
peb = typedVar("ntdll!_PEB", getProcessOffset())
exeModule = module(peb.ImageBaseAddress)
print exeModule
This should work a bit more reliably, and fail more predicably, were the _PEB
structure ever to change.