Skip to content

Instantly share code, notes, and snippets.

@w4kfu
Last active April 5, 2018 14:40
Show Gist options
  • Save w4kfu/f4fc1fd7ba33d69026f028cb4795e0a6 to your computer and use it in GitHub Desktop.
Save w4kfu/f4fc1fd7ba33d69026f028cb4795e0a6 to your computer and use it in GitHub Desktop.
fuck DIA
import argparse
import ctypes
import os
HANDLE = ctypes.c_void_p
HMODULE = HANDLE
DWORD = ctypes.c_uint
DWORD64 = ctypes.c_uint64
PVOID = ctypes.c_void_p
BOOL = ctypes.c_bool
LPSTR = ctypes.c_char_p
ULONG = ctypes.c_uint32
ULONG64 = ctypes.c_uint64
WCHAR = ctypes.c_wchar
CHAR = ctypes.c_char
SYMOPT_UNDNAME = 0x00000002
SYMOPT_NO_CPP = 0x00000008
SYMOPT_IGNORE_NT_SYMPATH = 0x00001000
ERROR_SUCCESS = 0x00000000
SYMOPT_ALLOW_ABSOLUTE_SYMBOLS = 0x00000800
MAX_SYM_NAME = 2000
class SYM_INFO(ctypes.Structure):
_fields_ = [
("SizeOfStruct", ULONG),
("TypeIndex", ULONG),
("Reserved", ULONG64 * 2),
("Index", ULONG),
("Size", ULONG),
("ModBase", ULONG64),
("Flags", ULONG),
("Value", ULONG64),
("Address", ULONG64),
("Register", ULONG),
("Scope", ULONG),
("Tag", ULONG),
("NameLen", ULONG),
("MaxNameLen", ULONG),
("Name", CHAR * (MAX_SYM_NAME + 1)),
]
def __repr__(self):
return "TypeIndex : {0} ; Index : {1} ; Size : 0x{2:08X} ; ModBase : 0x{3:016X} ; Address : 0x{4:016X}".format(self.TypeIndex, self.Index, self.Size, self.ModBase, self.Address)
def __str__(self):
return "TypeIndex : {0} ; Index : {1} ; Size : 0x{2:08X} ; ModBase : 0x{3:016X} ; Address : 0x{4:016X}".format(self.TypeIndex, self.Index, self.Size, self.ModBase, self.Address)
PSYM_INFO = ctypes.POINTER(SYM_INFO)
def RaiseIfZero(result, func = None, arguments = ()):
if not result:
raise ctypes.WinError()
return result
def RaiseIfNotZero(result, func = None, arguments = ()):
if result:
raise ctypes.WinError()
return result
#
# BOOL WINAPI SetEnvironmentVariable(
# _In_ LPCTSTR lpName,
# _In_opt_ LPCTSTR lpValue
# );
#
def SetEnvironmentVariable(name, value):
_SetEnvironmentVariable = ctypes.windll.kernel32.SetEnvironmentVariableA
_SetEnvironmentVariable.argtypes = [LPSTR, LPSTR]
_SetEnvironmentVariable.restype = BOOL
_SetEnvironmentVariable.errcheck = RaiseIfZero
return _SetEnvironmentVariable(name, value)
#
# DWORD WINAPI GetEnvironmentVariable(
# _In_opt_ LPCTSTR lpName,
# _Out_opt_ LPTSTR lpBuffer,
# _In_ DWORD nSize
# );
#
def GetEnvironmentVariable(name):
_GetEnvironmentVariable = ctypes.windll.kernel32.GetEnvironmentVariableA
_GetEnvironmentVariable.argtypes = [LPSTR, LPSTR, DWORD]
_GetEnvironmentVariable.restype = DWORD
_GetEnvironmentVariable.errcheck = RaiseIfZero
n = _GetEnvironmentVariable(name, None, 0x00)
if n == 0x00:
return None
buf = ctypes.create_string_buffer("\x00" * n)
_GetEnvironmentVariable(name, buf, n)
return buf.value
#
# HMODULE WINAPI LoadLibrary(
# _In_ LPCTSTR lpFileName
# );
#
def LoadLibrary(dll):
_LoadLibraryA = ctypes.windll.kernel32.LoadLibraryA
_LoadLibraryA.argtypes = [LPSTR]
_LoadLibraryA.restype = HMODULE
_LoadLibraryA.errcheck = RaiseIfZero
return _LoadLibraryA(dll)
#
# FARPROC WINAPI GetProcAddress(
# _In_ HMODULE hModule,
# _In_ LPCSTR lpProcName
# );
#
def GetProcAddress(hmod, func):
_GetProcAddress = ctypes.windll.kernel32.GetProcAddress
_GetProcAddress.argtypes = [HMODULE, LPSTR]
_GetProcAddress.restype = PVOID
_GetProcAddress.errcheck = RaiseIfZero
return _GetProcAddress(hmod, func)
#
# BOOL WINAPI FreeLibrary(
# _In_ HMODULE hModule
# );
#
def FreeLibrary(hmod):
_FreeLibrary = ctypes.windll.kernel32.FreeLibrary
_FreeLibrary.argtypes = [HMODULE]
_FreeLibrary.restype = BOOL
_FreeLibrary.errcheck = RaiseIfZero
return _FreeLibrary(hmod)
#
# DWORD WINAPI SymGetOptions(void);
#
def SymGetOptions():
_SymGetOptions = ctypes.windll.dbghelp.SymGetOptions
_SymGetOptions.argtypes = []
_SymGetOptions.restype = DWORD
return _SymGetOptions()
#
# DWORD WINAPI SymSetOptions(
# __in DWORD SymOptions
# );
#
def SymSetOptions(SymOptions):
_SymSetOptions = ctypes.windll.dbghelp.SymSetOptions
_SymSetOptions.argtypes = [DWORD]
_SymSetOptions.restype = DWORD
_SymSetOptions.errcheck = RaiseIfZero
return _SymSetOptions(SymOptions)
#
# BOOL WINAPI SymInitialize(
# __in HANDLE hProcess,
# __in_opt PCTSTR UserSearchPath,
# __in BOOL fInvadeProcess
# );
#
def SymInitializeA(hProcess, UserSearchPath = None, fInvadeProcess = False):
_SymInitialize = ctypes.windll.dbghelp.SymInitialize
_SymInitialize.argtypes = [HANDLE, LPSTR, BOOL]
_SymInitialize.restype = BOOL
_SymInitialize.errcheck = RaiseIfZero
return _SymInitialize(hProcess, UserSearchPath, fInvadeProcess)
#
# DWORD64 WINAPI SymLoadModule64(
# __in HANDLE hProcess,
# __in_opt HANDLE hFile,
# __in_opt PCSTR ImageName,
# __in_opt PCSTR ModuleName,
# __in DWORD64 BaseOfDll,
# __in DWORD SizeOfDll
# );
#
def SymLoadModule64(hProcess, hFile = None, ImageName = None, ModuleName = None, BaseOfDll = 0x00, SizeOfDll = 0x00):
_SymLoadModule64 = ctypes.windll.dbghelp.SymLoadModule64
_SymLoadModule64.argtypes = [HANDLE, HANDLE, LPSTR, LPSTR, DWORD64, DWORD]
_SymLoadModule64.restype = DWORD64
lpBaseAddress = _SymLoadModule64(hProcess, hFile, ImageName, ModuleName, BaseOfDll, SizeOfDll)
if lpBaseAddress == 0x00:
dwErrorCode = ctypes.windll.kernel32.GetLastError()
if dwErrorCode != ERROR_SUCCESS:
raise ctypes.WinError(dwErrorCode)
return lpBaseAddress
# DWORD64 WINAPI SymLoadModuleEx(
# _In_ HANDLE hProcess,
# _In_ HANDLE hFile,
# _In_ PCTSTR ImageName,
# _In_ PCTSTR ModuleName,
# _In_ DWORD64 BaseOfDll,
# _In_ DWORD DllSize,
# _In_ PMODLOAD_DATA Data,
# _In_ DWORD Flags
# );
def SymLoadModuleEx(hProcess, hFile = None, ImageName = None, ModuleName = None, BaseOfDll = None, SizeOfDll = 0x00):
_SymLoadModuleEx = ctypes.windll.dbghelp.SymLoadModuleEx
_SymLoadModuleEx.argtypes = [HANDLE, HANDLE, LPSTR, LPSTR, DWORD64, DWORD, PVOID, DWORD]
_SymLoadModuleEx.restype = DWORD64
lpBaseAddress = _SymLoadModuleEx(hProcess, hFile, ImageName, ModuleName, BaseOfDll, SizeOfDll, None, 0x00)
if lpBaseAddress == 0x00:
dwErrorCode = ctypes.windll.kernel32.GetLastError()
if dwErrorCode != ERROR_SUCCESS:
raise ctypes.WinError(dwErrorCode)
return lpBaseAddress
#
# BOOL WINAPI SymFromName(
# __in HANDLE hProcess,
# __in PCTSTR Name,
# __inout PSYMBOL_INFO Symbol
# );
#
def SymFromName(hProcess, Name):
_SymFromNameA = ctypes.windll.dbghelp.SymFromName
_SymFromNameA.argtypes = [HANDLE, LPSTR, PSYM_INFO]
_SymFromNameA.restype = BOOL
_SymFromNameA.errcheck = RaiseIfZero
SymInfo = SYM_INFO()
SymInfo.SizeOfStruct = ctypes.sizeof(SYM_INFO) - MAX_SYM_NAME
SymInfo.MaxNameLen = MAX_SYM_NAME
_SymFromNameA(hProcess, Name, ctypes.byref(SymInfo))
return SymInfo
PSYM_ENUMSYMBOLS_CALLBACK64 = ctypes.WINFUNCTYPE(BOOL, LPSTR, DWORD64, ULONG, PVOID)
# BOOL WINAPI SymEnumerateSymbols64(
# __in HANDLE hProcess,
# __in ULONG64 BaseOfDll,
# __in PSYM_ENUMSYMBOLS_CALLBACK64 EnumSymbolsCallback,
# __in_opt PVOID UserContext
# );
def SymEnumerateSymbols64A(hProcess, BaseOfDll, EnumSymbolsCallback, UserContext = None):
_SymEnumerateSymbols64 = ctypes.windll.dbghelp.SymEnumerateSymbols64
_SymEnumerateSymbols64.argtypes = [HANDLE, ULONG64, PSYM_ENUMSYMBOLS_CALLBACK64, PVOID]
_SymEnumerateSymbols64.restype = BOOL
_SymEnumerateSymbols64.errcheck = RaiseIfZero
EnumSymbolsCallback = PSYM_ENUMSYMBOLS_CALLBACK64(EnumSymbolsCallback)
_SymEnumerateSymbols64(hProcess, BaseOfDll, EnumSymbolsCallback, UserContext)
#
# BOOL WINAPI SymEnumerateSymbols64(
# __in HANDLE hProcess,
# __in ULONG64 BaseOfDll,
# __in PSYM_ENUMSYMBOLS_CALLBACK64 EnumSymbolsCallback,
# __in_opt PVOID UserContext
# );
#
def SymEnumSymbols(hProcess, BaseOfDll, Mask, EnumSymbolsCallback, UserContext = None):
_SymEnumSymbols = ctypes.windll.dbghelp.SymEnumSymbols
_SymEnumSymbols.argtypes = [HANDLE, ULONG64, LPSTR, PSYM_ENUMSYMBOLS_CALLBACK64, PVOID]
_SymEnumSymbols.restype = BOOL
_SymEnumSymbols.errcheck = RaiseIfZero
EnumSymbolsCallback = PSYM_ENUMSYMBOLS_CALLBACK64(EnumSymbolsCallback)
r = _SymEnumSymbols(hProcess, BaseOfDll, Mask, EnumSymbolsCallback, UserContext)
print r
#
# BOOL WINAPI SymGetSearchPath(
# _In_ HANDLE hProcess,
# _Out_ PTSTR SearchPath,
# _In_ DWORD SearchPathLength
# );
#
def SymGetSearchPath(hProcess):
_SymGetSearchPath = ctypes.windll.dbghelp.SymGetSearchPath
_SymGetSearchPath.argtypes = [HANDLE, LPSTR, DWORD]
_SymGetSearchPath.restype = DWORD
n = _SymGetSearchPath(hProcess, None, 0x00)
if n == 0x00:
return None
buf = ctypes.create_string_buffer("\x00" * n)
_SymGetSearchPath(hProcess, buf, n)
return buf.value
#
# BOOL WINAPI SymSetSearchPath(
# _In_ HANDLE hProcess,
# _In_opt_ PCTSTR SearchPath
# );
#
def SymSetSearchPath(hProcess, path):
_SymSetSearchPath = ctypes.windll.dbghelp.SymSetSearchPath
_SymSetSearchPath.argtypes = [HANDLE, LPSTR]
_SymSetSearchPath.restype = BOOL
_SymSetSearchPath.restype = RaiseIfZero
return _SymSetSearchPath(hProcess, path)
#
# BOOL WINAPI SymUnloadModule64(
# _In_ HANDLE hProcess,
# _In_ DWORD64 BaseOfDll
# );
#
def SymUnloadModule64(hProcess, baseofdll):
_SymUnloadModule64 = ctypes.windll.dbghelp.SymUnloadModule64
_SymUnloadModule64.argtypes = [HANDLE, DWORD64]
_SymUnloadModule64.restype = BOOL
_SymUnloadModule64.restype = RaiseIfZero
return _SymUnloadModule64(hProcess, baseofdll)
class _SymbolEnumerator (object):
def __init__(self):
pass
def __call__(self, SymbolName, SymbolAddress, SymbolSize, UserContext):
print repr(SymbolName)
return 0x01
class CDbgHelp(object):
def __init__(self, pe_file, path=""):
LoadLibrary("dbghelp.dll")
self.hproc = ctypes.windll.kernel32.GetModuleHandleA(None)
if len(path) > 0:
SetEnvironmentVariable("PATH", path + ";" + GetEnvironmentVariable("PATH"))
self.dir_name = os.path.dirname(os.path.realpath(pe_file))
self.pe_name = os.path.basename(pe_file)
if len(self.dir_name) > 0:
SetEnvironmentVariable("PATH", self.dir_name + ";" + GetEnvironmentVariable("PATH"))
if self.pe_name.endswith('.exe'):
self.hMod = LoadLibrary(self.pe_name)
self.sizedll = 0x00
self.base = 0x00
else:
self.hMod = 0x00
self.base = 0x10000000
self.sizedll = os.path.getsize(pe_file)
SymInitializeA(ctypes.windll.kernel32.GetModuleHandleA(None))
SymOptions = SymGetOptions()
# TODO : Moare options ?!
SymOptions |= SYMOPT_ALLOW_ABSOLUTE_SYMBOLS
SymOptions &= ~(SYMOPT_IGNORE_NT_SYMPATH | SYMOPT_NO_CPP)
SymSetOptions(SymOptions)
SymSetSearchPath(self.hproc, self.dir_name)
self.base = SymLoadModule64(ctypes.windll.kernel32.GetModuleHandleA(None), None, self.pe_name, None, self.base, self.sizedll)
def list_sym(self):
print self.base
SymEnumerateSymbols64A(ctypes.windll.kernel32.GetModuleHandleA(None), self.base, _SymbolEnumerator())
def get_sym_info(self, name):
x = SymFromName(ctypes.windll.kernel32.GetModuleHandleA(None), name)
return x
def unload(self):
if self.hMod != 0x00:
FreeLibrary(self.hMod)
self.hMod = 0x00
if self.base != 0x00:
SymUnloadModule64(ctypes.windll.kernel32.GetModuleHandleA(None), self.base)
self.base = 0x00
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='get symbol info')
parser.add_argument('-i', dest='pe_file', help="input PE file", required=True, metavar='pe_file')
parser.add_argument('-p', dest='path', help="input path", required=False, metavar='path', default="")
parser.add_argument('-s', dest='symbol', help="symbol name", required=True, metavar='symbol', default="")
args = parser.parse_args()
cdbg = CDbgHelp(args.pe_file, args.path)
cdbg.list_sym()
x = cdbg.get_sym_info(args.symbol)
print x
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment