Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you use SymLoadModuleEx to load a PDB file?

I'm trying to call SymLoadModuleEx to load the symbols from a PDB file and then use SymFromAddr to look up symbols from that PDB. However, I can't figure out what to pass for the parameters BaseOfDll and DllSize -- the documentation explicitly says that when loading a PDB file, these parameters can't be 0, and indeed attempting to pass 0 results in it failing with ERROR_INVALID_PARAMETER.

Here's what my code looks like:

SymSetOptions(SYMOPT_LOAD_LINES);
HANDLE hprocess = GetCurrentProcess();
if (!SymInitialize(hprocess, NULL, FALSE))
    die("SymInitialize");

if(SymLoadModuleEx(hprocess, NULL, "full path to some PDB file.pdb", NULL,
                   0,  // What to pass here?
                   0,  // What to pass here?
                   NULL, 0) == 0)
{
    die("SymLoadModuleEx");
}

How do you figure out what BaseOfDll and DllSize to pass in when loading a PDB file? The PDB file in question is the symbol file for a different program executable (not a DLL), and just for the sake of argument, assume that you don't have access to the original EXE from which the PDB was generated.

Alternatively, is there a better method of looking up the symbols corresponding to a given address from a PDB file?

like image 754
Adam Rosenfield Avatar asked Feb 01 '11 19:02

Adam Rosenfield


People also ask

How do I open a PDB file?

How to open a PDB file. You can use Microsoft Visual Studio (Windows) to load information from a PDB file created by that program. This allows you to debug the program the file is associated with. You can also use Microsoft's CVDump program (Windows) to read the information a Visual Studio PDB file contains.

How do I install PDB files?

Specify the modules that you want the debugger to load from the Symbol file (. pdb) locations when it starts. Select Load all modules, unless excluded (the default) to load all the symbols for all modules in the symbol file location, except modules you specifically exclude.

How do I load a PDB symbol?

Open Settings: Tools->Options -> Debugging -> Symbols and add directory, where your . PDB files are located. You can add custom path, like for each project, and also you can edit common path, where Visual Studio will save all .

How do I use PDB files?

The easiest way to use the PDB file is to let Visual Studio do the heavy lifting - either launch your program with Visual Studio's "Debug" command (F5 by default), or run the program and use the "Attach to Process" item in Visual Studio's Debug menu.


1 Answers

dbghelp.dll and the Sym* methods here make use of the Debug Interface Access (DIA) SDK.1
DIA itself is COM-based and much more flexible than what DbgHelp offers.

Specifically, to load a known PDB and lookup a symbol based on an address, you can do the following:

  1. CoCreate a DIA data source (see the "Example" section here).
  2. Use IDiaDataSource::loadDataFromPdb to load a specific PDB (DLL size and base address are not needed).
  3. Use IDiaDataSource::openSession to get the IDiaSession for your data source.
  4. Depending on if you have an absolute virtual address (VA) or relative virtual address (RVA), you can use findSymbolByVA or findSymbolByRVA, respectively, to get the IDiaSymbol associated with that address.
  5. Finally, you can use IDiaSymbol::get_name to get the function name containing the address you specified.

None of this requires the original image; only the PDB is required. Assuming you're using Visual Studio, the headers and libraries for DIA are available under (for example):
C:\Program Files (x86)\Microsoft Visual Studio 10.0\DIA SDK.

like image 190
Chris Schmich Avatar answered Oct 01 '22 22:10

Chris Schmich