Ejemplo n.º 1
0
        public void AddModule(string filename, ulong baseOfDll, int sizeOfDll)
        {
            var baseAddress = NativeDbgHelp.SymLoadModule64(_hProcess, IntPtr.Zero, filename, null, baseOfDll, (uint)sizeOfDll);

            if (baseAddress == 0)
            {
                // should work if the same module is added more than once
                if (Marshal.GetLastWin32Error() == ERROR_SUCCESS)
                {
                    return;
                }

                Console.WriteLine($"SymLoadModule64 failed for {filename}");
            }
        }
Ejemplo n.º 2
0
        private bool SymInitialize(IntPtr hProcess, bool loadModules = false)
        {
            // read https://docs.microsoft.com/en-us/windows/win32/api/dbghelp/nf-dbghelp-symsetoptions for more details
            // maybe SYMOPT_NO_PROMPTS and SYMOPT_FAIL_CRITICAL_ERRORS could be used
            NativeDbgHelp.SymSetOptions(
                NativeDbgHelp.SYMOPT_DEFERRED_LOADS |   // performance optimization
                NativeDbgHelp.SYMOPT_UNDNAME            // C++ names are not mangled
                );

            // https://docs.microsoft.com/en-us/windows/win32/api/dbghelp/nf-dbghelp-syminitialize
            // search path for symbols:
            //   - The current working directory of the application
            //   - The _NT_SYMBOL_PATH environment variable
            //   - The _NT_ALTERNATE_SYMBOL_PATH environment variable
            //
            // passing false as last parameter means that we will need to call SymLoadModule64
            // each time a module is loaded in the process
            return(NativeDbgHelp.SymInitialize(hProcess, null, loadModules));
        }
Ejemplo n.º 3
0
        private string GetNativeMethodName(ulong address)
        {
            var symbol = new NativeDbgHelp.SYMBOL_INFO();

            symbol.MaxNameLen   = 1024;
            symbol.SizeOfStruct = (uint)Marshal.SizeOf(symbol) - 1024;   // char buffer is not counted
            // the ANSI version of SymFromAddr is called so each character is 1 byte long

            if (NativeDbgHelp.SymFromAddr(_hProcess, address, out var displacement, ref symbol))
            {
                var buffer = new StringBuilder(symbol.Name.Length);

                // remove weird "$##" at the end of some symbols
                var pos = symbol.Name.LastIndexOf("$##");
                if (pos == -1)
                {
                    buffer.Append(symbol.Name);
                }
                else
                {
                    buffer.Append(symbol.Name, 0, pos);
                }

                // add offset if any
                if (displacement != 0)
                {
                    buffer.Append($"+0x{displacement}");
                }

                return(buffer.ToString());
            }

            // default value is just the address in HEX
#if DEBUG
            return($"0x{address:x}  (SymFromAddr failed with 0x{Marshal.GetLastWin32Error():x})");
#else
            return($"0x{address:x}");
#endif
        }