Пример #1
0
        internal Symbol GetSymbol(string symbolName)
        {
            // Initialise a native symbol handler

            if (!Dbghelp.SymSetOptions(SymbolOptions.UndecorateName).HasFlag(SymbolOptions.UndecorateName))
            {
                throw new Win32Exception();
            }

            if (!Dbghelp.SymInitialize(Kernel32.GetCurrentProcess(), null, false))
            {
                throw new Win32Exception();
            }

            try
            {
                const int pseudoDllAddress = 0x1000;

                // Load the symbol file into the symbol handler

                var symbolFileSize = new FileInfo(_pdbFilePath).Length;

                var symbolTableAddress = Dbghelp.SymLoadModuleEx(Kernel32.GetCurrentProcess(), IntPtr.Zero, _pdbFilePath, null, pseudoDllAddress, (int)symbolFileSize, IntPtr.Zero, 0);

                if (symbolTableAddress == 0)
                {
                    throw new Win32Exception();
                }

                try
                {
                    // Initialise a buffer to store the symbol information

                    Span <byte> symbolInformationBytes = stackalloc byte[(Unsafe.SizeOf <SymbolInfo>() + sizeof(char) * Constants.MaxSymbolNameLength + sizeof(long) - 1) / sizeof(long)];

                    MemoryMarshal.Write(symbolInformationBytes, ref Unsafe.AsRef(new SymbolInfo(Unsafe.SizeOf <SymbolInfo>(), 0, Constants.MaxSymbolNameLength)));

                    // Retrieve the symbol information

                    if (!Dbghelp.SymFromName(Kernel32.GetCurrentProcess(), symbolName, out symbolInformationBytes[0]))
                    {
                        throw new Win32Exception();
                    }

                    var symbolInformation = MemoryMarshal.Read <SymbolInfo>(symbolInformationBytes);

                    return(new Symbol((int)(symbolInformation.Address - pseudoDllAddress)));
                }

                finally
                {
                    Dbghelp.SymUnloadModule64(Kernel32.GetCurrentProcess(), symbolTableAddress);
                }
            }

            finally
            {
                Dbghelp.SymCleanup(Kernel32.GetCurrentProcess());
            }
        }
Пример #2
0
        internal Symbol GetSymbol(string symbolName)
        {
            // Initialise a symbol handler

            Dbghelp.SymSetOptions(SymbolOptions.UndecorateName);

            var currentProcessHandle = Kernel32.GetCurrentProcess();

            if (!Dbghelp.SymInitialize(currentProcessHandle, null, false))
            {
                throw new Win32Exception();
            }

            try
            {
                const int pseudoDllAddress = 0x1000;

                // Load the symbol table for the PDB into the symbol handler

                var pdbSize = new FileInfo(_pdbFilePath).Length;

                var symbolTableAddress = Dbghelp.SymLoadModule(currentProcessHandle, IntPtr.Zero, _pdbFilePath, null, pseudoDllAddress, (int)pdbSize);

                if (symbolTableAddress == 0)
                {
                    throw new Win32Exception();
                }

                // Initialise an array to receive the symbol information

                var symbolInformationSize = (Unsafe.SizeOf <SymbolInfo>() + sizeof(char) * Constants.MaxSymbolNameLength + sizeof(long) - 1) / sizeof(long);

                Span <byte> symbolInformationBytes = stackalloc byte[symbolInformationSize];

                MemoryMarshal.Write(symbolInformationBytes, ref Unsafe.AsRef(new SymbolInfo(Unsafe.SizeOf <SymbolInfo>(), 0, Constants.MaxSymbolNameLength)));

                // Retrieve the symbol information

                if (!Dbghelp.SymFromName(currentProcessHandle, symbolName, out symbolInformationBytes[0]))
                {
                    throw new Win32Exception();
                }

                var symbolInformation = MemoryMarshal.Read <SymbolInfo>(symbolInformationBytes);

                return(new Symbol((int)(symbolInformation.Address - pseudoDllAddress)));
            }

            finally
            {
                Dbghelp.SymCleanup(currentProcessHandle);
            }
        }
        private static ImmutableDictionary <string, int> ParseSymbolOffsets(string pdbPath, IEnumerable <string> symbolNames)
        {
            var symbolOffsets = new Dictionary <string, int>();

            using var localProcess = System.Diagnostics.Process.GetCurrentProcess();

            // Initialise a symbol handler

            Dbghelp.SymSetOptions(SymbolOptions.UndecorateName | SymbolOptions.DeferredLoads);

            if (!Dbghelp.SymInitialize(localProcess.SafeHandle, null, false))
            {
                throw ExceptionBuilder.BuildWin32Exception("SymInitialize");
            }

            // Load the symbol table for the PDB

            const int pseudoDllBaseAddress = 0x1000;

            var pdbSize = new FileInfo(pdbPath).Length;

            var symbolTableAddress = Dbghelp.SymLoadModuleEx(localProcess.SafeHandle, IntPtr.Zero, pdbPath, null, pseudoDllBaseAddress, (int)pdbSize, IntPtr.Zero, 0);

            if (symbolTableAddress == 0)
            {
                throw ExceptionBuilder.BuildWin32Exception("SymLoadModuleEx");
            }

            // Initialise a buffer to receive the symbol information

            var symbolInfoBufferSize = (Unsafe.SizeOf <SymbolInfo>() + Constants.MaxSymbolName * sizeof(char) + sizeof(long) - 1) / sizeof(long);

            var symbolInfoBuffer = new byte[symbolInfoBufferSize];

            var symbolInfo = new SymbolInfo {
                SizeOfStruct = Unsafe.SizeOf <SymbolInfo>(), MaxNameLen = Constants.MaxSymbolName
            };

            MemoryMarshal.Write(symbolInfoBuffer, ref symbolInfo);

            // Retrieve the offsets of the symbols

            SymbolInfo RetrieveSymbolInformation(string symbolName)
            {
                if (!Dbghelp.SymFromName(localProcess.SafeHandle, symbolName, ref symbolInfoBuffer[0]))
                {
                    throw ExceptionBuilder.BuildWin32Exception("SymFromName");
                }

                return(MemoryMarshal.Read <SymbolInfo>(symbolInfoBuffer));
            }

            foreach (var symbolName in symbolNames)
            {
                var symbolInformation = RetrieveSymbolInformation(symbolName);

                symbolOffsets.Add(symbolName, (int)(symbolInformation.Address - pseudoDllBaseAddress));
            }

            if (!Dbghelp.SymCleanup(localProcess.SafeHandle))
            {
                throw ExceptionBuilder.BuildWin32Exception("SymCleanup");
            }

            return(symbolOffsets.ToImmutableDictionary());
        }
Пример #4
0
        private static IEnumerable <Symbol> ParseSymbols(string pdbFilePath, IEnumerable <string> symbolNames)
        {
            // Initialise a symbol handler

            Dbghelp.SymSetOptions(SymbolOptions.UndecorateName);

            using var currentProcessHandle = Kernel32.GetCurrentProcess();

            if (!Dbghelp.SymInitialize(currentProcessHandle, null, false))
            {
                throw new Win32Exception();
            }

            try
            {
                // Load the symbol table for the PDB into the symbol handler

                const int pseudoDllBaseAddress = 0x1000;

                var pdbSize = new FileInfo(pdbFilePath).Length;

                var symbolTableAddress = Dbghelp.SymLoadModuleEx(currentProcessHandle, IntPtr.Zero, pdbFilePath, null, pseudoDllBaseAddress, (int)pdbSize, IntPtr.Zero, 0);

                if (symbolTableAddress == 0)
                {
                    throw new Win32Exception();
                }

                var symbolInformationBlockSize = (Unsafe.SizeOf <SymbolInfo>() + Constants.MaxSymbolName * sizeof(char) + sizeof(long) - 1) / sizeof(long);

                int GetSymbolRva(string symbolName)
                {
                    // Initialise a block to receive the symbol information

                    Span <byte> symbolInformationBlock = stackalloc byte[symbolInformationBlockSize];

                    var symbolInformation = new SymbolInfo(Constants.MaxSymbolName);

                    MemoryMarshal.Write(symbolInformationBlock, ref symbolInformation);

                    // Retrieve the symbol information

                    if (!Dbghelp.SymFromName(currentProcessHandle, symbolName, out symbolInformationBlock[0]))
                    {
                        throw new Win32Exception();
                    }

                    // Calculate the relative virtual address of the symbol

                    symbolInformation = MemoryMarshal.Read <SymbolInfo>(symbolInformationBlock);

                    return((int)(symbolInformation.Address - pseudoDllBaseAddress));
                }

                foreach (var symbolName in symbolNames)
                {
                    var symbolRva = GetSymbolRva(symbolName);

                    yield return(new Symbol(symbolName, symbolRva));
                }
            }

            finally
            {
                Dbghelp.SymCleanup(currentProcessHandle);
            }
        }