From 989ddc0cd19bf51ba2589e492f6029bf70665c55 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Tue, 22 Feb 2022 17:49:11 +0200 Subject: [PATCH 01/16] Start working on __main__.py --- pydia2/__main__.py | 90 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 pydia2/__main__.py diff --git a/pydia2/__main__.py b/pydia2/__main__.py new file mode 100644 index 0000000..587bf75 --- /dev/null +++ b/pydia2/__main__.py @@ -0,0 +1,90 @@ +""" +Dump debug information for executable or from a pdb. + +This is a reproduction of the DIA2Dump sample included with the DIA SDK. +""" +import sys +import os +import argparse +import comtypes +import pydia2 + +__package__ = "pydia2" + + +def load_data_from_pdb(file): + source = pydia2.CreateObject(pydia2.dia.DiaSource, pydia2.dia.IDiaDataSource) + + if os.path.splitext(file)[1] == ".pdb": + source.loadDataFromPdb(file) + else: + # TODO Add callback? + source.loadDataForExe(file, None, None) + + session = source.openSession() + + return (source, session) + + +def dump_all_pdb_info(session): + dump_all_mods(session) + dump_all_publics(session) + + +def dump_all_mods(session): + print("\n\n*** MODULES\n") + + enum_symbols = session.globalScope.findChildren(pydia2.dia.SymTagCompiland, None, 0) + + for i, symbol in enumerate(enum_symbols, 1): + symbol = symbol.QueryInterface(pydia2.dia.IDiaSymbol) + print(f"{i:04X} {symbol.name}") + + print() + + +def print_public_symbol(symbol): + try: + rva = symbol.relativeVirtualAddress + except comtypes.COMError: + rva = 0xFFFFFFFF + + print(f"{symbol.symTag}: [{rva:08X}][{symbol.addressSection:04X}:{symbol.addressOffset:08X}]") + + +def dump_all_publics(session): + print("\n\n*** PUBLICS\n") + + enum_symbols = session.globalScope.findChildren(pydia2.dia.SymTagPublicSymbol, None, 0) + + for symbol in enum_symbols: + symbol = symbol.QueryInterface(pydia2.dia.IDiaSymbol) + print_public_symbol(symbol) + + print() + + +def main(): + parser = argparse.ArgumentParser(prog="pydia2", description=__doc__) + parser.add_argument("file") + parser.add_argument("-a", "--all", action="store_true", help="print all the debug info") + parser.add_argument("-m", "--mods", action="store_true", help="print all the mods") + parser.add_argument("-p", "--publics", action="store_true", help="print all the publics") + + args = parser.parse_args() + + source, session = load_data_from_pdb(args.file) + + if args.all: + dump_all_pdb_info(session) + return + + if args.mods: + dump_all_mods(session) + + if args.publics: + dump_all_publics(session) + + +if __name__ == "__main__": + sys.exit(main()) From 03b7e27b9e8b34fb8633e033a1c24b1dddf2efad Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Tue, 22 Feb 2022 18:05:08 +0200 Subject: [PATCH 02/16] Add SymTag enum --- pydia2/__init__.py | 49 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/pydia2/__init__.py b/pydia2/__init__.py index a0bb462..a757d02 100644 --- a/pydia2/__init__.py +++ b/pydia2/__init__.py @@ -5,6 +5,7 @@ import sys import pathlib import ctypes +import enum import comtypes from comtypes import client from . import _dia, cvconst @@ -54,3 +55,51 @@ def CreateObject(progid, interface=None): iid = interface._iid_ _NoRegCoCreate(str(_DIA_DLL), ctypes.byref(clsid), ctypes.byref(iid), ctypes.byref(p)) return client.GetBestInterface(p) + + +class SymTag(enum.IntEnum): + Null = dia.SymTagNull + Exe = dia.SymTagExe + Compiland = dia.SymTagCompiland + CompilandDetails = dia.SymTagCompilandDetails + CompilandEnv = dia.SymTagCompilandEnv + Function = dia.SymTagFunction + Block = dia.SymTagBlock + Data = dia.SymTagData + Annotation = dia.SymTagAnnotation + Label = dia.SymTagLabel + PublicSymbol = dia.SymTagPublicSymbol + UDT = dia.SymTagUDT + # Enum = dia.SymTagEnum + Enum = 12 + FunctionType = dia.SymTagFunctionType + PointerType = dia.SymTagPointerType + ArrayType = dia.SymTagArrayType + BaseType = dia.SymTagBaseType + Typedef = dia.SymTagTypedef + BaseClass = dia.SymTagBaseClass + Friend = dia.SymTagFriend + FunctionArgType = dia.SymTagFunctionArgType + FuncDebugStart = dia.SymTagFuncDebugStart + FuncDebugEnd = dia.SymTagFuncDebugEnd + UsingNamespace = dia.SymTagUsingNamespace + VTableShape = dia.SymTagVTableShape + VTable = dia.SymTagVTable + Custom = dia.SymTagCustom + Thunk = dia.SymTagThunk + CustomType = dia.SymTagCustomType + ManagedType = dia.SymTagManagedType + Dimension = dia.SymTagDimension + CallSite = dia.SymTagCallSite + InlineSite = dia.SymTagInlineSite + BaseInterface = dia.SymTagBaseInterface + VectorType = dia.SymTagVectorType + MatrixType = dia.SymTagMatrixType + HLSLType = dia.SymTagHLSLType + Caller = dia.SymTagCaller + Callee = dia.SymTagCallee + Export = dia.SymTagExport + HeapAllocationSite = dia.SymTagHeapAllocationSite + CoffGroup = dia.SymTagCoffGroup + Inlinee = dia.SymTagInlinee + Max = dia.SymTagMax From 08fdc992f5a599d46f68cc159af3184bcf187686 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Tue, 22 Feb 2022 18:05:16 +0200 Subject: [PATCH 03/16] Finish dump_all_publics --- pydia2/__main__.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/pydia2/__main__.py b/pydia2/__main__.py index 587bf75..160195c 100644 --- a/pydia2/__main__.py +++ b/pydia2/__main__.py @@ -49,7 +49,23 @@ def print_public_symbol(symbol): except comtypes.COMError: rva = 0xFFFFFFFF - print(f"{symbol.symTag}: [{rva:08X}][{symbol.addressSection:04X}:{symbol.addressOffset:08X}]") + print(f"{pydia2.SymTag(symbol.symTag).name}: [{rva:08X}][{symbol.addressSection:04X}:{symbol.addressOffset:08X}] ", end='') + + if symbol.symTag == pydia2.dia.SymTagThunk: + try: + print("f{symbol.name}") + except comtypes.COMError: + try: + target_rva = symbol.targetRelativeVirtualAdddress + except comtypes.COMError: + target_rva = 0xFFFFFFFF + + print(f"target -> [{target_rva:08X}][{symbol.targetSection:04X}:{symbol.targetOffset:08X}]") + else: + try: + print(f"{symbol.name}({symbol.undecoratedName})") + except comtypes.COMError: + print(f"{symbol.name}") def dump_all_publics(session): From af63519f95a401696748e855fb1e298e4d5e8667 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Tue, 22 Feb 2022 18:15:27 +0200 Subject: [PATCH 04/16] Add dump_all_symbols stub --- pydia2/__main__.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pydia2/__main__.py b/pydia2/__main__.py index 160195c..4af0dfb 100644 --- a/pydia2/__main__.py +++ b/pydia2/__main__.py @@ -29,6 +29,7 @@ def load_data_from_pdb(file): def dump_all_pdb_info(session): dump_all_mods(session) dump_all_publics(session) + dump_all_symbols(session) def dump_all_mods(session): @@ -80,12 +81,17 @@ def dump_all_publics(session): print() +def dump_all_symbols(session): + pass + + def main(): parser = argparse.ArgumentParser(prog="pydia2", description=__doc__) parser.add_argument("file") parser.add_argument("-a", "--all", action="store_true", help="print all the debug info") parser.add_argument("-m", "--mods", action="store_true", help="print all the mods") parser.add_argument("-p", "--publics", action="store_true", help="print all the publics") + parser.add_argument("-s", "--symbols", action="store_true", help="print symbols") args = parser.parse_args() @@ -101,6 +107,9 @@ def main(): if args.publics: dump_all_publics(session) + if args.symbols: + dump_all_symbols(session) + if __name__ == "__main__": sys.exit(main()) From 6e57ce7d08fe49ef75c6d87c4e60f06eb2000924 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Wed, 23 Feb 2022 20:46:13 +0200 Subject: [PATCH 05/16] Add stubs for much of the functionality --- pydia2/__main__.py | 380 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 370 insertions(+), 10 deletions(-) diff --git a/pydia2/__main__.py b/pydia2/__main__.py index 4af0dfb..cf5e192 100644 --- a/pydia2/__main__.py +++ b/pydia2/__main__.py @@ -12,6 +12,9 @@ __package__ = "pydia2" +MAX_RVA_LINES_BYTES_RANGE = 0x100 + + def load_data_from_pdb(file): source = pydia2.CreateObject(pydia2.dia.DiaSource, pydia2.dia.IDiaDataSource) @@ -36,7 +39,6 @@ def dump_all_mods(session): print("\n\n*** MODULES\n") enum_symbols = session.globalScope.findChildren(pydia2.dia.SymTagCompiland, None, 0) - for i, symbol in enumerate(enum_symbols, 1): symbol = symbol.QueryInterface(pydia2.dia.IDiaSymbol) print(f"{i:04X} {symbol.name}") @@ -44,6 +46,98 @@ def dump_all_mods(session): print() +def dump_all_publics(session): + print("\n\n*** PUBLICS\n") + + enum_symbols = session.globalScope.findChildren(pydia2.dia.SymTagPublicSymbol, None, 0) + for symbol in enum_symbols: + symbol = symbol.QueryInterface(pydia2.dia.IDiaSymbol) + print_public_symbol(symbol) + + print() + + +def dump_all_symbols(session): + print("\n\n*** SYMBOLS\n") + + enum_symbols = session.globalScope.findChildren(pydia2.dia.SymTagCompiland, None, 0) + for compiland in enum_symbols: + compiland = compiland.QueryInterface(pydia2.dia.IDiaSymbol) + print("\n** Module: ", end='') + + try: + print(f"{compiland.name}\n") + except comtypes.COMError: + print("(???)\n") + + enum_children = compiland.findChildren(pydia2.dia.SymTagNull, None, 0) + for symbol in enum_children: + symbol = symbol.QueryInterface(pydia2.dia.IDiaSymbol) + print_symbol(symbol, 0) + + print() + + +def dump_all_globals(session): + pass # TODO + + +def dump_all_types(session): + pass # TODO + + +def dump_all_udts(session): + pass # TODO + + +def dump_all_enums(session): + pass # TODO + + +def dump_all_typedefs(session): + pass # TODO + + +def dump_all_files(session): + pass # TODO + + +def dump_all_lines(session): + pass # TODO + + +def dump_all_lines_at_rva(session): + pass # TODO + + +def dump_all_sec_contribs(session): + pass # TODO + + +def dump_all_debug_streams(session): + pass # TODO + + +def dump_all_injected_sources(session): + pass # TODO + + +def dump_injected_source(session, name): + pass # TODO + + +def dump_all_sources_files(session): + pass # TODO + + +def dump_all_fpo(session): + pass # TODO + + +def dump_all_oems(session): + pass # TODO + + def print_public_symbol(symbol): try: rva = symbol.relativeVirtualAddress @@ -69,20 +163,188 @@ def print_public_symbol(symbol): print(f"{symbol.name}") -def dump_all_publics(session): - print("\n\n*** PUBLICS\n") +def print_global_symbol(symbol): + pass # TODO - enum_symbols = session.globalScope.findChildren(pydia2.dia.SymTagPublicSymbol, None, 0) - for symbol in enum_symbols: - symbol = symbol.QueryInterface(pydia2.dia.IDiaSymbol) - print_public_symbol(symbol) +def print_call_site_info(symbol): + pass # TODO - print() +def print_heap_alloc_site(symbol): + pass # TODO -def dump_all_symbols(session): - pass + +def print_coff_group(symbol): + pass # TODO + + +def print_symbol(symbol, indent): + try: + sym_tag = symbol.symTag + except comtypes.COMError: + print("ERROR - PrintSymbol get_symTag() failed") + + if sym_tag == pydia2.dia.SymTagFunction: + print() + + print_sym_tag(sym_tag) + + print(' ' * indent, end='') + + if sym_tag == pydia2.dia.SymTagCompilandDetails: + print_compiland_details(symbol) + + elif sym_tag == pydia2.dia.SymTagCompilandEnv: + print_compiland_env(symbol) + + elif sym_tag == pydia2.dia.SymTagData: + print_data(symbol) + + elif sym_tag in (pydia2.dia.SymTagFunction, pydia2.dia.SymTagBlock): + print_location(symbol) + + # TODO + elif sym_tag == pydia2.dia.SymTagAnnotation: + print_location(symbol) + print() + + elif sym_tag == pydia2.dia.SymTagLabel: + print_location(symbol) + print(", ", end='') + print_name(symbol) + + elif sym_tag in (pydia2.dia.SymTagEnum, pydia2.dia.SymTagTypedef, pydia2.dia.SymTagUDT, pydia2.dia.SymTagBaseClass): + print_udt(symbol) + + elif sym_tag in (pydia2.dia.SymTagFuncDebugStart, pydia2.dia.SymTagFuncDebugEnd): + print_location(symbol) + + elif sym_tag in (pydia2.dia.SymTagFunctionArgType, pydia2.dia.SymTagFunctionType, pydia2.dia.SymTagPointerType, pydia2.dia.SymTagArrayType, pydia2.dia.SymTagBaseType): + try: + print_type(symbol.type) + except comtypes.COMError: + pass + + print() + + elif sym_tag == pydia2.dia.SymTagThunk: + print_thunk(symbol) + + elif sym_tag == pydia2.dia.SymTagCallSite: + print_call_site_info(symbol) + + elif sym_tag == pydia2.dia.SymTagHeapAllocationSite: + print_heap_alloc_site(symbol) + + elif sym_tag == pydia2.dia.SymTagCoffGroup: + print_coff_group(symbol) + + else: + print_name(symbol) + + try: + type_ = symbol.type + print(" has type ") + print_type(type_) + except comtypes.COMError: + pass + + +def print_sym_tag(sym_tag): + print(f"{pydia2.SymTag(sym_tag).name:15s}: ", end='') + + +def print_name(symbol): + pass # TODO + + +def print_und_name(symbol): + pass # TODO + + +def print_thunk(symbol): + pass # TODO + + +def print_compiland_details(symbol): + pass # TODO + + +def print_compiland_env(symbol): + pass # TODO + + +def print_location(symbol): + pass # TODO + + +def print_const(symbol): + pass # TODO + + +def print_udt(symbol): + pass # TODO + + +def print_symbol_type(symbol): + pass # TODO + + +def print_type(symbol): + pass # TODO + + +def print_bound(symbol): + pass # TODO + + +def print_data(symbol): + pass # TODO + + +def print_variant(var): + pass # TODO + + +def print_udt_kind(symbol): + pass # TODO + + +def print_type_in_detail(symbol, indent): + pass # TODO + + +def print_function_type(symbol): + pass # TODO + + +def print_source_file(source): + pass # TODO + + +def print_lines(session, function): + pass # TODO + + +def print_enum_lines(lines): + pass # TODO + + +def print_sec_contribs(segment): + pass # TODO + + +def print_stream_data(stream): + pass # TODO + + +def print_frame_data(frame_data): + pass # TODO + + +def print_property_storage(prop_store): + pass # TODO def main(): @@ -91,9 +353,32 @@ def main(): parser.add_argument("-a", "--all", action="store_true", help="print all the debug info") parser.add_argument("-m", "--mods", action="store_true", help="print all the mods") parser.add_argument("-p", "--publics", action="store_true", help="print all the publics") + parser.add_argument("-g", "--globals", action="store_true", help="print all the globals") + parser.add_argument("-t", "--types", action="store_true", help="print all the types") + parser.add_argument("-f", "--files", action="store_true", help="print all the files") parser.add_argument("-s", "--symbols", action="store_true", help="print symbols") + parser.add_argument("-l", nargs='?', metavar="RVA[:BYTES]", const=True, help="print line number info at RVA address in the bytes range") + parser.add_argument("-c", "--sec-contribs", action="store_true", help="print section contribution info") + parser.add_argument("--dbg", action="store_true", help="dump debug streams") + parser.add_argument("--injsrc", nargs='?', metavar="FILE", const=True, help="dump injected source") + parser.add_argument("--source-files", "--sf", action="store_true", help="dump all source files") + parser.add_argument("--oem", action="store_true", help="dump all OEM specific types") + parser.add_argument("--fpo", nargs='?', metavar="RVA/SYMBOL", const=True, help="dump frame pointer omission information for a func addr/symbol") + parser.add_argument("--compiland", nargs='?', metavar="NAME", help="dump symbols for this compiland") + parser.add_argument("--lines", metavar="RVA/FUNC", help="dump line numbers for this address/function") + parser.add_argument("--type", metavar="SYMBOL", help="dump this type in detail") + parser.add_argument("--label", metavar="RVA", help="dump label at RVA") + parser.add_argument("--sym", metavar="SYMBOL/RVA[:CHILDNAME]", help="dump child information of this symbol/at this addr") + parser.add_argument("--lsrc", metavar="FILE[:LINE]", help="dump line numbers for this source file") + parser.add_argument("--ps", metavar="RVA", help="dump symbols after this address") + parser.add_argument("--psr", metavar="RVA", help="dump symbols before this address") + parser.add_argument("-n", type=int, default=16, help="number of symbols to dump for --ps/--psr") + parser.add_argument("--annotations", metavar="RVA", help="dump annotation symbol for this RVA") + parser.add_argument("--maptosrc", metavar="RVA", help="dump src RVA for this image RVA") + parser.add_argument("--mapfromsrc", metavar="RVA", help="dump image RVA for src RVA") args = parser.parse_args() + print(args) source, session = load_data_from_pdb(args.file) @@ -110,6 +395,81 @@ def main(): if args.symbols: dump_all_symbols(session) + if args.globals: + dump_all_globals(session) + + if args.types: + dump_all_types(session) + + if args.files: + dump_all_files(session) + + if args.l: + if isinstance(args.l, str) and args.l != '-': + rva, range = args.l.partition(":") + rva = int(rva, 16) + range = int(range) if range else MAX_RVA_LINES_BYTES_RANGE + + dump_all_lines_at_rva(session, rva) + + else: + dump_all_lines(session) + + if args.sec_contribs: + dump_all_sec_contribs(session) + + if args.dbg: + dump_all_debug_streams(session) + + if args.injsrc: + if isinstance(args.injsrc, str) and args.injsrc != '-': + dump_injected_source(session, args.injsrc) + else: + dump_all_injected_sources(session) + + if args.source_files: + dump_all_sources_files(session) + + if args.oem: + dump_all_oems(session) + + if args.fpo: + pass # TODO + + if args.compiland: + pass # TODO + + if args.lines: + pass # TODO + + if args.type: + pass # TODO + + if args.label: + pass # TODO + + if args.sym: + pass # TODO + + if args.lsrc: + pass # TODO + + if args.ps: + pass # TODO + + if args.psr: + pass # TODO + + if args.annotations: + pass # TODO + + if args.maptosrc: + pass # TODO + + if args.mapfromsrc: + pass # TODO + + if __name__ == "__main__": sys.exit(main()) From 3b5f2691652bbe1fdf8ea058ffa43bfbe2451e2c Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Wed, 23 Feb 2022 21:06:29 +0200 Subject: [PATCH 06/16] Work on print_symbol --- pydia2/__main__.py | 153 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 152 insertions(+), 1 deletion(-) diff --git a/pydia2/__main__.py b/pydia2/__main__.py index cf5e192..152d2b5 100644 --- a/pydia2/__main__.py +++ b/pydia2/__main__.py @@ -33,6 +33,15 @@ def dump_all_pdb_info(session): dump_all_mods(session) dump_all_publics(session) dump_all_symbols(session) + dump_all_globals(session) + dump_all_types(session) + dump_all_files(session) + dump_all_lines(session) + dump_all_sec_contribs(session) + dump_all_debug_streams(session) + dump_all_injected_sources(session) + dump_all_fpo(session) + dump_all_oems(session) def dump_all_mods(session): @@ -204,7 +213,139 @@ def print_symbol(symbol, indent): elif sym_tag in (pydia2.dia.SymTagFunction, pydia2.dia.SymTagBlock): print_location(symbol) - # TODO + try: + print(f", len = {symbol.length:08X}", end='') + except comtypes.COMError: + pass + + if sym_tag == pydia2.dia.SymTagFunction: + try: + # TODO enum + print(f", {symbol.callingConvention}", end='') + except comtypes.COMError: + pass + + print_und_name(symbol) + print() + + if sym_tag == pydia2.dia.SymTagFunction: + print(' ' * indent, end='') + print(" Function attribute:", end='') + + try: + if symbol.isCxxReturnUdt: + print(" return user defined type (C++ style)", end='') + except comtypes.COMError: + pass + + try: + if symbol.constructor: + print(" instance constructor", end='') + except comtypes.COMError: + pass + + try: + if symbol.isConstructorVirtualBase: + print(" instance constructor of a class with virtual base", end='') + except comtypes.COMError: + pass + + print() + + print(' ' * indent, end='') + print(" Function info:", end='') + + try: + if symbol.hasAlloca: + print(" alloca", end='') + except comtypes.COMError: + pass + + try: + if symbol.hasSetJump: + print(" setjmp", end='') + except comtypes.COMError: + pass + + try: + if symbol.hasLongJump: + print(" longjmp", end='') + except comtypes.COMError: + pass + + try: + if symbol.hasInlAsm: + print(" inlasm", end='') + except comtypes.COMError: + pass + + try: + if symbol.hasEH: + print(" eh", end='') + except comtypes.COMError: + pass + + try: + if symbol.inlSpec: + print(" inl_specified", end='') + except comtypes.COMError: + pass + + try: + if symbol.hasSEH: + print(" seh", end='') + except comtypes.COMError: + pass + + try: + if symbol.isNaked: + print(" naked", end='') + except comtypes.COMError: + pass + + try: + if symbol.hasSecurityChecks: + print(" gschecks", end='') + except comtypes.COMError: + pass + + try: + if symbol.isSafeBuffers: + print(" safebuffers", end='') + except comtypes.COMError: + pass + + try: + if symbol.hasEHa: + print(" asyncheh", end='') + except comtypes.COMError: + pass + + try: + if symbol.noStackOrdering: + print(" gsnostackordering", end='') + except comtypes.COMError: + pass + + try: + if symbol.wasInlined: + print(" wasinlined", end='') + except comtypes.COMError: + pass + + try: + if symbol.strictGSCheck: + print(" strict_gs_check", end='') + except comtypes.COMError: + pass + + print() + + enum_children = symbol.findChildren(pydia2.dia.SymTagNull, None, 0) + for child in enum_children: + child = child.QueryInterface(pydia2.dia.IDiaSymbol) + print_symbol(child, indent + 2) + elif sym_tag == pydia2.dia.SymTagAnnotation: print_location(symbol) print() @@ -250,6 +391,16 @@ def print_symbol(symbol, indent): except comtypes.COMError: pass + if sym_tag in (pydia2.dia.SymTagUDT, pydia2.dia.SymTagAnnotation): + print() + + enum_children = symbol.findChildren(pydia2.dia.SymTagNull, None, 0) + for child in enum_children: + child = child.QueryInterface(pydia2.dia.IDiaSymbol) + print_symbol(child, indent + 2) + + print() + def print_sym_tag(sym_tag): print(f"{pydia2.SymTag(sym_tag).name:15s}: ", end='') From fe71beb60a14758f9ea7b1aa7d69bac6dc96287c Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Thu, 24 Feb 2022 15:22:10 +0200 Subject: [PATCH 07/16] Missing end --- pydia2/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydia2/__main__.py b/pydia2/__main__.py index 152d2b5..f6b9f0b 100644 --- a/pydia2/__main__.py +++ b/pydia2/__main__.py @@ -386,7 +386,7 @@ def print_symbol(symbol, indent): try: type_ = symbol.type - print(" has type ") + print(" has type ", end='') print_type(type_) except comtypes.COMError: pass From 0747844ad73b563ab65ecafea3404b748be59c15 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Fri, 25 Feb 2022 20:53:53 +0200 Subject: [PATCH 08/16] Work a bit on __main__.py --- pydia2/__init__.py | 48 --------------------------------- pydia2/__main__.py | 66 ++++++++++++++++++++++++++-------------------- 2 files changed, 38 insertions(+), 76 deletions(-) diff --git a/pydia2/__init__.py b/pydia2/__init__.py index a757d02..eb70e42 100644 --- a/pydia2/__init__.py +++ b/pydia2/__init__.py @@ -55,51 +55,3 @@ def CreateObject(progid, interface=None): iid = interface._iid_ _NoRegCoCreate(str(_DIA_DLL), ctypes.byref(clsid), ctypes.byref(iid), ctypes.byref(p)) return client.GetBestInterface(p) - - -class SymTag(enum.IntEnum): - Null = dia.SymTagNull - Exe = dia.SymTagExe - Compiland = dia.SymTagCompiland - CompilandDetails = dia.SymTagCompilandDetails - CompilandEnv = dia.SymTagCompilandEnv - Function = dia.SymTagFunction - Block = dia.SymTagBlock - Data = dia.SymTagData - Annotation = dia.SymTagAnnotation - Label = dia.SymTagLabel - PublicSymbol = dia.SymTagPublicSymbol - UDT = dia.SymTagUDT - # Enum = dia.SymTagEnum - Enum = 12 - FunctionType = dia.SymTagFunctionType - PointerType = dia.SymTagPointerType - ArrayType = dia.SymTagArrayType - BaseType = dia.SymTagBaseType - Typedef = dia.SymTagTypedef - BaseClass = dia.SymTagBaseClass - Friend = dia.SymTagFriend - FunctionArgType = dia.SymTagFunctionArgType - FuncDebugStart = dia.SymTagFuncDebugStart - FuncDebugEnd = dia.SymTagFuncDebugEnd - UsingNamespace = dia.SymTagUsingNamespace - VTableShape = dia.SymTagVTableShape - VTable = dia.SymTagVTable - Custom = dia.SymTagCustom - Thunk = dia.SymTagThunk - CustomType = dia.SymTagCustomType - ManagedType = dia.SymTagManagedType - Dimension = dia.SymTagDimension - CallSite = dia.SymTagCallSite - InlineSite = dia.SymTagInlineSite - BaseInterface = dia.SymTagBaseInterface - VectorType = dia.SymTagVectorType - MatrixType = dia.SymTagMatrixType - HLSLType = dia.SymTagHLSLType - Caller = dia.SymTagCaller - Callee = dia.SymTagCallee - Export = dia.SymTagExport - HeapAllocationSite = dia.SymTagHeapAllocationSite - CoffGroup = dia.SymTagCoffGroup - Inlinee = dia.SymTagInlinee - Max = dia.SymTagMax diff --git a/pydia2/__main__.py b/pydia2/__main__.py index f6b9f0b..c4e6488 100644 --- a/pydia2/__main__.py +++ b/pydia2/__main__.py @@ -47,7 +47,7 @@ def dump_all_pdb_info(session): def dump_all_mods(session): print("\n\n*** MODULES\n") - enum_symbols = session.globalScope.findChildren(pydia2.dia.SymTagCompiland, None, 0) + enum_symbols = session.globalScope.findChildren(pydia2.cvconst.SymTag.Compiland, None, 0) for i, symbol in enumerate(enum_symbols, 1): symbol = symbol.QueryInterface(pydia2.dia.IDiaSymbol) print(f"{i:04X} {symbol.name}") @@ -58,7 +58,7 @@ def dump_all_mods(session): def dump_all_publics(session): print("\n\n*** PUBLICS\n") - enum_symbols = session.globalScope.findChildren(pydia2.dia.SymTagPublicSymbol, None, 0) + enum_symbols = session.globalScope.findChildren(pydia2.cvconst.SymTag.PublicSymbol, None, 0) for symbol in enum_symbols: symbol = symbol.QueryInterface(pydia2.dia.IDiaSymbol) print_public_symbol(symbol) @@ -69,7 +69,7 @@ def dump_all_publics(session): def dump_all_symbols(session): print("\n\n*** SYMBOLS\n") - enum_symbols = session.globalScope.findChildren(pydia2.dia.SymTagCompiland, None, 0) + enum_symbols = session.globalScope.findChildren(pydia2.cvconst.SymTag.Compiland, None, 0) for compiland in enum_symbols: compiland = compiland.QueryInterface(pydia2.dia.IDiaSymbol) print("\n** Module: ", end='') @@ -79,7 +79,7 @@ def dump_all_symbols(session): except comtypes.COMError: print("(???)\n") - enum_children = compiland.findChildren(pydia2.dia.SymTagNull, None, 0) + enum_children = compiland.findChildren(pydia2.cvconst.SymTag.Null, None, 0) for symbol in enum_children: symbol = symbol.QueryInterface(pydia2.dia.IDiaSymbol) print_symbol(symbol, 0) @@ -153,9 +153,9 @@ def print_public_symbol(symbol): except comtypes.COMError: rva = 0xFFFFFFFF - print(f"{pydia2.SymTag(symbol.symTag).name}: [{rva:08X}][{symbol.addressSection:04X}:{symbol.addressOffset:08X}] ", end='') + print(f"{pydia2.cvconst.SymTag(symbol.symTag).name}: [{rva:08X}][{symbol.addressSection:04X}:{symbol.addressOffset:08X}] ", end='') - if symbol.symTag == pydia2.dia.SymTagThunk: + if symbol.symTag == pydia2.cvconst.SymTag.Thunk: try: print("f{symbol.name}") except comtypes.COMError: @@ -194,23 +194,23 @@ def print_symbol(symbol, indent): except comtypes.COMError: print("ERROR - PrintSymbol get_symTag() failed") - if sym_tag == pydia2.dia.SymTagFunction: + if sym_tag == pydia2.cvconst.SymTag.Function: print() print_sym_tag(sym_tag) print(' ' * indent, end='') - if sym_tag == pydia2.dia.SymTagCompilandDetails: + if sym_tag == pydia2.cvconst.SymTag.CompilandDetails: print_compiland_details(symbol) - elif sym_tag == pydia2.dia.SymTagCompilandEnv: + elif sym_tag == pydia2.cvconst.SymTag.CompilandEnv: print_compiland_env(symbol) - elif sym_tag == pydia2.dia.SymTagData: + elif sym_tag == pydia2.cvconst.SymTag.Data: print_data(symbol) - elif sym_tag in (pydia2.dia.SymTagFunction, pydia2.dia.SymTagBlock): + elif sym_tag in (pydia2.cvconst.SymTag.Function, pydia2.cvconst.SymTag.Block): print_location(symbol) try: @@ -218,7 +218,7 @@ def print_symbol(symbol, indent): except comtypes.COMError: pass - if sym_tag == pydia2.dia.SymTagFunction: + if sym_tag == pydia2.cvconst.SymTag.Function: try: # TODO enum print(f", {symbol.callingConvention}", end='') @@ -228,7 +228,7 @@ def print_symbol(symbol, indent): print_und_name(symbol) print() - if sym_tag == pydia2.dia.SymTagFunction: + if sym_tag == pydia2.cvconst.SymTag.Function: print(' ' * indent, end='') print(" Function attribute:", end='') @@ -341,27 +341,27 @@ def print_symbol(symbol, indent): print() - enum_children = symbol.findChildren(pydia2.dia.SymTagNull, None, 0) + enum_children = symbol.findChildren(pydia2.cvconst.SymTag.Null, None, 0) for child in enum_children: child = child.QueryInterface(pydia2.dia.IDiaSymbol) print_symbol(child, indent + 2) - elif sym_tag == pydia2.dia.SymTagAnnotation: + elif sym_tag == pydia2.cvconst.SymTag.Annotation: print_location(symbol) print() - elif sym_tag == pydia2.dia.SymTagLabel: + elif sym_tag == pydia2.cvconst.SymTag.Label: print_location(symbol) print(", ", end='') print_name(symbol) - elif sym_tag in (pydia2.dia.SymTagEnum, pydia2.dia.SymTagTypedef, pydia2.dia.SymTagUDT, pydia2.dia.SymTagBaseClass): + elif sym_tag in (pydia2.cvconst.SymTag.Enum, pydia2.cvconst.SymTag.Typedef, pydia2.cvconst.SymTag.UDT, pydia2.cvconst.SymTag.BaseClass): print_udt(symbol) - elif sym_tag in (pydia2.dia.SymTagFuncDebugStart, pydia2.dia.SymTagFuncDebugEnd): + elif sym_tag in (pydia2.cvconst.SymTag.FuncDebugStart, pydia2.cvconst.SymTag.FuncDebugEnd): print_location(symbol) - elif sym_tag in (pydia2.dia.SymTagFunctionArgType, pydia2.dia.SymTagFunctionType, pydia2.dia.SymTagPointerType, pydia2.dia.SymTagArrayType, pydia2.dia.SymTagBaseType): + elif sym_tag in (pydia2.cvconst.SymTag.FunctionArgType, pydia2.cvconst.SymTag.FunctionType, pydia2.cvconst.SymTag.PointerType, pydia2.cvconst.SymTag.ArrayType, pydia2.cvconst.SymTag.BaseType): try: print_type(symbol.type) except comtypes.COMError: @@ -369,16 +369,16 @@ def print_symbol(symbol, indent): print() - elif sym_tag == pydia2.dia.SymTagThunk: + elif sym_tag == pydia2.cvconst.SymTag.Thunk: print_thunk(symbol) - elif sym_tag == pydia2.dia.SymTagCallSite: + elif sym_tag == pydia2.cvconst.SymTag.CallSite: print_call_site_info(symbol) - elif sym_tag == pydia2.dia.SymTagHeapAllocationSite: + elif sym_tag == pydia2.cvconst.SymTag.HeapAllocationSite: print_heap_alloc_site(symbol) - elif sym_tag == pydia2.dia.SymTagCoffGroup: + elif sym_tag == pydia2.cvconst.SymTag.CoffGroup: print_coff_group(symbol) else: @@ -391,10 +391,10 @@ def print_symbol(symbol, indent): except comtypes.COMError: pass - if sym_tag in (pydia2.dia.SymTagUDT, pydia2.dia.SymTagAnnotation): + if sym_tag in (pydia2.cvconst.SymTag.UDT, pydia2.cvconst.SymTag.Annotation): print() - enum_children = symbol.findChildren(pydia2.dia.SymTagNull, None, 0) + enum_children = symbol.findChildren(pydia2.cvconst.SymTag.Null, None, 0) for child in enum_children: child = child.QueryInterface(pydia2.dia.IDiaSymbol) print_symbol(child, indent + 2) @@ -403,7 +403,7 @@ def print_symbol(symbol, indent): def print_sym_tag(sym_tag): - print(f"{pydia2.SymTag(sym_tag).name:15s}: ", end='') + print(f"{pydia2.cvconst.SymTag(sym_tag).name:15s}: ", end='') def print_name(symbol): @@ -427,7 +427,18 @@ def print_compiland_env(symbol): def print_location(symbol): - pass # TODO + try: + location_type = symbol.locationType + except comtypes.COMError: + print("symbol in optimized code", end='') + return + + if location_type == pydia2.cvconst.LocationType.Static: + try: + print(f"{pydia2.cvconst.LocationType(location_type).name}, [{symbol.relativeVirtualAddress:08X}][{symbol.addressSection:04X}:{symbol.addressOffset:08X}]", end='') + except comtypes.COMError: + pass + # TODO def print_const(symbol): @@ -529,7 +540,6 @@ def main(): parser.add_argument("--mapfromsrc", metavar="RVA", help="dump image RVA for src RVA") args = parser.parse_args() - print(args) source, session = load_data_from_pdb(args.file) From 1a4c0f17491e877c9dc27753454a61852e2fe693 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Fri, 25 Feb 2022 20:57:52 +0200 Subject: [PATCH 09/16] Use Call enum --- pydia2/__main__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pydia2/__main__.py b/pydia2/__main__.py index c4e6488..ee5d3ac 100644 --- a/pydia2/__main__.py +++ b/pydia2/__main__.py @@ -220,8 +220,7 @@ def print_symbol(symbol, indent): if sym_tag == pydia2.cvconst.SymTag.Function: try: - # TODO enum - print(f", {symbol.callingConvention}", end='') + print(f", {pydia2.cvconst.Call(symbol.callingConvention).name}", end='') except comtypes.COMError: pass From 755799e3a7d359b3577c706593d2105bfa10b31b Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Sun, 27 Feb 2022 10:46:37 +0200 Subject: [PATCH 10/16] Implement more of __main__ --- pydia2/__main__.py | 263 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 224 insertions(+), 39 deletions(-) diff --git a/pydia2/__main__.py b/pydia2/__main__.py index ee5d3ac..3af9fb7 100644 --- a/pydia2/__main__.py +++ b/pydia2/__main__.py @@ -8,6 +8,7 @@ import argparse import comtypes import pydia2 +from pydia2 import dia, cvconst __package__ = "pydia2" @@ -16,7 +17,7 @@ def load_data_from_pdb(file): - source = pydia2.CreateObject(pydia2.dia.DiaSource, pydia2.dia.IDiaDataSource) + source = pydia2.CreateObject(dia.DiaSource, dia.IDiaDataSource) if os.path.splitext(file)[1] == ".pdb": source.loadDataFromPdb(file) @@ -47,9 +48,9 @@ def dump_all_pdb_info(session): def dump_all_mods(session): print("\n\n*** MODULES\n") - enum_symbols = session.globalScope.findChildren(pydia2.cvconst.SymTag.Compiland, None, 0) + enum_symbols = session.globalScope.findChildren(cvconst.SymTag.Compiland, None, 0) for i, symbol in enumerate(enum_symbols, 1): - symbol = symbol.QueryInterface(pydia2.dia.IDiaSymbol) + symbol = symbol.QueryInterface(dia.IDiaSymbol) print(f"{i:04X} {symbol.name}") print() @@ -58,9 +59,9 @@ def dump_all_mods(session): def dump_all_publics(session): print("\n\n*** PUBLICS\n") - enum_symbols = session.globalScope.findChildren(pydia2.cvconst.SymTag.PublicSymbol, None, 0) + enum_symbols = session.globalScope.findChildren(cvconst.SymTag.PublicSymbol, None, 0) for symbol in enum_symbols: - symbol = symbol.QueryInterface(pydia2.dia.IDiaSymbol) + symbol = symbol.QueryInterface(dia.IDiaSymbol) print_public_symbol(symbol) print() @@ -69,9 +70,9 @@ def dump_all_publics(session): def dump_all_symbols(session): print("\n\n*** SYMBOLS\n") - enum_symbols = session.globalScope.findChildren(pydia2.cvconst.SymTag.Compiland, None, 0) + enum_symbols = session.globalScope.findChildren(cvconst.SymTag.Compiland, None, 0) for compiland in enum_symbols: - compiland = compiland.QueryInterface(pydia2.dia.IDiaSymbol) + compiland = compiland.QueryInterface(dia.IDiaSymbol) print("\n** Module: ", end='') try: @@ -79,9 +80,9 @@ def dump_all_symbols(session): except comtypes.COMError: print("(???)\n") - enum_children = compiland.findChildren(pydia2.cvconst.SymTag.Null, None, 0) + enum_children = compiland.findChildren(cvconst.SymTag.Null, None, 0) for symbol in enum_children: - symbol = symbol.QueryInterface(pydia2.dia.IDiaSymbol) + symbol = symbol.QueryInterface(dia.IDiaSymbol) print_symbol(symbol, 0) print() @@ -153,9 +154,9 @@ def print_public_symbol(symbol): except comtypes.COMError: rva = 0xFFFFFFFF - print(f"{pydia2.cvconst.SymTag(symbol.symTag).name}: [{rva:08X}][{symbol.addressSection:04X}:{symbol.addressOffset:08X}] ", end='') + print(f"{cvconst.SymTag(symbol.symTag).name}: [{rva:08X}][{symbol.addressSection:04X}:{symbol.addressOffset:08X}] ", end='') - if symbol.symTag == pydia2.cvconst.SymTag.Thunk: + if symbol.symTag == cvconst.SymTag.Thunk: try: print("f{symbol.name}") except comtypes.COMError: @@ -194,23 +195,23 @@ def print_symbol(symbol, indent): except comtypes.COMError: print("ERROR - PrintSymbol get_symTag() failed") - if sym_tag == pydia2.cvconst.SymTag.Function: + if sym_tag == cvconst.SymTag.Function: print() print_sym_tag(sym_tag) print(' ' * indent, end='') - if sym_tag == pydia2.cvconst.SymTag.CompilandDetails: + if sym_tag == cvconst.SymTag.CompilandDetails: print_compiland_details(symbol) - elif sym_tag == pydia2.cvconst.SymTag.CompilandEnv: + elif sym_tag == cvconst.SymTag.CompilandEnv: print_compiland_env(symbol) - elif sym_tag == pydia2.cvconst.SymTag.Data: + elif sym_tag == cvconst.SymTag.Data: print_data(symbol) - elif sym_tag in (pydia2.cvconst.SymTag.Function, pydia2.cvconst.SymTag.Block): + elif sym_tag in (cvconst.SymTag.Function, cvconst.SymTag.Block): print_location(symbol) try: @@ -218,16 +219,16 @@ def print_symbol(symbol, indent): except comtypes.COMError: pass - if sym_tag == pydia2.cvconst.SymTag.Function: + if sym_tag == cvconst.SymTag.Function: try: - print(f", {pydia2.cvconst.Call(symbol.callingConvention).name}", end='') + print(f", {cvconst.Call(symbol.callingConvention).name}", end='') except comtypes.COMError: pass print_und_name(symbol) print() - if sym_tag == pydia2.cvconst.SymTag.Function: + if sym_tag == cvconst.SymTag.Function: print(' ' * indent, end='') print(" Function attribute:", end='') @@ -340,27 +341,27 @@ def print_symbol(symbol, indent): print() - enum_children = symbol.findChildren(pydia2.cvconst.SymTag.Null, None, 0) + enum_children = symbol.findChildren(cvconst.SymTag.Null, None, 0) for child in enum_children: - child = child.QueryInterface(pydia2.dia.IDiaSymbol) + child = child.QueryInterface(dia.IDiaSymbol) print_symbol(child, indent + 2) - elif sym_tag == pydia2.cvconst.SymTag.Annotation: + elif sym_tag == cvconst.SymTag.Annotation: print_location(symbol) print() - elif sym_tag == pydia2.cvconst.SymTag.Label: + elif sym_tag == cvconst.SymTag.Label: print_location(symbol) print(", ", end='') print_name(symbol) - elif sym_tag in (pydia2.cvconst.SymTag.Enum, pydia2.cvconst.SymTag.Typedef, pydia2.cvconst.SymTag.UDT, pydia2.cvconst.SymTag.BaseClass): + elif sym_tag in (cvconst.SymTag.Enum, cvconst.SymTag.Typedef, cvconst.SymTag.UDT, cvconst.SymTag.BaseClass): print_udt(symbol) - elif sym_tag in (pydia2.cvconst.SymTag.FuncDebugStart, pydia2.cvconst.SymTag.FuncDebugEnd): + elif sym_tag in (cvconst.SymTag.FuncDebugStart, cvconst.SymTag.FuncDebugEnd): print_location(symbol) - elif sym_tag in (pydia2.cvconst.SymTag.FunctionArgType, pydia2.cvconst.SymTag.FunctionType, pydia2.cvconst.SymTag.PointerType, pydia2.cvconst.SymTag.ArrayType, pydia2.cvconst.SymTag.BaseType): + elif sym_tag in (cvconst.SymTag.FunctionArgType, cvconst.SymTag.FunctionType, cvconst.SymTag.PointerType, cvconst.SymTag.ArrayType, cvconst.SymTag.BaseType): try: print_type(symbol.type) except comtypes.COMError: @@ -368,16 +369,16 @@ def print_symbol(symbol, indent): print() - elif sym_tag == pydia2.cvconst.SymTag.Thunk: + elif sym_tag == cvconst.SymTag.Thunk: print_thunk(symbol) - elif sym_tag == pydia2.cvconst.SymTag.CallSite: + elif sym_tag == cvconst.SymTag.CallSite: print_call_site_info(symbol) - elif sym_tag == pydia2.cvconst.SymTag.HeapAllocationSite: + elif sym_tag == cvconst.SymTag.HeapAllocationSite: print_heap_alloc_site(symbol) - elif sym_tag == pydia2.cvconst.SymTag.CoffGroup: + elif sym_tag == cvconst.SymTag.CoffGroup: print_coff_group(symbol) else: @@ -390,23 +391,38 @@ def print_symbol(symbol, indent): except comtypes.COMError: pass - if sym_tag in (pydia2.cvconst.SymTag.UDT, pydia2.cvconst.SymTag.Annotation): + if sym_tag in (cvconst.SymTag.UDT, cvconst.SymTag.Annotation): print() - enum_children = symbol.findChildren(pydia2.cvconst.SymTag.Null, None, 0) + enum_children = symbol.findChildren(cvconst.SymTag.Null, None, 0) for child in enum_children: - child = child.QueryInterface(pydia2.dia.IDiaSymbol) + child = child.QueryInterface(dia.IDiaSymbol) print_symbol(child, indent + 2) print() def print_sym_tag(sym_tag): - print(f"{pydia2.cvconst.SymTag(sym_tag).name:15s}: ", end='') + print(f"{cvconst.SymTag(sym_tag).name:15s}: ", end='') def print_name(symbol): - pass # TODO + try: + name = symbol.name + except comtypes.COError: + print("(none)", end='') + return + + try: + undecoratedName = symbol.undecoratedName + except comtypes.COMError: + print(f"{name}", end='') + return + + if undecoratedName is None or name == undecoratedName: + print(f"{name}", end='') + else: + print(f"{undecoratedName}({name})") def print_und_name(symbol): @@ -418,7 +434,126 @@ def print_thunk(symbol): def print_compiland_details(symbol): - pass # TODO + try: + print(f"\n\tLanguage: {cvconst.CFL_LANG(symbol.language).name}") + except comtypes.COMError: + pass + + try: + print(f"\tTarget processor: {cvconst.CPU_TYPE(symbol.platform).name}") + except comtypes.COMError: + pass + + try: + if symbol.editAndContinueEnabled: + print("\tCompiled for edit and continue: yes") + else: + print("\tCompiled for edit and continue: no") + except comtypes.COMError: + pass + + try: + if symbol.hasDebugInfo: + print("\tCompiled without debugging info: no") + else: + print("\tCompiled without debugging info: yes") + except comtypes.COMError: + pass + + try: + if symbol.isLTCG: + print("\tCompiled with LTCG: yes") + else: + print("\tCompiled with LTCG: no") + except comtypes.COMError: + pass + + try: + if symbol.isDataAligned: + print("\tCompiled with /bzalign: no") + else: + print("\tCompiled with /bzalign: yes") + except comtypes.COMError: + pass + + try: + if symbol.hasManagedCode: + print("\tManaged code present: yes") + else: + print("\tManaged code present: no") + except comtypes.COMError: + pass + + try: + if symbol.hasSecurityChecks: + print("\tCompiled with /GS: yes") + else: + print("\tCompiled with /GS: no") + except comtypes.COMError: + pass + + try: + if symbol.isSdl: + print("\tCompiled with /sdl: yes") + else: + print("\tCompiled with /sdl: no") + except comtypes.COMError: + pass + + try: + if symbol.isHotpatchable: + print("\tCompiled with /hotpatch: yes") + else: + print("\tCompiled with /hotpatch: no") + except comtypes.COMError: + pass + + try: + if symbol.isCVTCIL: + print("\tConverted by CVTCIL: yes") + else: + print("\tConverted by CVTCIL: no") + except comtypes.COMError: + pass + + try: + if symbol.isMSILNetmodule: + print("\tMSIL module: yes") + else: + print("\tMSIL module: no") + except comtypes.COMError: + pass + + try: + print(f"\tFrontend Version: Major = {symbol.frontEndMajor}, Minor = {symbol.frontEndMinor}, build = {symbol.frontEndBuild}", end='') + + try: + print(f", QFE = {symbol.frontEndQFE}", end='') + except comtypes.COMError: + pass + + print() + except comtypes.COMError: + pass + + try: + print(f"\tBackend Version: Major = {symbol.backEndMajor}, Minor = {symbol.backEndMinor}, build = {symbol.backEndBuild}", end='') + + try: + print(f", QFE = {symbol.backEndQFE}", end='') + except comtypes.COMError: + pass + + print() + except comtypes.COMError: + pass + + try: + print(f"\tVersion string: {symbol.compilerName}", end='') + except comtypes.COMError: + pass + + print() def print_compiland_env(symbol): @@ -432,12 +567,62 @@ def print_location(symbol): print("symbol in optimized code", end='') return - if location_type == pydia2.cvconst.LocationType.Static: + if location_type == cvconst.LocationType.Static: + try: + print(f"{cvconst.LocationType(location_type).name}, [{symbol.relativeVirtualAddress:08X}][{symbol.addressSection:04X}:{symbol.addressOffset:08X}]", end='') + except comtypes.COMError: + pass + + elif location_type in (cvconst.LocationType.TLS, cvconst.LocationType.MetaData, cvconst.LocationType.IlRel): try: - print(f"{pydia2.cvconst.LocationType(location_type).name}, [{symbol.relativeVirtualAddress:08X}][{symbol.addressSection:04X}:{symbol.addressOffset:08X}]", end='') + print(f"{cvconst.LocationType(location_type).name}, [{symbol.relativeVirtualAddress:08X}][{symbol.addressSection:04X}:{symbol.addressOffset:08X}]", end='') except comtypes.COMError: pass - # TODO + + elif location_type == cvconst.LocationType.RegRel: + try: + # TODO register names + print(f"{symbol.registerId} Relative, [{symbol.offset:08X}]", end='') + except comtypes.COMError: + pass + + elif location_type == cvconst.LocationType.ThisRel: + try: + print(f"this+0x{symbol.offset:X}", end='') + except comtypes.COMError: + pass + + elif location_type == cvconst.LocationType.BitField: + try: + print(f"this(bf)+0x{symbol.offset:X}:0x{symbol.bitPosition:X} len(0x{symbol.length:X})", end='') + except comtypes.COMError: + pass + + elif location_type == cvconst.LocationType.Enregistered: + try: + # TODO register names + print(f"enregistered {symbol.registerId}", end='') + except comtypes.COMError: + pass + + elif location_type == cvconst.LocationType.Slot: + try: + print(f"{cvconst.LocationType(location_type).name} {symbol.slot}", end='') + except comtypes.COMError: + pass + + elif location_type == cvconst.LocationType.Constant: + try: + print(f"constant", end='') + print_variant(symbol.value) + except comtypes.COMError: + pass + + elif location_type == cvconst.LocationType.Null: + pass + + else: + print(f"Error - invalid location type: 0x{location_type:X}", end='') def print_const(symbol): From 7b7b248818845f93a753abe5a48a65551cf64ac5 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Sun, 27 Feb 2022 21:43:25 +0200 Subject: [PATCH 11/16] More work on __main__.py --- pydia2/__main__.py | 265 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 236 insertions(+), 29 deletions(-) diff --git a/pydia2/__main__.py b/pydia2/__main__.py index 3af9fb7..0660865 100644 --- a/pydia2/__main__.py +++ b/pydia2/__main__.py @@ -174,19 +174,19 @@ def print_public_symbol(symbol): def print_global_symbol(symbol): - pass # TODO + print("TODO", end='') # TODO def print_call_site_info(symbol): - pass # TODO + print("TODO", end='') # TODO def print_heap_alloc_site(symbol): - pass # TODO + print("TODO", end='') # TODO def print_coff_group(symbol): - pass # TODO + print("TODO", end='') # TODO def print_symbol(symbol, indent): @@ -386,8 +386,9 @@ def print_symbol(symbol, indent): try: type_ = symbol.type - print(" has type ", end='') - print_type(type_) + if type_: + print(" has type ", end='') + print_type(type_) except comtypes.COMError: pass @@ -414,23 +415,35 @@ def print_name(symbol): return try: - undecoratedName = symbol.undecoratedName + undecorated_name = symbol.undecoratedName except comtypes.COMError: print(f"{name}", end='') return - if undecoratedName is None or name == undecoratedName: + if undecorated_name is None or name == undecorated_name: print(f"{name}", end='') else: - print(f"{undecoratedName}({name})") + print(f"{undecorated_name}({name})") def print_und_name(symbol): - pass # TODO + try: + undecorated_name = symbol.undecoratedName + if undecorated_name is not None and len(undecorated_name) > 0: + print(f"{undecorated_name}", end='') + else: + print("(none)", end='') + except comtypes.COMError: + try: + name = symbol.name + if len(name) > 0: + print(f"{name}", end='') + except comtypes.Error: + print("(none)", end='') def print_thunk(symbol): - pass # TODO + print("TODO", end='') # TODO def print_compiland_details(symbol): @@ -557,7 +570,9 @@ def print_compiland_details(symbol): def print_compiland_env(symbol): - pass # TODO + print_name(symbol) + print(" =", end='') + print_variant(symbol.value) def print_location(symbol): @@ -573,7 +588,7 @@ def print_location(symbol): except comtypes.COMError: pass - elif location_type in (cvconst.LocationType.TLS, cvconst.LocationType.MetaData, cvconst.LocationType.IlRel): + elif location_type in (cvconst.LocationType.TLS, cvconst.LocationType.LocInMetaData, cvconst.LocationType.IlRel): try: print(f"{cvconst.LocationType(location_type).name}, [{symbol.relativeVirtualAddress:08X}][{symbol.addressSection:04X}:{symbol.addressOffset:08X}]", end='') except comtypes.COMError: @@ -626,19 +641,205 @@ def print_location(symbol): def print_const(symbol): - pass # TODO + print("TODO", end='') # TODO def print_udt(symbol): - pass # TODO + print_name(symbol) + print_symbol_type(symbol) def print_symbol_type(symbol): - pass # TODO + try: + type_ = symbol.type + print(", Type: ", end='') + print_type(symbol) + except comtypes.COMError: + pass def print_type(symbol): - pass # TODO + try: + sym_tag = symbol.symTag + except comtypes.COMError: + print("ERROR - can't retrieve the symbol's SymTag") + return + + try: + name = symbol.name + except comtypes.COMError: + name = '' + + len_ = symbol.length + + if sym_tag != cvconst.SymTag.PointerType: + try: + if symbol.constType: + print("const ", end='') + except comtypes.COMError: + pass + + try: + if symbol.volatileType: + print("volatile ", end='') + except comtypes.COMError: + pass + + try: + if symbol.unalignedType: + print("__unaligned ", end='') + except comtypes.COMError: + pass + + if sym_tag == cvconst.SymTag.UDT: + print_udt_kind(symbol) + print_name(symbol) + + elif sym_tag == cvconst.SymTag.Enum: + print("enum ", end='') + print_name(symbol) + + elif sym_tag == cvconst.SymTag.FunctionType: + print("function ", end='') + + elif sym_tag == cvconst.SymTag.PointerType: + try: + base_type = symbol.type + except comtypes.COMError: + print("ERROR - SymTagPointerType get_type", end='') + return + + print_type(base_type) + + try: + if symbol.reference: + print(" &") + else: + print(" *") + except comtypes.COMError: + pass + + try: + if symbol.constType: + print("const ", end='') + except comtypes.COMError: + pass + + try: + if symbol.volatileType: + print("volatile ", end='') + except comtypes.COMError: + pass + + try: + if symbol.unalignedType: + print("__unaligned ", end='') + except comtypes.COMError: + pass + + + elif sym_tag == cvconst.SymTag.ArrayType: + try: + base_type = symbol.type + except comtypes.Error: + print("ERROR - SymTagArrayType get_type") + return + + print_type(base_type) + + try: + rank = symbol.rank + enum_sym = symbol.findChildren(cvconst.SymTag.Dimension, None, 0) + for sym in enum_sym: + sym = sym.QueryInterface(dia.IDiaSymbol) + + print("[", end='') + + try: + print_bound(symbol.lowerBound) + print("..", end='') + except comtypes.COMError: + pass + + try: + print_bound(symbol.upperBound) + print("..", end='') + except comtypes.COMError: + pass + + print("]", end='') + except comtypes.Error: + enum_sym = symbol.findChildren(cvconst.SymTag.CustomType, None, 0) + if enum_sym is not None and enum_sym.Count > 0: + for sym in enum_sym: + sym = sym.QueryInterface(dia.IDiaSymbol) + print("[", end='') + print_type(sym) + print("]", end='') + else: + try: + print(f"[0x{symbol.count:X}", end='') + except comtypes.Error: + try: + len_array = symbol.length + len_elem = base_type.length + + if len_elem == 0: + print(f"[0x{len_array:X}]", end='') + else: + print(f"[0x{len_array / len_elem}]", end='') + + except comtypes.Error: + pass + + + elif sym_tag == cvconst.SymTag.BaseType: + try: + info = symbol.baseType + except comtypes.COMError: + print("SymTagBaseType get_baseType", end='') + return + + if info == cvconst.BasicType.UInt: + print("unsigned ", end='') + + if info == cvconst.BasicType.Int: + if len_ == 1: + if info == cvconst.BasicType.Int: + print("signed ", end='') + + elif len_ == 2: + print("short", end='') + + elif len_ == 4: + print("int", end='') + + elif len_ == 8: + print("__int64", end='') + + info = 0xFFFFFFFF + + elif info == cvconst.BasicType.Float: + if len_ == 4: + print("float", end='') + elif len_ == 8: + print("double", end='') + + info = 0xFFFFFFFF + + if info != 0xFFFFFFFF: + # TODO Better strings? + print(f"{cvconst.BasicType(info).name}", end='') + + + elif sym_tag == cvconst.SymTag.Typedef: + print_name(symbol) + + elif sym_tag == cvconst.SymTag.CustomType: + pass # TODO + + elif sym_tag == cvconst.SymTag.Data: + print_location(symbol) def print_bound(symbol): @@ -646,51 +847,57 @@ def print_bound(symbol): def print_data(symbol): - pass # TODO + print_location(symbol) + + print(f", {cvconst.DataKind(symbol.dataKind).name}", end='') + print_symbol_type(symbol) + + print(", ", end='') + print_name(symbol) def print_variant(var): - pass # TODO + print("TODO", end='') # TODO def print_udt_kind(symbol): - pass # TODO + print("TODO", end='') # TODO def print_type_in_detail(symbol, indent): - pass # TODO + print("TODO", end='') # TODO def print_function_type(symbol): - pass # TODO + print("TODO", end='') # TODO def print_source_file(source): - pass # TODO + print("TODO", end='') # TODO def print_lines(session, function): - pass # TODO + print("TODO", end='') # TODO def print_enum_lines(lines): - pass # TODO + print("TODO", end='') # TODO def print_sec_contribs(segment): - pass # TODO + print("TODO", end='') # TODO def print_stream_data(stream): - pass # TODO + print("TODO", end='') # TODO def print_frame_data(frame_data): - pass # TODO + print("TODO", end='') # TODO def print_property_storage(prop_store): - pass # TODO + print("TODO", end='') # TODO def main(): From fd4fdf4a03792255534e5197ae18272e0600e0ba Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Sun, 27 Feb 2022 21:51:25 +0200 Subject: [PATCH 12/16] Add a TODO --- pydia2/__main__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pydia2/__main__.py b/pydia2/__main__.py index 0660865..833d063 100644 --- a/pydia2/__main__.py +++ b/pydia2/__main__.py @@ -3,6 +3,7 @@ This is a reproduction of the DIA2Dump sample included with the DIA SDK. """ +# TODO Audit exception handling import sys import os import argparse From cbf142d2b5d0b0f4c299d99863a0f13ac5d2c421 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Wed, 2 Mar 2022 14:57:04 +0200 Subject: [PATCH 13/16] Implement print_thunk --- pydia2/__main__.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pydia2/__main__.py b/pydia2/__main__.py index 833d063..e445306 100644 --- a/pydia2/__main__.py +++ b/pydia2/__main__.py @@ -444,7 +444,16 @@ def print_und_name(symbol): def print_thunk(symbol): - print("TODO", end='') # TODO + try: + print(f"[{symbol.relativeVirtualAddress:08X}][{symbol.addressSection:04X}:{symbol.addressOffset:08X}]", end='') + except comtypes.COMError: + pass + + try: + print(f", target [{symbol.targetSection:08X}][{symbol.targetOffset:04X}:{symbol.targetRelativeVirtualAddress:08X}]", end='') + except comtypes.COMError: + print(", target ", end='') + print_name(symbol) def print_compiland_details(symbol): From 7174c709f8bd4fc069ebc10afedcf2b088ac9037 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Wed, 2 Mar 2022 15:37:11 +0200 Subject: [PATCH 14/16] Implement a bit more of __main__.py --- docs/example.rst | 3 ++ docs/index.rst | 3 +- pydia2/__main__.py | 112 +++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 107 insertions(+), 11 deletions(-) create mode 100644 docs/example.rst diff --git a/docs/example.rst b/docs/example.rst new file mode 100644 index 0000000..47f9544 --- /dev/null +++ b/docs/example.rst @@ -0,0 +1,3 @@ +Example (Dia2Dump in Python) +============================ +.. literalinclude:: ../pydia2/__main__.py diff --git a/docs/index.rst b/docs/index.rst index 567b7a2..93581f7 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -4,7 +4,8 @@ Welcome to pydia2's documentation! .. toctree:: :maxdepth: 2 :caption: Contents: - :hidden: + + example .. automodule:: pydia2 :members: diff --git a/pydia2/__main__.py b/pydia2/__main__.py index e445306..f6b4870 100644 --- a/pydia2/__main__.py +++ b/pydia2/__main__.py @@ -90,23 +90,54 @@ def dump_all_symbols(session): def dump_all_globals(session): - pass # TODO + print("\n\n*** GLOBALS\n") + + for sym_tag in [cvconst.SymTag.Function, cvconst.SymTag.Thunk, cvconst.SymTag.Data]: + enum_children = session.globalScope.findChildren(sym_tag, None, 0) + for symbol in enum_children: + symbol = symbol.QueryInterface(dia.IDiaSymbol) + print_global_symbol(symbol) def dump_all_types(session): - pass # TODO + print("\n\n*** TYPES\n") + + dump_all_udts(session) + dump_all_enums(session) + dump_all_typedefs(session) def dump_all_udts(session): - pass # TODO + print("\n\n** User Defined Types\n") + + enum_children = session.globalScope.findChildren(cvconst.SymTag.UDT, None, 0) + for symbol in enum_children: + symbol = symbol.QueryInterface(dia.IDiaSymbol) + print_type_in_detail(symbol, 0) + + print() def dump_all_enums(session): - pass # TODO + print("\n\n** ENUMS\n") + + enum_children = session.globalScope.findChildren(cvconst.SymTag.Enum, None, 0) + for symbol in enum_children: + symbol = symbol.QueryInterface(dia.IDiaSymbol) + print_type_in_detail(symbol, 0) + + print() def dump_all_typedefs(session): - pass # TODO + print("\n\n** TYPEDEFS\n") + + enum_children = session.globalScope.findChildren(cvconst.SymTag.Typedef, None, 0) + for symbol in enum_children: + symbol = symbol.QueryInterface(dia.IDiaSymbol) + print_type_in_detail(symbol, 0) + + print() def dump_all_files(session): @@ -146,7 +177,14 @@ def dump_all_fpo(session): def dump_all_oems(session): - pass # TODO + print("\n\n*** OEM Specific types\n") + + enum_children = session.globalScope.findChildren(cvconst.SymTag.CustomType, None, 0) + for symbol in enum_children: + symbol = symbol.QueryInterface(dia.IDiaSymbol) + print_type_in_detail(symbol, 0) + + print() def print_public_symbol(symbol): @@ -179,15 +217,70 @@ def print_global_symbol(symbol): def print_call_site_info(symbol): - print("TODO", end='') # TODO + try: + print(f"[0x{symbol.addressSection:04X}:0x{symbol.addressOffset:08X}] ", end='') + except comtypes.COMError: + pass + + try: + print(f"0x{symbol.relativeVirtualAddress:08X} ", end='') + except comtypes.COMError: + pass + + try: + func_type = symbol.type + tag = symbol.symTag + + if tag == cvconst.SymTag.FunctionType: + print_function_type(tag) + elif tag == cvconst.SymTag.PointerType: + print_function_type(func_type) + else: + print("???") + except comtypes.COMError: + pass def print_heap_alloc_site(symbol): - print("TODO", end='') # TODO + try: + print(f"[0x{symbol.addressSection:04X}:0x{symbol.addressOffset:08X}] ", end='') + except comtypes.COMError: + pass + + try: + print(f"0x{symbol.relativeVirtualAddress:08X} ", end='') + except comtypes.COMError: + pass + + try: + alloc_type = symbol.type + print_type(alloc_type) + except comtypes.COMError: + pass def print_coff_group(symbol): - print("TODO", end='') # TODO + try: + print(f"[0x{symbol.addressSection:04X}:0x{symbol.addressOffset:08X}] ", end='') + except comtypes.COMError: + pass + + try: + print(f"0x{symbol.relativeVirtualAddress:08X}, ", end='') + except comtypes.COMError: + pass + + try: + print("len = {symbol.length:08X}, ", end='') + except comtypes.COMError: + pass + + try: + print("characteristics = {symbol.characteristics:08X}", end='') + except comtypes.COMError: + pass + + print_name(symbol) def print_symbol(symbol, indent): @@ -1032,6 +1125,5 @@ def main(): pass # TODO - if __name__ == "__main__": sys.exit(main()) From 2f89f05dd8d3a4fc584f8d993d1544a0dc350619 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Wed, 2 Mar 2022 22:18:01 +0200 Subject: [PATCH 15/16] More work on __main__.py --- pydia2/__main__.py | 88 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) diff --git a/pydia2/__main__.py b/pydia2/__main__.py index f6b4870..402c1d9 100644 --- a/pydia2/__main__.py +++ b/pydia2/__main__.py @@ -968,7 +968,93 @@ def print_udt_kind(symbol): def print_type_in_detail(symbol, indent): - print("TODO", end='') # TODO + try: + sym_tag = symbol.symTag + except comtypes.COMError: + print("ERROR - PrintTypeInDetail() get_symTag") + return + + print_sym_tag(sym_tag) + + print(' ' * indent, end='') + + if sym_tag == cvconst.SymTag.Data: + print_data(symbol) + + try: + type_ = symbol.type + sym_tag_type = type_.symTag + if sym_tag_type == cvconst.SymTag.UDT: + print() + print_type_in_detail(type_, indent + 2) + except comtypes.COMError: + pass + + elif sym_tag in (cvconst.SymTag.Typedef, cvconst.SymTag.VTable): + print_symbol_type(symbol) + + elif sym_tag in (cvconst.SymTag.Enum, cvconst.SymTag.UDT): + print_udt(symbol) + print() + + enum_children = symbol.findChildren(cvconst.SymTag.Null, None, 0) + for child in enum_children: + child = child.QueryInterface(dia.IDiaSymbol) + print_type_in_detail(child, indent + 2) + + return + + elif sym_tag == cvconst.SymTag.Function: + print_function_type(symbol) + return + + elif sym_tag == cvconst.SymTag.PointerType: + print_name(symbol) + print(" has type ", end='') + print_type(symbol) + + elif sym_tag in (cvconst.SymTag.ArrayType, cvconst.SymTag.BaseType, cvconst.SymTag.FunctionArgType, cvconst.SymTag.UsingNamespace, cvconst.SymTag.Custom, cvconst.SymTag.Friend): + print_name(symbol) + print_symbol_type(symbol) + + elif sym_tag in (cvconst.SymTag.VTableShape, cvconst.SymTag.BaseClass): + print_name(symbol) + + try: + print(f" virtual, offset = 0x{symbol.virtualBaseDispIndex:X}, pointer offset = {symbol.virtualBasePointerOffset}, virtual base pointer type = ", end='') + + try: + virtualBaseTableType = symbol.virtualBaseTableType + if virtualBaseTableType: + print_type(virtualBaseTableType) + except comtypes.COMError: + print("(unknown)", end='') + except comtypes.COMError: + try: + print(f", offset = 0x{symbol.offset:X}", end='') + except comtypes.COMError: + pass + + print() + + enum_children = symbol.findChildren(cvconst.SymTag.Null, None, 0) + for child in enum_children: + child = child.QueryInterface(dia.IDiaSymbol) + print_type_in_detail(child, indent + 2) + + elif sym_tag == cvconst.SymTag.FunctionType: + try: + print_type(symbol.type) + except comtypes.COMError: + pass + + elif sym_tag == cvconst.SymTag.Thunk: + print_thunk(symbol) + + else: + print("ERROR - PrintTypeInDetail() invalid SymTag") + + print() def print_function_type(symbol): From 6276d90d696010d279fefc15bd2c3da088d7e9a9 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Thu, 22 Feb 2024 19:20:36 +0200 Subject: [PATCH 16/16] Dump WIP --- pydia2/__main__.py | 241 +++++++++++++++++++++++---------------------- 1 file changed, 124 insertions(+), 117 deletions(-) diff --git a/pydia2/__main__.py b/pydia2/__main__.py index 402c1d9..6bfa660 100644 --- a/pydia2/__main__.py +++ b/pydia2/__main__.py @@ -141,7 +141,14 @@ def dump_all_typedefs(session): def dump_all_files(session): - pass # TODO + print("\n\n*** FILES\n") + + enum_children = session.globalScope.findChildren(cvconst.SymTag.Compiland, None, 0) + for symbol in enum_children: + symbol = symbol.QueryInterface(dia.IDiaSymbol) + print_type_in_detail(symbol, 0) + + print() def dump_all_lines(session): @@ -794,155 +801,155 @@ def print_type(symbol): except comtypes.COMError: pass - if sym_tag == cvconst.SymTag.UDT: - print_udt_kind(symbol) - print_name(symbol) + if sym_tag == cvconst.SymTag.UDT: + print_udt_kind(symbol) + print_name(symbol) - elif sym_tag == cvconst.SymTag.Enum: - print("enum ", end='') - print_name(symbol) + elif sym_tag == cvconst.SymTag.Enum: + print("enum ", end='') + print_name(symbol) - elif sym_tag == cvconst.SymTag.FunctionType: - print("function ", end='') + elif sym_tag == cvconst.SymTag.FunctionType: + print("function ", end='') - elif sym_tag == cvconst.SymTag.PointerType: - try: - base_type = symbol.type - except comtypes.COMError: - print("ERROR - SymTagPointerType get_type", end='') - return + elif sym_tag == cvconst.SymTag.PointerType: + try: + base_type = symbol.type + except comtypes.COMError: + print("ERROR - SymTagPointerType get_type", end='') + return - print_type(base_type) + print_type(base_type) - try: - if symbol.reference: - print(" &") - else: - print(" *") - except comtypes.COMError: - pass + try: + if symbol.reference: + print(" &") + else: + print(" *") + except comtypes.COMError: + pass - try: - if symbol.constType: - print("const ", end='') - except comtypes.COMError: - pass + try: + if symbol.constType: + print("const ", end='') + except comtypes.COMError: + pass - try: - if symbol.volatileType: - print("volatile ", end='') - except comtypes.COMError: - pass + try: + if symbol.volatileType: + print("volatile ", end='') + except comtypes.COMError: + pass - try: - if symbol.unalignedType: - print("__unaligned ", end='') - except comtypes.COMError: - pass + try: + if symbol.unalignedType: + print("__unaligned ", end='') + except comtypes.COMError: + pass - elif sym_tag == cvconst.SymTag.ArrayType: - try: - base_type = symbol.type - except comtypes.Error: - print("ERROR - SymTagArrayType get_type") - return + elif sym_tag == cvconst.SymTag.ArrayType: + try: + base_type = symbol.type + except comtypes.Error: + print("ERROR - SymTagArrayType get_type") + return - print_type(base_type) + print_type(base_type) - try: - rank = symbol.rank - enum_sym = symbol.findChildren(cvconst.SymTag.Dimension, None, 0) + try: + rank = symbol.rank + enum_sym = symbol.findChildren(cvconst.SymTag.Dimension, None, 0) + for sym in enum_sym: + sym = sym.QueryInterface(dia.IDiaSymbol) + + print("[", end='') + + try: + print_bound(symbol.lowerBound) + print("..", end='') + except comtypes.COMError: + pass + + try: + print_bound(symbol.upperBound) + print("..", end='') + except comtypes.COMError: + pass + + print("]", end='') + except comtypes.Error: + enum_sym = symbol.findChildren(cvconst.SymTag.CustomType, None, 0) + if enum_sym is not None and enum_sym.Count > 0: for sym in enum_sym: sym = sym.QueryInterface(dia.IDiaSymbol) - print("[", end='') - - try: - print_bound(symbol.lowerBound) - print("..", end='') - except comtypes.COMError: - pass - - try: - print_bound(symbol.upperBound) - print("..", end='') - except comtypes.COMError: - pass - + print_type(sym) print("]", end='') - except comtypes.Error: - enum_sym = symbol.findChildren(cvconst.SymTag.CustomType, None, 0) - if enum_sym is not None and enum_sym.Count > 0: - for sym in enum_sym: - sym = sym.QueryInterface(dia.IDiaSymbol) - print("[", end='') - print_type(sym) - print("]", end='') - else: + else: + try: + print(f"[0x{symbol.count:X}", end='') + except comtypes.Error: try: - print(f"[0x{symbol.count:X}", end='') - except comtypes.Error: - try: - len_array = symbol.length - len_elem = base_type.length + len_array = symbol.length + len_elem = base_type.length - if len_elem == 0: - print(f"[0x{len_array:X}]", end='') - else: - print(f"[0x{len_array / len_elem}]", end='') + if len_elem == 0: + print(f"[0x{len_array:X}]", end='') + else: + print(f"[0x{len_array / len_elem}]", end='') - except comtypes.Error: - pass + except comtypes.Error: + pass - elif sym_tag == cvconst.SymTag.BaseType: - try: - info = symbol.baseType - except comtypes.COMError: - print("SymTagBaseType get_baseType", end='') - return + elif sym_tag == cvconst.SymTag.BaseType: + try: + info = symbol.baseType + except comtypes.COMError: + print("SymTagBaseType get_baseType", end='') + return - if info == cvconst.BasicType.UInt: - print("unsigned ", end='') + if info == cvconst.BasicType.UInt: + print("unsigned ", end='') - if info == cvconst.BasicType.Int: - if len_ == 1: - if info == cvconst.BasicType.Int: - print("signed ", end='') + if info == cvconst.BasicType.Int: + if len_ == 1: + if info == cvconst.BasicType.Int: + print("signed ", end='') - elif len_ == 2: - print("short", end='') + elif len_ == 2: + print("short", end='') - elif len_ == 4: - print("int", end='') + elif len_ == 4: + print("int", end='') - elif len_ == 8: - print("__int64", end='') + elif len_ == 8: + print("__int64", end='') - info = 0xFFFFFFFF + info = 0xFFFFFFFF - elif info == cvconst.BasicType.Float: - if len_ == 4: - print("float", end='') - elif len_ == 8: - print("double", end='') + elif info == cvconst.BasicType.Float: + if len_ == 4: + print("float", end='') + elif len_ == 8: + print("double", end='') - info = 0xFFFFFFFF + info = 0xFFFFFFFF - if info != 0xFFFFFFFF: - # TODO Better strings? - print(f"{cvconst.BasicType(info).name}", end='') + if info != 0xFFFFFFFF: + # TODO Better strings? + print(f"{cvconst.BasicType(info).name}", end='') - elif sym_tag == cvconst.SymTag.Typedef: - print_name(symbol) + elif sym_tag == cvconst.SymTag.Typedef: + print_name(symbol) - elif sym_tag == cvconst.SymTag.CustomType: - pass # TODO + elif sym_tag == cvconst.SymTag.CustomType: + pass # TODO - elif sym_tag == cvconst.SymTag.Data: - print_location(symbol) + elif sym_tag == cvconst.SymTag.Data: + print_location(symbol) def print_bound(symbol): @@ -1058,7 +1065,7 @@ def print_type_in_detail(symbol, indent): def print_function_type(symbol): - print("TODO", end='') # TODO + print("TODO") # TODO def print_source_file(source):