diff --git a/ctypes_generation/definitions/functions/symbols.txt b/ctypes_generation/definitions/functions/symbols.txt index d982ec2..826ff88 100644 --- a/ctypes_generation/definitions/functions/symbols.txt +++ b/ctypes_generation/definitions/functions/symbols.txt @@ -124,6 +124,14 @@ BOOL WINAPI SymEnumTypesByName( _In_ PVOID UserContext ); +BOOL WINAPI SymEnumTypesByNameW( + [in] HANDLE hProcess, + [in] ULONG64 BaseOfDll, + [in, optional] PCWSTR mask, + [in] PVOID EnumSymbolsCallback, + [in] PVOID UserContext +); + BOOL WINAPI SymEnumerateModules64( _In_ HANDLE hProcess, _In_ PVOID EnumModulesCallback, @@ -285,6 +293,13 @@ BOOL WINAPI SymGetTypeFromName( _Inout_ PSYMBOL_INFO Symbol ); +BOOL WINAPI SymGetTypeFromNameW( + [in] HANDLE hProcess, + [in] ULONG64 BaseOfDll, + [in] PCWSTR Name, + [in, out] PSYMBOL_INFOW Symbol +); + BOOL WINAPI SymGetTypeInfo( _In_ HANDLE hProcess, diff --git a/windows/debug/symbols.py b/windows/debug/symbols.py index c34b664..94e0200 100644 --- a/windows/debug/symbols.py +++ b/windows/debug/symbols.py @@ -50,8 +50,7 @@ class SymbolInfoBase(object): def __init__(self, *args, **kwargs): self.resolver = kwargs.get("resolver", None) - #: POUET POUET - self.displacement = kwargs.get("displacement", 0) #: POUET POUET + self.displacement = kwargs.get("displacement", 0) def as_type(self): @@ -162,7 +161,15 @@ class SymbolType(object): res = ires if res is None: res = TST_TYPE_RES_TYPE.get(typeinfo, gdef.DWORD)() - windows.winproxy.SymGetTypeInfo(self.resolver.handle, self.modbase, self._typeid, typeinfo, ctypes.byref(res)) + try: + windows.winproxy.SymGetTypeInfo(self.resolver.handle, self.modbase, self._typeid, typeinfo, ctypes.byref(res)) + except WindowsError as e: + if e.winerror == gdef.ERROR_INVALID_FUNCTION: + # invalid function on object -> None + # We may lose some information with that between no return value VS error + # Explicit verification on attributes per tags ? + return None + raise if ires is not None: return ires newres = res.value @@ -211,6 +218,11 @@ class SymbolType(object): def offset(self): return self._get_type_info(gdef.TI_GET_OFFSET) + @property + def count(self): + # Only valid on tag == SymTagArrayType + return self._get_type_info(gdef.TI_GET_COUNT) + @property def nb_children(self): return self._get_type_info(gdef.TI_GET_CHILDRENCOUNT) @@ -219,6 +231,10 @@ class SymbolType(object): def value(self): return self._get_type_info(gdef.TI_GET_VALUE) + @property + def address(self): + return self._get_type_info(gdef.TI_GET_ADDRESS) + @property def children(self): count = self.nb_children @@ -237,15 +253,25 @@ class SymbolType(object): # Constructor def new_typeid(self, newtypeid): + if newtypeid is None: + return None return type(self)(newtypeid, self.modbase, self.resolver) def __repr__(self): if self.tag == gdef.SymTagBaseType: return '<{0} {1!r}>'.format(type(self).__name__, self.basetype) + elif self.tag == gdef.SymTagArrayType: + target_type = self.type.name + array_size = self.count + return '<{0} {1}[{2}] tag={3!r}>'.format(type(self).__name__, target_type, array_size, self.tag) elif self.tag == gdef.SymTagPointerType: target_type = self.type.name - return '<{0} PTR TO "{1}" tag={2}>'.format(type(self).__name__, target_type, self.tag) - return '<{0} name="{1}" tag={2}>'.format(type(self).__name__, self.name, self.tag) + if self.type.tag == gdef.SymTagBaseType: + target_type = repr(self.type.basetype) + else: + target_type = self.type.name + return '<{0} PTR TO "{1}" tag={2!r}>'.format(type(self).__name__, target_type, self.tag) + return '<{0} name="{1}" tag={2!r}>'.format(type(self).__name__, self.name, self.tag) class SymbolModule(gdef.IMAGEHLP_MODULEW64): @@ -526,7 +552,7 @@ class SymbolHandler(object): buff = windows.utils.BUFFER(SymbolInfo)(size=full_size) buff[0].SizeOfStruct = ctypes.sizeof(SymbolInfo) buff[0].MaxNameLen = max_len_size - windows.winproxy.SymGetTypeFromName(self.handle, mod, name, buff) + windows.winproxy.SymGetTypeFromNameW(self.handle, mod, name, buff) return SymbolType.from_symbol_info(buff[0], resolver=self) diff --git a/windows/generated_def/winfuncs.py b/windows/generated_def/winfuncs.py index c3f2eb6..49dcac3 100644 --- a/windows/generated_def/winfuncs.py +++ b/windows/generated_def/winfuncs.py @@ -2510,6 +2510,11 @@ SymEnumTypesParams = ((1, 'hProcess'), (1, 'BaseOfDll'), (1, 'EnumSymbolsCallbac SymEnumTypesByNamePrototype = WINFUNCTYPE(BOOL, HANDLE, ULONG64, PCSTR, PVOID, PVOID) SymEnumTypesByNameParams = ((1, 'hProcess'), (1, 'BaseOfDll'), (1, 'mask'), (1, 'EnumSymbolsCallback'), (1, 'UserContext')) +#def SymEnumTypesByNameW(hProcess, BaseOfDll, mask, EnumSymbolsCallback, UserContext): +# return SymEnumTypesByNameW.ctypes_function(hProcess, BaseOfDll, mask, EnumSymbolsCallback, UserContext) +SymEnumTypesByNameWPrototype = WINFUNCTYPE(BOOL, HANDLE, ULONG64, PCWSTR, PVOID, PVOID) +SymEnumTypesByNameWParams = ((1, 'hProcess'), (1, 'BaseOfDll'), (1, 'mask'), (1, 'EnumSymbolsCallback'), (1, 'UserContext')) + #def SymEnumerateModules64(hProcess, EnumModulesCallback, UserContext): # return SymEnumerateModules64.ctypes_function(hProcess, EnumModulesCallback, UserContext) SymEnumerateModules64Prototype = WINFUNCTYPE(BOOL, HANDLE, PVOID, PVOID) @@ -2635,6 +2640,11 @@ SymEnumSymbolsForAddrWParams = ((1, 'hProcess'), (1, 'Address'), (1, 'EnumSymbol SymGetTypeFromNamePrototype = WINFUNCTYPE(BOOL, HANDLE, ULONG64, PCSTR, PSYMBOL_INFO) SymGetTypeFromNameParams = ((1, 'hProcess'), (1, 'BaseOfDll'), (1, 'Name'), (1, 'Symbol')) +#def SymGetTypeFromNameW(hProcess, BaseOfDll, Name, Symbol): +# return SymGetTypeFromNameW.ctypes_function(hProcess, BaseOfDll, Name, Symbol) +SymGetTypeFromNameWPrototype = WINFUNCTYPE(BOOL, HANDLE, ULONG64, PCWSTR, PSYMBOL_INFOW) +SymGetTypeFromNameWParams = ((1, 'hProcess'), (1, 'BaseOfDll'), (1, 'Name'), (1, 'Symbol')) + #def SymGetTypeInfo(hProcess, ModBase, TypeId, GetType, pInfo): # return SymGetTypeInfo.ctypes_function(hProcess, ModBase, TypeId, GetType, pInfo) SymGetTypeInfoPrototype = WINFUNCTYPE(BOOL, HANDLE, DWORD64, ULONG, IMAGEHLP_SYMBOL_TYPE_INFO, PVOID) diff --git a/windows/winproxy/apis/dbghelp.py b/windows/winproxy/apis/dbghelp.py index 1ad6a71..09fa558 100644 --- a/windows/winproxy/apis/dbghelp.py +++ b/windows/winproxy/apis/dbghelp.py @@ -104,6 +104,10 @@ def SymSetSearchPathW(hProcess, SearchPath): def SymGetTypeInfo(hProcess, ModBase, TypeId, GetType, pInfo): return SymGetTypeInfo.ctypes_function(hProcess, ModBase, TypeId, GetType, pInfo) +@DbgHelpProxy() +def SymGetTypeFromNameW(hProcess, BaseOfDll, Name, Symbol): + return SymGetTypeFromNameW.ctypes_function(hProcess, BaseOfDll, Name, Symbol) + @DbgHelpProxy() def SymEnumSymbols(hProcess, BaseOfDll, Mask, EnumSymbolsCallback, UserContext=None): UserContext = transform_pyobject_to_pvoid(UserContext)