Example #1
0
        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;
        }
Example #2
0
        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);
        }
Example #3
0
        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}");
        }
Example #4
0
    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;
    }
Example #5
0
    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;
    }
Example #6
0
        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());
            }
        }
Example #7
0
        /// <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);
        }
Example #8
0
 /// <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");
     }
 }
Example #9
0
        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;
        }
Example #10
0
 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();
     }
 }
Example #11
0
 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));
        }
Example #13
0
        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;
        }
Example #14
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);
        }
Example #15
0
        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;
        }
Example #16
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]);
            }
        }
Example #17
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;
        }
Example #18
0
        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]);
        }
Example #19
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);
        }
Example #20
0
        /// <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);
        }
Example #21
0
        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;
        }
Example #22
0
        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);
        }
Example #23
0
        /// <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());
                }
            }
        }
Example #24
0
        /// <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;
        }
Example #25
0
        /// <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);
        }
Example #26
0
        /// <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");
        }
Example #27
0
        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);
        }
Example #28
0
        /// <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);
        }
Example #29
0
        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;
        }
Example #30
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);
        }
Example #31
0
    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);
    }
Example #32
0
        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);
        }
Example #33
0
 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();
 }
Example #34
0
        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();
        }
Example #35
0
        /// <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;
        }
Example #37
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);
        }
Example #38
0
        /// <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);
            }
        }
Example #39
0
        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);
        }
Example #40
0
        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);
            }
        }
Example #41
0
        /// <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();
        }
Example #44
0
 private bool IsBitField(IDiaSymbol sym)
 {
     return (LocationTypeEnum)sym.locationType == LocationTypeEnum.LocIsBitField;
 }
Example #45
0
        /// <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;
        }
Example #46
0
        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;
        }
Example #47
0
 /// <summary>
 /// Gets the type identifier.
 /// </summary>
 /// <param name="type">The type.</param>
 private uint GetTypeId(IDiaSymbol type)
 {
     return type.symIndexId;
 }
Example #48
0
        /// <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");
        }
Example #49
0
 // 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;
 }
Example #50
0
        /// <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();
        }
Example #51
0
 public CArr TranslateArr(IDiaSymbol sym)
 {
     CType next = Translate(sym.type);
     int len = (int)sym.count;           // it should be safe
     return new CArr(next, len);
 }
Example #52
0
        /// <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);
            }
        }
Example #53
0
        /// <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));
            }
        }
Example #54
0
 public CTerm TranslateBaseType(IDiaSymbol sym)
 {
     return WithAttr(_TranslateBaseType(sym), sym);
 }
Example #55
0
 public CBits TranslateBitField(IDiaSymbol sym)
 {
     return new CBits(TranslateBaseType(sym.type), (int)sym.length);
 }
Example #56
0
        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());
            }
        }
Example #57
0
        // 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;
        }
Example #58
0
        /// <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));
            }
        }
Example #59
0
 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");
     }
 }
Example #60
0
        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;
        }