public CFunc TranslateFunc(IDiaSymbol sym) { CType retType = Translate(sym.type); CFunc res = new CFunc(retType, TranslateCallConv(sym.callingConvention)); IDiaEnumSymbols syms; sym.findChildren(SymTagEnum.SymTagFunctionArgType, null, 0, out syms); if (syms.count == 0) { res.Add(PrimTypes.VOID); return res; } else if (syms.count == 1) { IDiaSymbol only = syms.Item(0).type; if ((SymTagEnum)only.symTag == SymTagEnum.SymTagBaseType && (BaseTypeEnum)only.baseType == BaseTypeEnum.btNoType) { return res; } } foreach (IDiaSymbol argSym in syms) { CType argType = Translate(argSym.type); res.Add(argType); } return res; }
void FuncCollectSym(IDiaSymbol Detail, uint tag, String ModName, String BlockName) { IDiaEnumSymbols EnumSymbols = null; IDiaSymbol Symbol = null; List<string> Args = new List<string>(); uint childrenFetched = 0; ForegroundColor = ConsoleColor.Green; if (Detail == null || string.IsNullOrWhiteSpace(Detail.name)) return; //WriteLine($"{Detail.undecoratedName} ({Detail.name}) Length: {Detail.length} RVA: {Detail.targetRelativeVirtualAddress} VA: {Detail.targetVirtualAddress}"); Detail.findChildren(SymTagEnum.SymTagNull, null, 0, out EnumSymbols); do { //EnumSymbols.Next(1, out Symbol, out childrenFetched); //if (Symbol == null || string.IsNullOrEmpty(Symbol.name)) // continue; Symbol = Detail; if (Symbol.type != null) Args.Add(Symbol.type.name); //else // WriteLine($"{Symbol.undecoratedName} ({Symbol.name}) @ {Symbol.virtualAddress:X} Length: {Symbol.length} "); } while (childrenFetched == 1); }
void CollectCompileDetails(IDiaSymbol detail, String ModName, String BlockName) { string Language = string.Empty, Platform = string.Empty; var lang = detail.language; var plat = detail.platform; switch (lang) { case 0: Language = "C"; break; case 1: Language = "C++"; break; case 2: Language = "Linked DLL/Import"; break; case 3: Language = "Fortran"; break; case 4: Language = "MASM"; break; case 5: Language = "Pascal"; break; case 6: Language = "ILASM"; break; case 7: Language = "MSIL"; break; case 8: Language = "HLSL"; break; case 9: Language = "Resource Data"; break; case 10: Language = "PGO Data (performance guided opt)"; break; case 11: Language = "Managed C#"; break; default: Language = "Other / Not hookable"; break; } if (plat > 2 && plat < 8) Platform = "x86"; if (plat == 0xD0) Platform = "x64"; else Platform = "Unsupported"; WriteLine($"Language: {Language} / {Platform}"); }
public static IDiaSymbol FindSymbol(String symName, IDiaSymbol parent, SymTagEnum symTag) { IDiaEnumSymbols e; parent.findChildren(symTag, symName, (uint)(NameSearchOptions.nsfCaseSensitive), out e); IDiaSymbol s; uint celt; if (e == null || e.count == 0) return null; e.Next(1, out s, out celt); if (e.count > 1) { for (int i = 1; i < e.count; i++) { IDiaSymbol s2; e.Next(1, out s2, out celt); // Diasym reader returns multiple symbols with same RVA in some cases. Issue the warning only // if the returned symbols actually differ. if (s.virtualAddress != s2.virtualAddress) { Shell.Error("Symbol " + symName + " has " + e.count + " matches. Taking first."); break; } } } return s; }
public static IDiaSymbol FindClassSymbol(String name, IDiaSymbol sym, SymTagEnum tag) { IDiaSymbol res = null; //Console.WriteLine("Looking for " + name + " in " + sym.name); res = Util.FindSymbol(name, sym, tag); if (res == null) { IDiaEnumSymbols e; sym.findChildren( SymTagEnum.SymTagBaseClass, null, (uint)NameSearchOptions.nsNone, out e); if (e == null || e.count == 0) return null; for (int i = 0; i < e.count && res == null; i++) { UInt32 celt; IDiaSymbol s; e.Next(1, out s, out celt); res = FindClassSymbol(name, s.type, tag); } } return res; }
public CType Translate(IDiaSymbol sym) { switch ((SymTagEnum)sym.symTag) { case SymTagEnum.SymTagBaseType: return TranslateBaseType(sym); case SymTagEnum.SymTagPointerType: return TranslatePtr(sym); case SymTagEnum.SymTagArrayType: return TranslateArr(sym); case SymTagEnum.SymTagFunctionType: return TranslateFunc(sym); case SymTagEnum.SymTagUDT: return PdbSymbol.IsUnnamed(sym) ? TranslateUnnamedUdt(sym) : TranslateTypeRef(sym); case SymTagEnum.SymTagEnum: return PdbSymbol.IsUnnamed(sym) ? TranslateEnum(sym) : TranslateTypeRef(sym); default: throw new NotImplementedException(((SymTagEnum)sym.symTag).ToString()); } }
/// <summary>Creates a new <see cref="Symbol"/> around a COM <see cref="IDiaSymbol"/> implementation.</summary> /// <param name="symbol">The symbol to wrap, or null. This method takes ownership of the <see cref="IDiaSymbol"/> COM RCW.</param> /// <returns>If <paramref name="symbol"/> is null, null; otherwise a <see cref="Symbol"/> wrapper around <paramref name="symbol"/>.</returns> public static Symbol Create(IDiaSymbol symbol) { // The handling (or not) of null in callers appears to be inconsistent. We may want // to just have people not bother with the null check at all here eventually. if (symbol == null) { return null; } return new Symbol(symbol); }
/// <summary> /// Gets the code of the specified type in original language. /// </summary> /// <param name="type">The type.</param> public static string GetTypeString(IDiaSymbol type) { switch ((CV_CFL_LANG)type.language) { case CV_CFL_LANG.CV_CFL_C: case CV_CFL_LANG.CV_CFL_CXX: return CppType.GetTypeString(type); default: throw new Exception("Unsupported language"); } }
public CEnum TranslateEnum(IDiaSymbol sym) { IDiaEnumSymbols symbols; sym.findChildren(SymTagEnum.SymTagNull, null, 0, out symbols); CEnum res = new CEnum(); foreach (IDiaSymbol constant in symbols) { res.Add(constant.name, (uint)constant.value); } return res; }
public static Offset FromDiaSymbol(IDiaSymbol sym) { switch ((LocationTypeEnum)sym.locationType) { case LocationTypeEnum.LocIsThisRel: return new Offset(sym.offset); case LocationTypeEnum.LocIsBitField: return new Offset(sym.offset, (int)sym.bitPosition); default: throw new ArgumentException(); } }
public static Offset BottomOffsetFromDiaSymbol(IDiaSymbol symbol) { Offset obj = Offset.FromDiaSymbol(symbol); switch ((LocationTypeEnum)symbol.locationType) { case LocationTypeEnum.LocIsThisRel: obj._bytes += (int)symbol.type.length; break; case LocationTypeEnum.LocIsBitField: obj._bits += (int)symbol.length; obj.Normalize(); break; } return obj; }
internal static IDiaSymbol TryGetDiaSymbol(IDiaSymbol symbol, SymTagEnum symTag, string name, out string error) { symbol.findChildren(symTag, name, 1, out IDiaEnumSymbols enumSymbols); if (enumSymbols.count != 1) { error = $"TryGetDiaSymbols() enumSymbols.count {enumSymbols.count} != 1"; ReleaseComObject(enumSymbols); return(null); } error = null; return(enumSymbols.Item(0u)); }
public PointerType(IDiaSymbol sym) { symbol = sym; constType = sym.constType != 0; length = sym.length; lexicalParent = sym.lexicalParent; lexicalParentId = sym.lexicalParentId; reference = sym.reference != 0; symIndexId = sym.symIndexId; symTag = sym.symTag; type = sym.type; typeId = sym.typeId; unalignedType = sym.unalignedType != 0; volatileType = sym.volatileType != 0; }
/// <summary> /// Gets the type from global space. /// </summary> /// <param name="typeName">Name of the type.</param> private IDiaSymbol GetTypeFromGlobalSpace(string typeName) { IDiaSymbol type = globalScope.GetChild(typeName, SymTagEnum.UDT); if (type == null) { type = globalScope.GetChild(typeName, SymTagEnum.Enum); } if (type == null) { type = globalScope.GetChild(typeName); } return(type); }
public VTable(IDiaSymbol sym) { symbol = sym; classParent = sym.classParent; classParentId = sym.classParentId; constType = sym.constType != 0; lexicalParent = sym.lexicalParent; lexicalParentId = sym.lexicalParentId; symIndexId = sym.symIndexId; symTag = sym.symTag; type = sym.type; typeId = sym.typeId; unalignedType = sym.unalignedType != 0; volatileType = sym.volatileType != 0; }
/// <summary> /// Converts <see cref="IDiaEnumSymbols"/> container to <see cref="IEnumerable{IDiaSymbol}"/>. /// </summary> /// <param name="container">The container.</param> public static IEnumerable <IDiaSymbol> Enum(this IDiaEnumSymbols container) { IDiaSymbol[] tempSymbols = new IDiaSymbol[1]; container.Reset(); while (true) { uint count; container.Next((uint)tempSymbols.Length, tempSymbols, out count); if (count == 0) { break; } yield return(tempSymbols[0]); } }
public Block(IDiaSymbol sym) { symbol = sym; addressOffset = sym.addressOffset; addressSection = sym.addressSection; length = sym.length; lexicalParent = sym.lexicalParent; lexicalParentId = sym.lexicalParentId; locationType = sym.locationType; name = sym.name; relativeVirtualAddress = sym.relativeVirtualAddress; symIndexId = sym.symIndexId; symTag = sym.symTag; virtualAddress = sym.virtualAddress; }
public CustomType(IDiaSymbol sym) { symbol = sym; oemId = sym.oemId; oemSymbolId = sym.oemSymbolId; symIndexId = sym.symIndexId; symTag = sym.symTag; type = sym.type; typeId = sym.typeId; uint size = 0; uint count = 0; sym.get_types(size, out count, out types[0]); }
/// <summary> /// Gets all types defined in the symbol. /// </summary> public IEnumerable <Symbol> GetAllTypes() { // Get all types defined in the symbol var diaGlobalTypes = session.globalScope.GetChildren(SymTagEnum.SymTagUDT).ToList(); diaGlobalTypes.AddRange(session.globalScope.GetChildren(SymTagEnum.SymTagEnum)); diaGlobalTypes.AddRange(session.globalScope.GetChildren(SymTagEnum.SymTagBaseType)); diaGlobalTypes.AddRange(session.globalScope.GetChildren(SymTagEnum.SymTagPointerType)); diaGlobalTypes.AddRange(session.globalScope.GetChildren(SymTagEnum.SymTagArrayType)); // Create symbols from types var convertedTypes = diaGlobalTypes.Select(s => new Symbol(this, s)).ToList(); var resultingTypes = convertedTypes.Where(t => t.Tag == SymTagEnum.SymTagUDT || t.Tag == SymTagEnum.SymTagEnum).OrderBy(s => s.Name).ToArray(); var cacheTypes = convertedTypes.OrderBy(s => s.Tag).ThenBy(s => s.Name).ToArray(); // Remove duplicate symbols by searching for the by name var symbols = new List <Symbol>(); var previousName = ""; foreach (var s in resultingTypes) { if (s.Name != previousName) { IDiaSymbol ss = session.globalScope.GetChild(s.Name, s.Tag); if (ss != null) { symbols.Add(GetSymbol(ss)); } else { symbols.Add(GetSymbol(s.DiaSymbol)); } previousName = s.Name; } } // Cache symbols inside the module foreach (var s in cacheTypes) { var symbolCache = GetSymbol(s.DiaSymbol); } return(symbols); }
/// <summary> /// Initializes a new instance of the <see cref="DiaModule"/> class. /// </summary> /// <param name="pdbPath">The PDB path.</param> /// <param name="module">The module.</param> public DiaModule(string pdbPath, Module module) { Module = module; dia = new DiaSource(); dia.loadDataFromPdb(pdbPath); dia.openSession(out session); globalScope = session.globalScope; typeAllFields = new DictionaryCache<uint, List<Tuple<string, uint, int>>>(GetTypeAllFields); typeFields = new DictionaryCache<uint, List<Tuple<string, uint, int>>>(GetTypeFields); basicTypes = SimpleCache.Create(() => { var types = new Dictionary<string, IDiaSymbol>(); var basicTypes = globalScope.GetChildren(SymTagEnum.SymTagBaseType); foreach (var type in basicTypes) { try { string typeString = TypeToString.GetTypeString(type); if (!types.ContainsKey(typeString)) { types.Add(typeString, type); } } catch (Exception) { } } return types; }); symbolNamesByAddress = new DictionaryCache<uint, Tuple<string, ulong>>((distance) => { IDiaSymbol symbol; int displacement; string name; session.findSymbolByRVAEx(distance, SymTagEnum.SymTagNull, out symbol, out displacement); symbol.get_undecoratedNameEx(0 | 0x8000 | 0x1000, out name); return Tuple.Create(name, (ulong)displacement); }); session.loadAddress = module.Address; enumTypeNames = new DictionaryCache<uint, Dictionary<ulong, string>>(GetEnumName); }
void IDiaSession.findChildren(IDiaSymbol parent, SymTagEnum symTag, string name, uint compareFlags, out IDiaEnumSymbols ppResult) { dynamic typ = null; if (!Dia3.StructCache.ContainsKey(name)) { var json = SymAPI.TypeDef(name, CV); var converter = new Newtonsoft.Json.Converters.ExpandoObjectConverter(); var obj = JsonConvert.DeserializeObject <List <ExpandoObject> >(json.Result, converter); // we access just the first object back Dia3.StructCache.TryAdd(name, obj.First()); } Dia3.StructCache.TryGetValue(name, out typ); ppResult = new EnumSymbols(CV, EnumSymType.Sym, typ); return; }
public static Offset BottomOffsetFromDiaSymbol(IDiaSymbol symbol) { Offset obj = Offset.FromDiaSymbol(symbol); switch ((LocationTypeEnum)symbol.locationType) { case LocationTypeEnum.LocIsThisRel: obj._bytes += (int)symbol.type.length; break; case LocationTypeEnum.LocIsBitField: obj._bits += (int)symbol.length; obj.Normalize(); break; } return(obj); }
/// <summary> /// Gets all base classes (including base classes of base classes). /// </summary> /// <param name="symbol">The symbol.</param> public static IEnumerable <IDiaSymbol> GetAllBaseClasses(this IDiaSymbol symbol) { List <IDiaSymbol> unprocessed = symbol.GetBaseClasses().ToList(); while (unprocessed.Count > 0) { List <IDiaSymbol> symbols = unprocessed; unprocessed = new List <IDiaSymbol>(); foreach (var s in symbols) { yield return(s); unprocessed.AddRange(s.GetBaseClasses()); } } }
/// <summary> /// Update the method symbol cache. /// </summary> private static void UpdateMethodSymbolCache(string methodName, IDiaSymbol methodSymbol, Dictionary <string, IDiaSymbol> methodSymbolCache) { Debug.Assert(!string.IsNullOrEmpty(methodName), "MethodName cannot be empty."); Debug.Assert(methodSymbol != null, "Method symbol cannot be null."); Debug.Assert(methodSymbolCache != null, "Method symbol cache cannot be null."); // #827589, In case a type has overloaded methods, then there could be a method already in the // cache which should be disposed. IDiaSymbol oldSymbol; if (methodSymbolCache.TryGetValue(methodName, out oldSymbol)) { ReleaseComObject(ref oldSymbol); } methodSymbolCache[methodName] = methodSymbol; }
/// <summary> /// Initializes a new instance of the <see cref="DiaModule"/> class. /// </summary> /// <param name="pdbPath">The PDB path.</param> /// <param name="module">The module.</param> public DiaModule(string pdbPath, Module module) { Module = module; dia = new DiaSource(); dia.loadDataFromPdb(pdbPath); dia.openSession(out session); globalScope = session.globalScope; typeAllFields = new DictionaryCache <uint, List <Tuple <string, uint, int> > >(GetTypeAllFields); typeFields = new DictionaryCache <uint, List <Tuple <string, uint, int> > >(GetTypeFields); basicTypes = SimpleCache.Create(() => { var types = new Dictionary <string, IDiaSymbol>(); var basicTypes = globalScope.GetChildren(SymTagEnum.SymTagBaseType); foreach (var type in basicTypes) { try { string typeString = TypeToString.GetTypeString(type); if (!types.ContainsKey(typeString)) { types.Add(typeString, type); } } catch (Exception) { } } return(types); }); symbolNamesByAddress = new DictionaryCache <uint, Tuple <string, ulong> >((distance) => { IDiaSymbol symbol; int displacement; string name; session.findSymbolByRVAEx(distance, SymTagEnum.SymTagNull, out symbol, out displacement); symbol.get_undecoratedNameEx(0 | 0x8000 | 0x1000, out name); return(Tuple.Create(name, (ulong)displacement)); }); session.loadAddress = module.Address; enumTypeNames = new DictionaryCache <uint, Dictionary <ulong, string> >(GetEnumName); }
/// <summary> /// Gets the source file name and line for the specified stack frame. /// </summary> /// <param name="address">The address.</param> /// <param name="sourceFileName">Name of the source file.</param> /// <param name="sourceFileLine">The source file line.</param> /// <param name="displacement">The displacement.</param> /// <exception cref="System.Exception">Address not found</exception> /// <exception cref="Exception">Address not found</exception> public void GetSourceFileNameAndLine(uint address, out string sourceFileName, out uint sourceFileLine, out ulong displacement) { IDiaSymbol function = session.findSymbolByRVA(address, SymTagEnum.Function); IDiaEnumLineNumbers lineNumbers = session.findLinesByRVA(address, (uint)function.length); foreach (IDiaLineNumber lineNumber in lineNumbers.Enum()) { if (address >= lineNumber.relativeVirtualAddress) { sourceFileName = lineNumber.sourceFile.fileName; sourceFileLine = lineNumber.lineNumber; displacement = address - lineNumber.relativeVirtualAddress; return; } } throw new Exception("Address not found"); }
public static ComPtr <IDiaSymbol> GetSymbol(this IDiaSymbol symbol, SymTagEnum symTag, string name, Predicate <IDiaSymbol> filter = null) { ComPtr <IDiaSymbol> result = new ComPtr <IDiaSymbol>(); symbol.findChildren(symTag, name, 1, out IDiaEnumSymbols enumSymbols); using (ComPtr.Create(enumSymbols)) { int n = enumSymbols.count; if (n == 0) { Debug.Fail("Symbol '" + name + "' was not found."); throw new ArgumentException(); } try { for (int i = 0; i < n; ++i) { using (ComPtr <T> item = ComPtr.Create(enumSymbols.Item((uint)i))) { if (filter == null || filter(item.Object)) { if (result.Object == null) { result = item.Detach(); } else { Debug.Fail("Found more than one symbol named '" + name + "' and matching the filter."); throw new ArgumentException(); } } } } } catch { result.Dispose(); throw; } } return(result); }
/// <summary> /// Initializes this instance of the <see cref="DiaModule"/> class. /// </summary> /// <param name="diaSession">The DIA session.</param> /// <param name="module">The module.</param> private void Initialize(IDiaSession diaSession, Module module) { Module = module; session = diaSession; globalScope = session.globalScope; typeAllFields = new DictionaryCache <uint, List <Tuple <string, uint, int> > >(GetTypeAllFields); typeFields = new DictionaryCache <uint, List <Tuple <string, uint, int> > >(GetTypeFields); basicTypes = SimpleCache.Create(() => { var types = new Dictionary <string, IDiaSymbol>(); var basicTypes = globalScope.GetChildren(SymTagEnum.BaseType); foreach (var type in basicTypes) { try { string typeString = TypeToString.GetTypeString(type); if (!types.ContainsKey(typeString)) { types.Add(typeString, type); } } catch (Exception) { } } return(types); }); symbolNamesByAddress = new DictionaryCache <uint, Tuple <string, ulong> >((distance) => { IDiaSymbol symbol; int displacement; string name; session.findSymbolByRVAEx(distance, SymTagEnum.Null, out symbol, out displacement); name = symbol.get_undecoratedNameEx(UndecoratedNameOptions.NameOnly | UndecoratedNameOptions.NoEscu); return(Tuple.Create(name, (ulong)displacement)); }); session.loadAddress = module.Address; enumTypeNames = new DictionaryCache <uint, Dictionary <ulong, string> >(GetEnumName); }
public ArrayType(IDiaSymbol sym) { symbol = sym; arrayIndexType = sym.arrayIndexType; arrayIndexTypeId = sym.arrayIndexTypeId; constType = sym.constType != 0; count = sym.count; length = sym.length; lexicalParent = sym.lexicalParent; lexicalParentId = sym.lexicalParentId; rank = sym.rank; symIndexId = sym.symIndexId; symTag = sym.symTag; type = sym.type; typeId = sym.typeId; unalignedType = sym.unalignedType != 0; volatileType = sym.volatileType != 0; }
public DiaSymbol FindClassSymbol(String name, SymTagEnum tag) { DiaSymbol res = null; IDiaSymbol sym = Util.FindClassSymbol(name, m_symbol, tag); if (sym != null) { if ((SymTagEnum)sym.symTag == SymTagEnum.SymTagData) { res = new DiaDataSymbol(sym); } else { res = new DiaSymbol(sym); } } return(res); }
public static bool TryGetSymbolForAddress(IntPtr address, out IDiaSymbol symbol) { session.globalScope.findChildrenExByRVA( SymTagEnum.SymTagPublicSymbol, name: null, compareFlags: 0, rva: (uint)(address.ToInt64() - module.BaseAddress.ToInt64()), out IDiaEnumSymbols symbols ); foreach (IDiaSymbol result in symbols) { symbol = result; return(true); } symbol = null; return(false); }
private CTerm WithAttr(CTerm type, IDiaSymbol sym) { SortedSet <TypeAttr> attrs = new SortedSet <TypeAttr>(); if (sym.constType == 1) { attrs.Add(TypeAttrs.Const); } if (sym.volatileType == 1) { attrs.Add(TypeAttrs.Volatile); } if (sym.unalignedType == 1) { attrs.Add(TypeAttrs.Unaligned); } return(attrs.Any() ? new CAttrTerm(type, attrs) : type); }
public void ProcessChildren(IDiaSymbol symbol) { symbol.findChildren(SymTagEnum.SymTagNull, null, 0, out var children); if (children == null) { return; } foreach (IDiaSymbol child in children) { if (child.symTag == (uint)SymTagEnum.SymTagFunction) { var functionInfo = ProcessFunction(child); if (functionInfo != null) { AddFunction(functionInfo); if (functionInfo.IsPure) { IsAbstract = true; } } } else { var memberInfo = ProcessMember(child); if (memberInfo != null) { AddMember(memberInfo); } } } // Sort members by offset, recompute padding. // Sorting is usually not needed (for data fields), but sometimes base class order is wrong. Members.Sort(SymbolMemberInfo.CompareOffsets); for (int i = 0; i < Members.Count; ++i) { var member = Members[i]; member.AlignWithPrevious = ComputeOffsetCollision(i); member.PaddingBefore = ComputePadding(i); member.BitPaddingAfter = ComputeBitPadding(i); } EndPadding = ComputeEndPadding(); }
private void LoadEnumEntries(Rfl.Enum type, IDiaSymbol dia_type) { IDiaEnumSymbols enum_entries; dia_type.findChildren(SymTagEnum.SymTagData, null, 0, out enum_entries); m_Logger.WriteSection("Reflecting Enum - {" + type.FullName.String + "}"); foreach (IDiaSymbol symbol in enum_entries) { // The values of an enumeration are stored as the smallest type possible (sbyte, short, int) // so need casting to int (casting to uint gives out of range exceptions). int value = System.Convert.ToInt32(symbol.value); type.AddEntry(symbol.name, value); m_Logger.Write(symbol.name + " = " + value.ToString()); } m_Logger.EndSection(); }
/// <summary> /// Looks through the configured symbol paths to find a PDB symbol /// file matching specified name. /// </summary> /// <param name="pdbFileName">Name of the PDB file.</param> /// <returns>The pdb file path or null the pdf file wasn't found.</returns> public string FindPdbFile(string pdbFileName) { foreach (string symbolPath in this.SymbolPaths) { string filePath = Path.Combine(symbolPath, pdbFileName); if (File.Exists(filePath)) { DiaSourceClass dia = new DiaSourceClass(); dia.loadDataFromPdb(filePath); IDiaSession session; dia.openSession(out session); IDiaSymbol symbol = session.globalScope; return(FindPdbFile(pdbFileName, symbol.guid, (int)symbol.age)); } } return(null); }
public FunctionType(IDiaSymbol sym) { symbol = sym; callingConvention = sym.callingConvention; classParent = sym.classParent; classParentId = sym.classParentId; constType = sym.constType != 0; count = sym.count; lexicalParent = sym.lexicalParent; lexicalParentId = sym.lexicalParentId; objectPointerType = sym.objectPointerType; symIndexId = sym.symIndexId; symTag = sym.symTag; thisAdjust = sym.thisAdjust; type = sym.type; typeId = sym.typeId; unalignedType = sym.unalignedType != 0; volatileType = sym.volatileType != 0; }
/// <summary> /// Gets the element type (if symbol is array or pointer). /// </summary> protected override Symbol GetElementType() { if (Tag == CodeTypeTag.Pointer || Tag == CodeTypeTag.Array) { IDiaSymbol type = symbol.type; if (type != null) { Symbol result = DiaModule.GetSymbol(type); if (Tag == CodeTypeTag.Pointer) { result.PointerType = this; } return(result); } } return(null); }
/// <summary> /// Initializes a new instance of the <see cref="DiaSymbolField"/> class. /// </summary> /// <param name="parentType">The parent type.</param> /// <param name="symbol">The DIA symbol.</param> public DiaSymbolField(DiaSymbol parentType, IDiaSymbol symbol) : base(parentType) { this.symbol = symbol; Name = symbol.name; LocationType = symbol.locationType; DataKind = symbol.dataKind; Offset = symbol.offset; Value = symbol.value; ulong size = symbol.length; if (size > int.MaxValue) { throw new ArgumentException("Symbol size is unexpected"); } Size = (int)size; if (LocationType == LocationType.BitField) { BitSize = Size; } else { BitSize = Size * 8; } uint bitPosition = symbol.bitPosition; if (bitPosition > int.MaxValue) { throw new ArgumentException("Symbol bit position is unexpected"); } BitPosition = (int)bitPosition; IDiaSymbol type = symbol.type; if (type != null) { Type = ((DiaModule)Module).GetSymbol(type); } }
private FunctionRecord ProcessChild(IDiaSymbol child) { Symbol c = new Symbol(child); Members member = new Members(c); Symbol grandChild = c.InspectType(); Symbol greatGrandChild = grandChild.InspectType(); if (c.Name == "OptimalZeroingAttribute") { Debug.WriteLine(""); } if ("RecordType" == c.Name) { Debug.WriteLine(""); } // I'm specifically looking for the unnamed types here since this is the best opportunity // the record where they are and queue them up for processing if (grandChild.Name != null && grandChild.Kind != SymbolKind.Enum && grandChild.Name.StartsWith("<unnamed-")) { _todoSymbolList.Add(grandChild); } if (greatGrandChild.RootSymbol != null && greatGrandChild.Kind != SymbolKind.Enum && greatGrandChild.Name != null && greatGrandChild.Name.StartsWith("<unnamed-")) { _todoSymbolList.Add(greatGrandChild); } // create a FunctionRecord helper FunctionRecord fr = new FunctionRecord(c, member, grandChild, _pointerSize); LocationType location = (LocationType)member.locationType; // bitfields need special processing so look for those first if (location == LocationType.LocIsBitField) { ProcessBitfield(fr, member, grandChild, c); } else { ProcessTheRest(fr, member, grandChild, c); } return(fr); }
private void ReadName(IDiaSymbol symbol, StringBuilder sb) { Contract.Requires(symbol != null); Contract.Requires(sb != null); if (string.IsNullOrEmpty(symbol.name)) { return; } if (!string.IsNullOrEmpty(symbol.undecoratedName)) { // If symbol.name equals symbol.undecoratedName there is some extra stuff which can't get undecorated. Try to fix it. if (symbol.name == symbol.undecoratedName) { var name = symbol.name; if (name.StartsWith("@ILT+")) { var start = name.IndexOf('('); if (start != -1) { name = name.Substring(start + 1, name.Length - 1 - start - 1); } } else if (!name.StartsWith("?")) { name = '?' + name; } sb.Append(NativeMethods.UndecorateSymbolName(name).TrimStart('?', ' ')); } else { sb.Append(symbol.undecoratedName); } } else { sb.Append(symbol.name); } }
/// <summary> /// Gets the field type id and offset of the specified type. /// </summary> /// <param name="type">The type.</param> /// <param name="fieldName">Name of the field.</param> private Tuple <uint, int> GetTypeFieldTypeAndOffset(IDiaSymbol type, string fieldName) { if (type.symTag == SymTagEnum.PointerType) { type = type.type; } var fields = typeAllFields[type.symIndexId]; foreach (var field in fields) { if (field.Item1 != fieldName) { continue; } return(Tuple.Create(field.Item2, field.Item3)); } throw new Exception("Field not found"); }
public PublicSymbol(IDiaSymbol sym) { symbol = sym; addressOffset = sym.addressOffset; addressSection = sym.addressSection; code = sym.code != 0; function = sym.function != 0; length = sym.length; lexicalParent = sym.lexicalParent; lexicalParentId = sym.lexicalParentId; locationType = sym.locationType; managed = sym.managed != 0; msil = sym.msil != 0; name = sym.name; symIndexId = sym.symIndexId; relativeVirtualAddress = sym.relativeVirtualAddress; symTag = sym.symTag; undecoratedName = sym.undecoratedName; sym.get_undecoratedNameEx(0, out undecoratedNameEx); }
/// <summary> /// Initializes a new instance of the ReflectedFunctionSignature class /// </summary> /// <param name="symbol"></param> public ReflectedFunctionSignature(IDiaSymbol symbol) { // Determine calling convention switch (symbol.callingConvention) { case 0x00: CallingConvention = CallingConvention.Cdecl; break; case 0x04: CallingConvention = CallingConvention.FastCall; break; case 0x07: CallingConvention = CallingConvention.StdCall; break; case 0x09: CallingConvention = CallingConvention.Winapi; break; case 0x0b: CallingConvention = CallingConvention.ThisCall; break; } // Get return type ReturnType = new ReflectedTypeRef(symbol.type); // Get parameters List<ReflectedTypeRef> paramList = new List<ReflectedTypeRef>(); IDiaSymbol objectPtrType = symbol.objectPointerType; if (objectPtrType != null) { paramList.Add(new ReflectedTypeRef(objectPtrType)); HasThis = true; } //int paramCount = (int)symbol.count; foreach (IDiaSymbol arg in symbol.EnumerateChildren(SymTagEnum.SymTagFunctionArgType)) { paramList.Add(new ReflectedTypeRef(arg.type)); } parameters = paramList.ToArray(); }
private bool IsBitField(IDiaSymbol sym) { return (LocationTypeEnum)sym.locationType == LocationTypeEnum.LocIsBitField; }
/// <summary> /// Gets the symbol from the cache or adds new entry in the cache if symbol wasn't previously found. /// </summary> /// <param name="symbol">The symbol.</param> internal Symbol GetSymbol(IDiaSymbol symbol) { if (symbol == null) return null; Symbol s; uint symbolId = symbol.symIndexId; if (!symbolById.TryGetValue(symbolId, out s)) { s = new Symbol(this, symbol); lock (this) { Symbol previousSymbol = null; symbolById.TryAdd(symbolId, s); if (s.Tag != SymTagEnum.SymTagExe) if (!symbolByName.TryGetValue(s.Name, out previousSymbol)) { symbolByName.TryAdd(s.Name, s); } else { previousSymbol.LinkSymbols(s); } } s.InitializeCache(); } return s; }
private CTerm WithAttr(CTerm type, IDiaSymbol sym) { SortedSet<TypeAttr> attrs = new SortedSet<TypeAttr>(); if (sym.constType == 1) { attrs.Add(TypeAttrs.Const); } if (sym.volatileType == 1) { attrs.Add(TypeAttrs.Volatile); } if (sym.unalignedType == 1) { attrs.Add(TypeAttrs.Unaligned); } return attrs.Any() ? new CAttrTerm(type, attrs) : type; }
/// <summary> /// Gets the type identifier. /// </summary> /// <param name="type">The type.</param> private uint GetTypeId(IDiaSymbol type) { return type.symIndexId; }
/// <summary> /// Gets the field type id and offset of the specified type. /// </summary> /// <param name="type">The type.</param> /// <param name="fieldName">Name of the field.</param> private Tuple<uint, int> GetTypeFieldTypeAndOffset(IDiaSymbol type, string fieldName) { if ((SymTagEnum)type.symTag == SymTagEnum.SymTagPointerType) type = type.type; var fields = typeAllFields[type.symIndexId]; foreach (var field in fields) { if (field.Item1 != fieldName) continue; return Tuple.Create(field.Item2, field.Item3); } throw new Exception("Field not found"); }
// TODO FIX NOW REMOVE internal IEnumerable<string> FindChildrenNames(IDiaSymbol scope, string name = null, NameSearchOptions searchOptions = NameSearchOptions.nsNone) { var syms = FindChildren(m_session.globalScope, name, searchOptions); var ret = new List<string>(); foreach (var sym in syms) ret.Add(sym.name); return ret; }
/// <summary> /// Gets the names of all fields of the specified type. /// </summary> /// <param name="type">The type.</param> private string[] GetTypeAllFieldNames(IDiaSymbol type) { if ((SymTagEnum)type.symTag == SymTagEnum.SymTagPointerType) type = type.type; var fields = typeAllFields[type.symIndexId]; return fields.Select(t => t.Item1).ToArray(); }
public CArr TranslateArr(IDiaSymbol sym) { CType next = Translate(sym.type); int len = (int)sym.count; // it should be safe return new CArr(next, len); }
/// <summary> /// Resolves the symbol address. /// </summary> /// <param name="process">The process.</param> /// <param name="symbol">The symbol.</param> /// <param name="frameContext">The frame context.</param> private static ulong ResolveAddress(Process process, IDiaSymbol symbol, ThreadContext frameContext) { ulong address; switch ((LocationType)symbol.locationType) { case LocationType.RegRel: switch ((CV_HREG_e)symbol.registerId) { case CV_HREG_e.CV_AMD64_ESP: case CV_HREG_e.CV_AMD64_RSP: address = frameContext.StackPointer; break; case CV_HREG_e.CV_AMD64_RIP: //case CV_HREG_e.CV_REG_EIP: address = frameContext.InstructionPointer; break; case CV_HREG_e.CV_AMD64_RBP: case CV_HREG_e.CV_AMD64_EBP: address = frameContext.FramePointer; break; case CV_HREG_e.CV_ALLREG_VFRAME: if (process.EffectiveProcessorType == ImageFileMachine.AMD64) address = frameContext.StackPointer; else address = frameContext.FramePointer; break; default: throw new Exception("Unknown register id" + (CV_HREG_e)symbol.registerId); } address += (ulong)symbol.offset; return address; case LocationType.Static: return symbol.virtualAddress; default: throw new Exception("Unknown location type " + (LocationType)symbol.locationType); } }
/// <summary> /// Gets the stack frame locals. /// </summary> /// <param name="block">The block.</param> /// <param name="variables">The variables.</param> /// <param name="frame">The frame.</param> /// <param name="module">The module.</param> /// <param name="arguments">if set to <c>true</c> only arguments will be returned.</param> private static void GetFrameLocals(IDiaSymbol block, List<Variable> variables, StackFrame frame, Module module, bool arguments) { foreach (var symbol in block.GetChildren(SymTagEnum.SymTagData)) { DataKind symbolDataKind = (DataKind)symbol.dataKind; if (arguments && symbolDataKind != DataKind.Param) { continue; } CodeType codeType = module.TypesById[symbol.typeId]; ulong address = ResolveAddress(module.Process, symbol, frame.FrameContext); var variableName = symbol.name; variables.Add(Variable.CreateNoCast(codeType, address, variableName, variableName)); } }
public CTerm TranslateBaseType(IDiaSymbol sym) { return WithAttr(_TranslateBaseType(sym), sym); }
public CBits TranslateBitField(IDiaSymbol sym) { return new CBits(TranslateBaseType(sym.type), (int)sym.length); }
public CPrefix _TranslateBaseType(IDiaSymbol sym) { int size = (int)sym.length; switch ((BaseTypeEnum)sym.baseType) { case BaseTypeEnum.btVoid: return PrimTypes.VOID; case BaseTypeEnum.btChar: return PrimTypes.CHAR; case BaseTypeEnum.btWChar: return PrimTypes.WCHAR; case BaseTypeEnum.btInt: return IntTypePairs.SelectBySize(size).Signed; case BaseTypeEnum.btUInt: return IntTypePairs.SelectBySize(size).Unsigned; // the design logic of Dia2Lib is // eh.. MS guys must be brain f****d at that time. case BaseTypeEnum.btLong: return PrimTypes.LONG; case BaseTypeEnum.btULong: return PrimTypes.ULONG; case BaseTypeEnum.btFloat: return sym.length == 4 ? PrimTypes.FLOAT : PrimTypes.FLOAT; case BaseTypeEnum.btHresult: return new CTypeRef("HRESULT"); default: throw new NotImplementedException(((BaseTypeEnum)sym.baseType).ToString()); } }
// TODO FIX NOW REMOVE private IEnumerable<IDiaSymbol> FindChildren(IDiaSymbol scope, string name = null, NameSearchOptions searchOptions = NameSearchOptions.nsNone) { IDiaEnumSymbols symEnum; m_session.findChildren(scope, SymTagEnum.SymTagNull, name, (uint)searchOptions, out symEnum); uint fetchCount; var ret = new List<IDiaSymbol>(); for (; ; ) { IDiaSymbol sym; symEnum.Next(1, out sym, out fetchCount); if (fetchCount == 0) break; SymTagEnum symTag = (SymTagEnum)sym.symTag; Debug.WriteLine("Got " + sym.name + " symTag " + symTag + " token " + sym.token.ToString("x")); if (symTag == SymTagEnum.SymTagFunction) { if (sym.token != 0) { var sourceLocation = SourceLocationForManagedCode(sym.token, 0); if (sourceLocation != null) Debug.WriteLine("Got Line " + sourceLocation.LineNumber + " file " + sourceLocation.SourceFile); } } if (symTag == SymTagEnum.SymTagCompiland) { var children = (List<IDiaSymbol>)FindChildren(sym, name, searchOptions); Debug.WriteLine("got " + children.Count + " children"); } ret.Add(sym); } return ret; }
/// <summary> /// Gets all fields from the type (including base classes). /// </summary> /// <param name="type">The type.</param> /// <param name="typeFields">The type fields.</param> /// <param name="offset">The offset.</param> private void GetTypeAllFields(IDiaSymbol type, List<Tuple<string, uint, int>> typeFields, int offset = 0) { // Get all fields from base classes var bases = type.GetBaseClasses(); foreach (var b in bases) { GetTypeAllFields(b, typeFields, offset + b.offset); } // Get type fields var fields = type.GetChildren(SymTagEnum.SymTagData); foreach (var field in fields) { if ((DataKind)field.dataKind == DataKind.StaticMember) continue; typeFields.Add(Tuple.Create(field.name, field.typeId, offset + field.offset)); } }
public CType TranslateUnnamedUdt(IDiaSymbol sym) { switch ((UdtKindEnum)sym.udtKind) { case UdtKindEnum.UdtStruct: return TranslateStruct(sym); case UdtKindEnum.UdtUnion: return TranslateUnion(sym); default: return new CPrim("NotImpl_Udt"); } }
public CUnion TranslateUnion(IDiaSymbol sym) { IDiaEnumSymbols symbols; sym.findChildren(SymTagEnum.SymTagData, null, 0, out symbols); CUnion res = new CUnion(); foreach (IDiaSymbol subSym in symbols) { Offset thisOffset = Offset.FromDiaSymbol(subSym); if (!thisOffset.IsEqualTo(Offset.Zero)) { symbols.Reset(); return TranslateUnion2(symbols); } string name = subSym.name; CType type = TranslateMember(subSym); res.Add(type, name); } return res; }