예제 #1
0
        public async Task <SSymbolResult> LookupGlobalSymbol(string moduleName, string symbolName)
        {
            SSymbolResult result = new SSymbolResult();

            Dia2Lib.IDiaSession session = await this.debuggerEngine.DiaLoader.LoadDiaSession(moduleName);

            if (session != null)
            {
                // We have a DIA session, use that.
                try {
                    Dia2Lib.IDiaEnumSymbols symbols;
                    session.globalScope.findChildren(Dia2Lib.SymTagEnum.SymTagNull, symbolName, (uint)DiaHelpers.NameSearchOptions.nsCaseSensitive, out symbols);
                    foreach (Dia2Lib.IDiaSymbol diaSymbol in symbols)
                    {
                        if (((DiaHelpers.LocationType)diaSymbol.locationType) == DiaHelpers.LocationType.LocIsTLS)
                        {
                            // For TLS-relative symbols, fall back to the debugger.
                            return(await this.debuggerEngine.LookupGlobalSymbol(moduleName, symbolName));
                        }

                        result.Module  = moduleName;
                        result.Pointer = (await this.debuggerEngine.GetModuleForName(moduleName)).BaseAddress + diaSymbol.relativeVirtualAddress;
                        result.Type    = DiaHelpers.GetTypeName(diaSymbol.type);
                        return(result);
                    }
                } catch { }
                throw new DebuggerException(String.Format("Invalid symbol: {0}!{1}", moduleName, symbolName));
            }
            else
            {
                return(await this.debuggerEngine.LookupGlobalSymbol(moduleName, symbolName));
            }
        }
예제 #2
0
        public async Task <IEnumerable <SNamedSymbol> > GetSymbolsInStackFrame(ulong instructionAddress, ulong stackAddress, ulong frameAddress)
        {
            List <SNamedSymbol> results = new List <SNamedSymbol>();
            SModule             module  = await this.debuggerEngine.GetModuleForAddress(instructionAddress);

            Dia2Lib.IDiaSession session = await this.debuggerEngine.DiaLoader.LoadDiaSession(module.Name);

            if (session == null)
            {
                throw new DebuggerException("Loading stack frame symbols directly from the debugger is not supported.");
            }

            Dia2Lib.IDiaSymbol symbol;
            uint rva = (uint)(instructionAddress - module.BaseAddress);

            try {
                session.findSymbolByRVA(rva, Dia2Lib.SymTagEnum.SymTagNull, out symbol);
            } catch {
                throw new DebuggerException(string.Format("Invalid symbol address: 0x:{0:x8}", instructionAddress));
            }

            if ((SymTagEnum)symbol.symTag == SymTagEnum.SymTagFunction || (SymTagEnum)symbol.symTag == SymTagEnum.SymTagBlock)
            {
                do
                {
                    IDiaEnumSymbols symbols = null;
                    symbol.findChildrenExByRVA(SymTagEnum.SymTagData, null, (uint)DiaHelpers.NameSearchOptions.nsNone, rva, out symbols);

                    foreach (IDiaSymbol localSymbol in symbols)
                    {
                        DiaHelpers.LocationType location = (DiaHelpers.LocationType)localSymbol.locationType;
                        if (location == DiaHelpers.LocationType.LocIsRegRel)
                        {
                            // Check if the offset is from the stack address or frame address.
                            DiaHelpers.CV_HREG_e register = (DiaHelpers.CV_HREG_e)localSymbol.registerId;
                            ulong relativeAddress         = 0;
                            switch (register)
                            {
                            case DiaHelpers.CV_HREG_e.CV_AMD64_RSP:
                            case DiaHelpers.CV_HREG_e.CV_AMD64_ESP: // Also CV_REG_ESP
                                relativeAddress = stackAddress;
                                break;

                            case DiaHelpers.CV_HREG_e.CV_AMD64_RBP:
                            case DiaHelpers.CV_HREG_e.CV_AMD64_EBP: // Also CV_REG_EBP
                            case DiaHelpers.CV_HREG_e.CV_ALLREG_VFRAME:
                                relativeAddress = frameAddress;
                                break;

                            default:
                                // Relative to a register that's not the frame pointer or stack pointer.  We don't have support for this yet.
                                continue;
                            }

                            int pointerAdjustment = 0;
                            if (localSymbol.name == "this")
                            {
                                pointerAdjustment = symbol.type.thisAdjust;
                            }

                            results.Add(new SNamedSymbol()
                            {
                                Symbol = new SSymbolResult()
                                {
                                    Module  = module.Name,
                                    Pointer = (ulong)((long)relativeAddress + localSymbol.offset),
                                    Type    = DiaHelpers.GetTypeName(localSymbol.type, pointerAdjustment)
                                },
                                Name = localSymbol.name
                            });
                        }
                    }

                    // If the symbol wasn't a function (e.g. it was a block) keep going until we reach containing function.
                } while ((SymTagEnum)symbol.symTag != SymTagEnum.SymTagFunction && ((symbol = symbol.lexicalParent) != null));
            }

            return(results);
        }
예제 #3
0
        private async Task <Type> LoadTypeFromDiaSession(IDiaSession diaSession, string module, string typename, DiaHelpers.NameSearchOptions options)
        {
            IDiaEnumSymbols symbols;

            diaSession.findChildren(diaSession.globalScope, SymTagEnum.SymTagNull, typename, (uint)options, out symbols);
            foreach (IDiaSymbol iterationSymbol in symbols)
            {
                IDiaSymbol symbol = iterationSymbol;
                while ((SymTagEnum)symbol.symTag == SymTagEnum.SymTagTypedef)
                {
                    symbol = symbol.type;
                }
                SymTagEnum symTag = (SymTagEnum)symbol.symTag;
                if (symTag == SymTagEnum.SymTagUDT || symTag == SymTagEnum.SymTagBaseType || symTag == SymTagEnum.SymTagEnum)
                {
                    // Get the fields for this class.
                    IDiaEnumSymbols dataSymbols;
                    symbol.findChildren(SymTagEnum.SymTagData, null, 0, out dataSymbols);
                    uint typeSize = (uint)symbol.length;
                    Dictionary <string, SField> fields    = new Dictionary <string, SField>();
                    Dictionary <string, ulong>  constants = new Dictionary <string, ulong>();

                    foreach (IDiaSymbol dataSymbol in dataSymbols)
                    {
                        DiaHelpers.LocationType location = (DiaHelpers.LocationType)dataSymbol.locationType;
                        if (location == DiaHelpers.LocationType.LocIsBitField)
                        {
                            byte bitOffset = (byte)dataSymbol.bitPosition;
                            byte bitCount  = (byte)dataSymbol.length;
                            fields.Add(dataSymbol.name, new SField((uint)dataSymbol.offset, (uint)dataSymbol.type.length, module, DiaHelpers.GetTypeName(dataSymbol.type), bitOffset, bitCount));
                        }
                        else if (location == DiaHelpers.LocationType.LocIsThisRel)
                        {
                            fields.Add(dataSymbol.name, new SField((uint)dataSymbol.offset, (uint)dataSymbol.type.length, module, DiaHelpers.GetTypeName(dataSymbol.type), 0, 0));
                        }
                        else if (location == DiaHelpers.LocationType.LocIsConstant)
                        {
                            try {
                                constants.Add(dataSymbol.name, (ulong)dataSymbol.value);
                            } catch {
                                // If the cast failed, just ignore the constant for now.
                            }
                        }
                    }

                    IDiaEnumSymbols enumSymbols;
                    symbol.findChildren(SymTagEnum.SymTagEnum, null, 0, out enumSymbols);
                    List <string> names = new List <string>();
                    foreach (IDiaSymbol enumSymbol in enumSymbols)
                    {
                        if (enumSymbol.name.IndexOf("<unnamed-enum") == 0)
                        {
                            // Anonymous enum.  Include the constants in the outer type.
                            IDiaEnumSymbols anonymousEnumDataSymbols;
                            enumSymbol.findChildren(SymTagEnum.SymTagData, null, 0, out anonymousEnumDataSymbols);
                            foreach (IDiaSymbol dataSymbol in anonymousEnumDataSymbols)
                            {
                                DiaHelpers.LocationType location = (DiaHelpers.LocationType)dataSymbol.locationType;
                                if (location == DiaHelpers.LocationType.LocIsConstant)
                                {
                                    try {
                                        constants.Add(dataSymbol.name, (ulong)dataSymbol.value);
                                    } catch {
                                        // If the cast failed, just ignore the constant for now.
                                    }
                                }
                            }
                        }
                    }

                    // Get the base types.
                    List <SBaseType> baseTypes = new List <SBaseType>();
                    IDiaEnumSymbols  baseClassSymbols;
                    symbol.findChildren(SymTagEnum.SymTagBaseClass, null, 0, out baseClassSymbols);
                    foreach (IDiaSymbol baseClassSymbol in baseClassSymbols)
                    {
                        string baseTypename = DiaHelpers.GetTypeName(baseClassSymbol.type);
                        Type   baseType;
                        try {
                            baseType = await this.LoadType(module, baseTypename);
                        } catch (DebuggerException) {
                            // Sometimes types will refer to a base type that doesn't resolve; just ignore that type.
                            baseType = null;
                        }
                        if (baseType != null)
                        {
                            baseTypes.Add(new SBaseType(baseType, baseClassSymbol.offset));
                        }
                        else
                        {
                            System.Diagnostics.Debug.WriteLine("Unable to retrieve base type: {0}", baseTypename);
                        }
                    }

                    // Construct the type.
                    Type type = new Type(module, typename, typeSize, symTag == SymTagEnum.SymTagEnum, fields, constants, baseTypes);
                    return(type);
                }
            }

            return(null);
        }