Last active
April 5, 2018 14:40
-
-
Save w4kfu/f4fc1fd7ba33d69026f028cb4795e0a6 to your computer and use it in GitHub Desktop.
fuck DIA
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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