コード例 #1
0
ファイル: SymbolHandler.cs プロジェクト: wisdark/Lunar
        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
ファイル: PdbFile.cs プロジェクト: ohio813/Bleak
        private async Task <Dictionary <string, IntPtr> > ParseSymbols(bool isWow64)
        {
            // Initialise a symbol handler for the local process

            var localProcessHandle = Process.GetCurrentProcess().SafeHandle;

            if (!Dbghelp.SymInitialize(localProcessHandle, IntPtr.Zero, false))
            {
                throw new PInvokeException("Failed to call SymInitialize");
            }

            // Load the symbol table for the PDB

            var pdbPathBuffer = Marshal.StringToHGlobalAnsi(await DownloadPdb(isWow64));

            var symbolTableBaseAddress = Dbghelp.SymLoadModuleEx(localProcessHandle, IntPtr.Zero, pdbPathBuffer, IntPtr.Zero, _module.BaseAddress, int.MaxValue, IntPtr.Zero, 0);

            if (symbolTableBaseAddress == IntPtr.Zero)
            {
                throw new PInvokeException("Failed to call SymLoadModuleEx");
            }

            // Initialise the callback used during SymEnumSymbols

            var symbolAddresses = new List <IntPtr>();

            var symbolNames = new List <string>();

            bool Callback(IntPtr symbolInfo, int symbolSize, IntPtr userContext)
            {
                symbolAddresses.Add((IntPtr)Marshal.PtrToStructure <SymbolInfo>(symbolInfo).Address);

                symbolNames.Add(Marshal.PtrToStringAnsi(symbolInfo + Marshal.SizeOf <SymbolInfo>()));

                return(true);
            }

            var callBackPointer = Marshal.GetFunctionPointerForDelegate(new Callbacks.EnumerateSymbolsCallback(Callback));

            // Enumerate the PDB symbols

            if (!Dbghelp.SymEnumSymbols(localProcessHandle, symbolTableBaseAddress, IntPtr.Zero, callBackPointer, IntPtr.Zero))
            {
                throw new PInvokeException("Failed to call SymEnumSymbols");
            }

            Dbghelp.SymUnloadModule64(localProcessHandle, symbolTableBaseAddress);

            var symbols = new Dictionary <string, IntPtr>();

            for (var symbolIndex = 0; symbolIndex < symbolNames.Count; symbolIndex++)
            {
                symbols.TryAdd(symbolNames[symbolIndex], symbolAddresses[symbolIndex]);
            }

            return(symbols);
        }
コード例 #3
0
ファイル: PdbFile.cs プロジェクト: zH4x/Bleak
        private static Dictionary <string, IntPtr> ParseSymbols(string pdbPath, IntPtr moduleAddress)
        {
            var symbols = new Dictionary <string, IntPtr>();

            // Initialise a symbol handler for the local process

            using var localProcess = Process.GetCurrentProcess();

            if (!Dbghelp.SymInitialize(localProcess.SafeHandle, IntPtr.Zero, false))
            {
                throw new Win32Exception($"Failed to call SymInitialize with error code {Marshal.GetLastWin32Error()}");
            }

            // Load the symbol table for the PDB

            var pdbPathBuffer = Encoding.Default.GetBytes(pdbPath);

            var symbolTableBaseAddress = Dbghelp.SymLoadModuleEx(localProcess.SafeHandle, IntPtr.Zero, ref pdbPathBuffer[0], IntPtr.Zero, moduleAddress, (int)new FileInfo(pdbPath).Length, IntPtr.Zero, 0);

            if (symbolTableBaseAddress == IntPtr.Zero)
            {
                throw new Win32Exception($"Failed to call SymLoadModuleEx with error code {Marshal.GetLastWin32Error()}");
            }

            // Initialise the callback used during the SymEnumSymbols call

            bool Callback(ref SymbolInfo symbolInfo, int symbolSize, IntPtr userContext)
            {
                var symbolNameBuffer = new byte[symbolInfo.NameLen];

                Unsafe.CopyBlockUnaligned(ref symbolNameBuffer[0], ref symbolInfo.Name, (uint)symbolNameBuffer.Length);

                symbols.TryAdd(Encoding.Default.GetString(symbolNameBuffer), (IntPtr)symbolInfo.Address);

                return(true);
            }

            var callbackDelegate = new Prototypes.EnumerateSymbolsCallback(Callback);

            // Enumerate the PDB symbols

            if (!Dbghelp.SymEnumSymbols(localProcess.SafeHandle, symbolTableBaseAddress, IntPtr.Zero, callbackDelegate, IntPtr.Zero))
            {
                throw new Win32Exception($"Failed to call SymEnumSymbols with error code {Marshal.GetLastWin32Error()}");
            }

            if (!Dbghelp.SymUnloadModule(localProcess.SafeHandle, symbolTableBaseAddress))
            {
                throw new Win32Exception($"Failed to call SymUnloadModule with error code {Marshal.GetLastWin32Error()}");
            }

            return(symbols);
        }
コード例 #4
0
ファイル: SymbolHandler.cs プロジェクト: FallenDev/Lunar-1
        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);
            }
        }
コード例 #5
0
        private Dictionary <string, IntPtr> ParseSymbols(string pdbPath, IntPtr moduleAddress)
        {
            // Initialise a symbol handler for the local process

            var localProcessHandle = Process.GetCurrentProcess().SafeHandle;

            if (!Dbghelp.SymInitialize(localProcessHandle, IntPtr.Zero, false))
            {
                throw new PInvokeException("Failed to call SymInitialize");
            }

            // Load the symbol table for the PDB

            var pdbPathBuffer = Marshal.StringToHGlobalAnsi(pdbPath);

            var symbolTableBaseAddress = Dbghelp.SymLoadModuleEx(localProcessHandle, IntPtr.Zero, pdbPathBuffer, IntPtr.Zero, moduleAddress, int.MaxValue, IntPtr.Zero, 0);

            if (symbolTableBaseAddress == IntPtr.Zero)
            {
                throw new PInvokeException("Failed to call SymLoadModuleEx");
            }

            // Initialise the callback used during the SymEnumSymbols call

            var symbols = new Dictionary <string, IntPtr>();

            bool Callback(IntPtr symbolInfo, int symbolSize, IntPtr userContext)
            {
                symbols.TryAdd(Marshal.PtrToStringAnsi(symbolInfo + Marshal.SizeOf <SymbolInfo>()), (IntPtr)Marshal.PtrToStructure <SymbolInfo>(symbolInfo).Address);

                return(true);
            }

            var callbackDelegate = new Prototypes.EnumerateSymbolsCallback(Callback);

            var callbackPointer = Marshal.GetFunctionPointerForDelegate(callbackDelegate);

            // Enumerate the PDB symbols

            if (!Dbghelp.SymEnumSymbols(localProcessHandle, symbolTableBaseAddress, IntPtr.Zero, callbackPointer, IntPtr.Zero))
            {
                throw new PInvokeException("Failed to call SymEnumSymbols");
            }

            Dbghelp.SymUnloadModule64(localProcessHandle, symbolTableBaseAddress);

            return(symbols);
        }
コード例 #6
0
ファイル: MiniDump.cs プロジェクト: Samojlov/OMSReader
        /// <summary>
        /// Writes user-mode minidump information to the specified file.
        /// </summary>
        /// <param name="fileToDump">A string to the file in which the information is to be written.</param>
        /// <param name="dumpType">The type of information to be generated.
        /// This parameter can be one or more of the values from the MINIDUMP_TYPE enumeration.</param>
        /// <returns>If the function succeeds, the return value is TRUE; otherwise, the return value is FALSE.
        /// To retrieve extended error information, call GetLastError. Note that the last error will be an HRESULT value.
        ///
        /// If the operation is canceled, the last error code is HRESULT_FROM_WIN32(ERROR_CANCELLED).</returns>
        /// <remarks>The MiniDumpCallback function receives extended minidump information from MiniDumpWriteDump.
        /// It also provides a way for the caller to determine the granularity of information written
        /// to the minidump file, as the callback function can filter the default information.
        ///
        /// MiniDumpWriteDump may not produce a valid stack trace for the calling thread.
        /// To work around this problem, you must capture the state of the calling thread before
        /// calling MiniDumpWriteDump and use it as the ExceptionParam parameter.
        /// One way to do this is to force an exception inside a __try/__except block and use the EXCEPTION_POINTERS
        /// information provided by GetExceptionInformation.
        /// Alternatively, you can call the function from a
        /// new worker thread and filter this worker thread from the dump.</remarks>
        public static bool MiniDumpToFile(string fileToDump, Dbghelp.MINIDUMP_TYPE dumpType)
        {
            if (Environment.OSVersion.Platform != PlatformID.Win32NT)
            {
                return(false);
            }
            bool result;

            using (FileStream fsToDump = File.Exists(fileToDump) ? File.Open(fileToDump, FileMode.Append) : File.Create(fileToDump))
            {
                Process thisProcess = Process.GetCurrentProcess();
                result = Dbghelp.MiniDumpWriteDump(thisProcess.Handle, thisProcess.Id,
                                                   fsToDump.SafeFileHandle.DangerousGetHandle(), dumpType,
                                                   IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
                fsToDump.Close();
            }
            return(result);
        }
コード例 #7
0
        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());
        }
コード例 #8
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);
            }
        }