public TypeInformation GetTypeByName(IntPtr base_address, string name) { Dictionary <long, SymbolLoadedModule> modules = GetLoadedModules().ToDictionary(m => m.BaseAddress.ToInt64()); using (var sym_info = AllocateSymInfo()) { if (_sym_get_type_from_name(Handle, base_address.ToInt64(), name, sym_info)) { var result = sym_info.Result; SymbolLoadedModule loaded_module; if (modules.ContainsKey(base_address.ToInt64())) { loaded_module = modules[base_address.ToInt64()]; } else { loaded_module = new SymbolLoadedModule(string.Empty, new IntPtr(result.ModBase), 0, string.Empty, true, this); } TypeInformationCache type_cache = new TypeInformationCache(); var ret = CreateType(type_cache, result.Tag, result.ModBase, result.TypeIndex, result.Size, loaded_module, GetNameFromSymbolInfo(sym_info)); type_cache.FixupPointerTypes(); return(ret); } else { throw new ArgumentException("Invalid type"); } } }
private BaseTypeInformation CreateBaseType(TypeInformationCache type_cache, long module_base, int index, SymbolLoadedModule module) { var base_type = GetSymbolDword(IMAGEHLP_SYMBOL_TYPE_INFO.TI_GET_BASETYPE, module_base, index) ?? 0; var length = GetSymbolLong(IMAGEHLP_SYMBOL_TYPE_INFO.TI_GET_LENGTH, module_base, index) ?? 0; return(new BaseTypeInformation(length, index, module, (BasicType)base_type)); }
private TypeInformation CreateType(TypeInformationCache type_cache, long module_base, int index, SymbolLoadedModule module) { var tag = GetSymbolTag(module_base, index) ?? SymTagEnum.SymTagNull; string name = GetSymbolName(module_base, index); long length = GetSymbolLength(module_base, index); return(CreateType(type_cache, tag, module_base, index, length, module, name)); }
public IEnumerable <TypeInformation> QueryTypesByName(IntPtr base_address, string mask) { Dictionary <long, SymbolLoadedModule> modules = GetLoadedModules().ToDictionary(m => m.BaseAddress.ToInt64()); List <TypeInformation> symbols = new List <TypeInformation>(); TypeInformationCache type_cache = new TypeInformationCache(); _sym_enum_types_by_name(Handle, base_address.ToInt64(), mask, (s, z, c) => EnumTypes(type_cache, modules, symbols, s), IntPtr.Zero); type_cache.FixupPointerTypes(); return(symbols); }
private ArrayTypeInformation CreateArrayType(TypeInformationCache type_cache, long module_base, int index, SymbolLoadedModule module) { int?array_type_index = GetArrayElementType(module_base, index); if (!array_type_index.HasValue) { return(new ArrayTypeInformation(index, module, new BaseTypeInformation(1, 0, module, BasicType.Char))); } TypeInformation array_type = CreateType(type_cache, module_base, array_type_index.Value, module); return(new ArrayTypeInformation(index, module, array_type)); }
public TypeInformation GetTypeForSymbolByAddress(IntPtr address) { var symbol = GetSymbolInfoForAddress(address); if (symbol == null) { return(null); } TypeInformationCache type_cache = new TypeInformationCache(); var ret = CreateType(type_cache, symbol.Tag, symbol.Module.BaseAddress.ToInt64(), symbol.TypeIndex, symbol.Size, symbol.Module, symbol.Name, symbol.Address); type_cache.FixupPointerTypes(); return(ret); }
private TypeInformation CreateType(TypeInformationCache type_cache, SymTagEnum tag, long module_base, int index, long size, SymbolLoadedModule module, string name, long address = 0) { if (type_cache.HasEntry(module_base, index)) { return(type_cache.GetEntry(module_base, index)); } TypeInformation ret; switch (tag) { case SymTagEnum.SymTagUDT: ret = CreateUserDefinedType(type_cache, module_base, index, module, name); break; case SymTagEnum.SymTagEnum: ret = CreateEnumType(type_cache, module_base, index, module, name); break; case SymTagEnum.SymTagBaseType: ret = CreateBaseType(type_cache, module_base, index, module); break; case SymTagEnum.SymTagPointerType: ret = CreatePointerType(type_cache, module_base, index, module); break; case SymTagEnum.SymTagArrayType: ret = CreateArrayType(type_cache, module_base, index, module); break; case SymTagEnum.SymTagFunction: ret = CreateFunctionType(type_cache, module_base, index, module, name, address); break; default: Debug.WriteLine(tag.ToString()); ret = new TypeInformation(tag, size, index, module, name); break; } type_cache.AddEntry(module_base, index, ret); return(ret); }
private UserDefinedTypeInformation CreateUserDefinedType(TypeInformationCache type_cache, long module_base, int type_index, SymbolLoadedModule module, string name) { int[] child_ids = GetChildIds(module_base, type_index); List <UserDefinedTypeMember> members = new List <UserDefinedTypeMember>(); long length = GetSymbolLong(IMAGEHLP_SYMBOL_TYPE_INFO.TI_GET_LENGTH, module_base, type_index) ?? 0; foreach (var id in child_ids) { if (!CheckTypeTag(module_base, id, SymTagEnum.SymTagData)) { continue; } string member_name = GetSymbolName(module_base, id); int offset = GetSymbolDword(IMAGEHLP_SYMBOL_TYPE_INFO.TI_GET_OFFSET, module_base, id) ?? 0; int? member_type = GetSymbolDword(IMAGEHLP_SYMBOL_TYPE_INFO.TI_GET_TYPE, module_base, id); var bit_position = GetSymbolDword(IMAGEHLP_SYMBOL_TYPE_INFO.TI_GET_BITPOSITION, module_base, id); var bit_length = GetSymbolLength(module_base, id); TypeInformation member_type_value = new TypeInformation(SymTagEnum.SymTagNull, 0, 0, module, member_name); if (member_type.HasValue) { var tag = GetSymbolTag(module_base, member_type.Value); member_type_value = CreateType(type_cache, tag ?? SymTagEnum.SymTagNull, module_base, member_type.Value, GetSymbolLong(IMAGEHLP_SYMBOL_TYPE_INFO.TI_GET_LENGTH, module_base, member_type.Value) ?? 0 , module, GetSymbolName(module_base, member_type.Value)); } if (bit_position.HasValue) { members.Add(new UserDefinedTypeBitFieldMember(member_type_value, member_name, offset, bit_position.Value, bit_length)); } else { members.Add(new UserDefinedTypeMember(member_type_value, member_name, offset)); } } UdtKind kind = (UdtKind)(GetSymbolDword(IMAGEHLP_SYMBOL_TYPE_INFO.TI_GET_UDTKIND, module_base, type_index) ?? 0); return(new UserDefinedTypeInformation(length, type_index, module, name, kind == UdtKind.UdtUnion, members.AsReadOnly())); }
private bool EnumTypes(TypeInformationCache type_cache, Dictionary <long, SymbolLoadedModule> modules, List <TypeInformation> symbols, IntPtr symbol_info) { using (var sym_info = MapSymbolInfo(symbol_info)) { SymbolLoadedModule loaded_module; var result = sym_info.Result; if (modules.ContainsKey(result.ModBase)) { loaded_module = modules[result.ModBase]; } else { loaded_module = new SymbolLoadedModule(string.Empty, new IntPtr(result.ModBase), 0, this); modules.Add(result.ModBase, loaded_module); } symbols.Add(CreateType(type_cache, result.Tag, result.ModBase, result.TypeIndex, result.Size, loaded_module, GetNameFromSymbolInfo(sym_info))); return(true); } }
private PointerTypeInformation CreatePointerType(TypeInformationCache type_cache, long module_base, int index, SymbolLoadedModule module) { var length = GetSymbolLong(IMAGEHLP_SYMBOL_TYPE_INFO.TI_GET_LENGTH, module_base, index) ?? 0; var type_id = GetSymbolDword(IMAGEHLP_SYMBOL_TYPE_INFO.TI_GET_TYPEID, module_base, index); var is_reference = GetSymbolDword(IMAGEHLP_SYMBOL_TYPE_INFO.TI_GET_IS_REFERENCE, module_base, index) ?? 0; PointerTypeInformation pointer; if (type_id.HasValue) { pointer = new PointerTypeInformation(length, index, module, null, is_reference != 0); type_cache.AddEntry(module_base, index, pointer); type_cache.AddFixedup(module_base, type_id.Value, pointer); pointer.PointerType = CreateType(type_cache, module_base, type_id.Value, module); } else { return(new PointerTypeInformation(length, index, module, new BaseTypeInformation(0, 0, module, BasicType.Void), is_reference != 0)); } type_cache.AddEntry(module_base, index, pointer); return(pointer); }
private EnumTypeInformation CreateEnumType(TypeInformationCache type_cache, long module_base, int type_index, SymbolLoadedModule module, string name) { int[] child_ids = GetChildIds(module_base, type_index); long length = GetSymbolLong(IMAGEHLP_SYMBOL_TYPE_INFO.TI_GET_LENGTH, module_base, type_index) ?? 0; List <EnumTypeInformationValue> values = new List <EnumTypeInformationValue>(); foreach (var id in child_ids) { if (CheckTypeTag(module_base, id, SymTagEnum.SymTagData)) { long enum_value = 0; if (_sym_get_type_info_var(Handle, module_base, id, IMAGEHLP_SYMBOL_TYPE_INFO.TI_GET_VALUE, out object value)) { enum_value = Convert.ToInt64(value); } values.Add(new EnumTypeInformationValue(GetSymbolName(module_base, id), enum_value)); } } return(new EnumTypeInformation(length, type_index, module, name, values.AsReadOnly())); }
private FunctionTypeInformation CreateFunctionType(TypeInformationCache type_cache, long module_base, int type_index, SymbolLoadedModule module, string name, long address) { List <FunctionParameter> parameters = new List <FunctionParameter>(); TypeInformation return_type = null; int[] child_ids = GetChildIds(module_base, type_index); List <string> arg_names = QueryLocalParameterNames(address, module); foreach (int id in child_ids) { if (GetSymbolTag(module_base, id) == SymTagEnum.SymTagFunctionArgType) { var type_id = GetSymbolDword(IMAGEHLP_SYMBOL_TYPE_INFO.TI_GET_TYPEID, module_base, id); if (type_id.HasValue) { TypeInformation arg = CreateType(type_cache, module_base, type_id.Value, module); string arg_name = $"p{parameters.Count}"; if (arg_names.Count > parameters.Count) { arg_name = arg_names[parameters.Count]; } parameters.Add(new FunctionParameter(arg_name, arg)); } } } int?ret_id = GetSymbolDword(IMAGEHLP_SYMBOL_TYPE_INFO.TI_GET_TYPE, module_base, type_index); if (ret_id.HasValue) { return_type = CreateType(type_cache, module_base, ret_id.Value, module); } return(new FunctionTypeInformation(type_index, module, name, return_type, parameters)); }