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}"); } }
private bool SymInitialize(IntPtr hProcess) { // 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, false)); }
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 the just the address in HEX #if DEBUG return($"0x{address:x} (SymFromAddr failed with 0x{Marshal.GetLastWin32Error():x})"); #else return($"0x{address:x}"); #endif }