- How to use Python to load DLL.
- How to read PDB file to report file path and line number by a given IP register value.
- How to use python ctypes.
I select Python to try DBGHELP.DLL because Python is easy for use. Below is the source code. You can run it with the command.
> python DbgHelpTest.py
You can see the results.
DbgHelpTest.py
#
# This source code is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This Python program demonstrates the usage of Windows DBGHELP.DLL by the
# below steps.
#
# 1. Locate functions of DBGHELP.DLL.
# 2. Load a PDB file at base address.
# 3. Input IP register value.
# 4. Output file path and line number of source code.
#
# Copyright (c) 2014 Count Chu.
#
import os
import ctypes
#
# Please set parameters here.
#
PdbFileName = "VcApp.pdb" # A PDB file that was created by you.
BaseAddr = ctypes.c_uint64 (0x400000) # Base address of the PDB file that will be loaded.
IpAddr = ctypes.c_uint64 (0x4113B0) # IP register value that will be input.
#
# Locate functions of DBGHELP.DLL that are used in the program.
#
DbgHelp = ctypes.WinDLL (r"dbghelp.dll")
print DbgHelp # for debug.
SymInitialize = DbgHelp ["SymInitialize"]
SymSetOptions = DbgHelp ["SymSetOptions"]
SymLoadModule64 = DbgHelp ["SymLoadModule64"]
SymGetLineFromAddr64 = DbgHelp ["SymGetLineFromAddr64"]
SymUnloadModule64 = DbgHelp ["SymUnloadModule64"]
#
# Define enumeration that is used in SymSetOptions.
#
class SymOpt:
LOAD_LINES = 0x00000010
UNDNAME = 0x00000002
DEFERRED_LOADS = 0x00000004
#
# Call SymSetOptions().
#
print ("Call SymSetOptions()") # for debug.
SymSetOptions (SymOpt.LOAD_LINES | SymOpt.UNDNAME | SymOpt.DEFERRED_LOADS)
#
# Get the current process handle. It should be -1.
#
ProcessHandle = ctypes.windll.kernel32.GetCurrentProcess ()
print ("ProcessHandle = %xh" % ProcessHandle) # for debug.
#
# Call SymInitialize().
#
print ("Call SymInitialize()") # for debug.
Status = SymInitialize (ProcessHandle, None, False)
if not Status:
print "Error. Calling SymInitialize() failed."
#
# Call SymLoadModule64().
#
FileSize = os.path.getsize (PdbFileName)
print ("FileSize = %d" % FileSize) # for debug.
print ("Call SymLoadModule64()") # for debug.
OutBaseAddr = SymLoadModule64 ( # DWORD64 WINAPI SymLoadModule64 (
ProcessHandle, # _In_ HANDLE hProcess,
0, # _In_opt_ HANDLE hFile,
PdbFileName, # _In_opt_ PCSTR ImageName,
None, # _In_opt_ PCSTR ModuleName,
BaseAddr, # _In_ DWORD64 BaseOfDll,
FileSize) # _In_ DWORD SizeOfDll
# );
print ("OutBaseAddr = %xh" % OutBaseAddr) # for debug.
#
# Declare IMAGEHLP_LINE64 structure and create a instance of it.
#
class IMAGEHLP_LINE64 (ctypes.Structure): # typedef struct _IMAGEHLP_LINE64 {
_fields_ = [ #
('SizeOfStruct', ctypes.c_uint32), # DWORD SizeOfStruct;
('Key', ctypes.c_void_p), # PVOID Key;
('LineNumber', ctypes.c_uint32), # DWORD LineNumber;
('FileName', ctypes.c_char_p), # PTSTR FileName;
('Address', ctypes.c_uint64) # DWORD64 Address;
] # } IMAGEHLP_LINE64, *PIMAGEHLP_LINE64;
Line = IMAGEHLP_LINE64 () # Create a instance of IMAGEHLP_LINE64.
#
# Call SymGetLineFromAddr64()
#
print ("Call SymGetLineFromAddr64()") # for debug.
Displacement = ctypes.c_uint32 (0)
Status = SymGetLineFromAddr64 ( # BOOL WINAPI SymGetLineFromAddr64 (
ProcessHandle, # _In_ HANDLE hProcess,
IpAddr, # _In_ DWORD64 dwAddr,
ctypes.byref (Displacement), # _Out_ PDWORD pdwDisplacement,
ctypes.byref (Line)) # _Out_ PIMAGEHLP_LINE64 Line
# );
print ("Status = %xh" % Status) # for debug.
if not Status:
print "Error. Calling SymGetLineFromAddr64() failed."
#
# Dump Displacement and IMAGEHLP_LINE64.
#
print ("Displacement = %d" % Displacement.value)
print ("Dump Line:")
print (" SizeOfStruct = %d" % Line.SizeOfStruct)
print (" Key = %s" % Line.Key)
print (" LineNumber = %d" % Line.LineNumber)
print (" FileName = %s" % Line.FileName)
print (" Address = %xh" % Line.Address)
#
# Call SymUnloadModule64()
#
Status = SymUnloadModule64 (ProcessHandle, BaseAddr)
if not Status:
print "Error. Calling SymUnloadModule64() failed."
No comments:
Post a Comment