Beispiel #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));
            }
        }
Beispiel #2
0
        public async Task <SSymbolNameAndDisplacement> LookupSymbolName(ulong pointer)
        {
            try {
                SModule module = await this.debuggerEngine.GetModuleForAddress(pointer);

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

                if (session != null)
                {
                    // We have a DIA session; use it.
                    Dia2Lib.IDiaSymbol symbol;
                    ulong rva = pointer - module.BaseAddress;
                    session.findSymbolByRVA((uint)rva, Dia2Lib.SymTagEnum.SymTagNull, out symbol);

                    // Blocks don't have names.  Walk up to the nearest non-block parent.
                    while ((Dia2Lib.SymTagEnum)symbol.symTag == Dia2Lib.SymTagEnum.SymTagBlock)
                    {
                        symbol = symbol.lexicalParent;
                    }

                    SymTagEnum symTag = (SymTagEnum)symbol.symTag;
                    string     name;
                    if (symTag == SymTagEnum.SymTagPublicSymbol || symTag == SymTagEnum.SymTagThunk)
                    {
                        // Public symbols have decorated names that need to be undecorated (see dbghelp!diaFillSymbolInfo).
                        symbol.get_undecoratedNameEx(0x1000, out name);
                    }
                    else
                    {
                        name = symbol.name;
                    }

                    return(new SSymbolNameAndDisplacement()
                    {
                        Module = module.Name,
                        Name = name,
                        Displacement = (ulong)(rva - symbol.relativeVirtualAddress)
                    });
                }
                else
                {
                    return(await this.debuggerEngine.LookupSymbolName(pointer));
                }
            } catch {
                throw new DebuggerException(String.Format("Invalid symbol address: 0x{0:x8}", pointer));
            }
        }
Beispiel #3
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);
        }