4

I'm struggling with mapping addresses to their symbols for debugging purposes (getting the callstack). The MS dbghelp.dll can tell the symbol from an address (see SymFromAddr, MSDN). However, it doesn't work and I wonder how this could ever work, because addresses seem to change with every run of the program:

#include <iostream>
void Foo() {}

int _tmain(int argc, _TCHAR* argv[])
{
    const long unsigned int addr = reinterpret_cast<long unsigned int>(&Foo);
    std::cout << "Address: " << std::hex << addr << std::endl;
    return 0;
}

Output:

D:\dev\Sandbox\Debug>Sandbox.exe
Address: 901320
D:\dev\Sandbox\Debug>Sandbox.exe
Address: ce1320
D:\dev\Sandbox\Debug>Sandbox.exe
Address: 3a1320
D:\dev\Sandbox\Debug>Sandbox.exe
Address: 3f1320

How could a different program ever read address like from a stacktrace and map it to functions? This sounds like magic to me. I didn't find anything in the linked documentation which says I would have to subtract something from the address or whatever.

In my understanding since we overcome the real-mode every process has a virtual memory space anyway, so no need to roll the dice for a load address any more. I would understand uncertainties of absolute address in case of DLLs, but not the main executable.

Tried on Win7 with VS2008.

Borph
  • 842
  • 1
  • 6
  • 17
  • Several answers about this randomization, thanks! I was like WTF!!! How on earth is a stack dump any useful then with this super MS "security through obscurity"?! – Borph Apr 25 '13 at 12:35
  • Because all debuggers can deal with modules loaded at random offets. DLLs move all the time. – MSalters Apr 25 '13 at 12:54

4 Answers4

6

Address Space Layout Randomization

MSalters
  • 173,980
  • 10
  • 155
  • 350
3

Because your code is compiled to use Address Space Layout Randomization, which makes code less vulnerable to attacks from "StackOverflows".

If you really want to change that, there is a linker option for that.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
3

There is a security feature that randomises some addresses, so a potential attacker can not exploit a known fixed relative position of things.

Raedwald
  • 46,613
  • 43
  • 151
  • 237
2

It's ASLR in action, as others have already mentioned.

Looks like what you need to do is to specify the image base for your executable when calling SymLoadModuleEx(). It's the BaseOfDll parameter.

I don't know where exactly it's stored in the crash dump (if that's something that that other program has to work with), but a running program can obtain its own image base address using GetModuleHandle() (discussed here).

You probably want to save the names and base addresses of all the DLLs loaded into the process as well, not just those of the EXE itself.

Community
  • 1
  • 1
Alexey Frunze
  • 61,140
  • 12
  • 83
  • 180
  • Yes, thank you! I was subtracting the base address in the running code now, so the logfile has relative addresses, and it worked. GetModuleHandle() did the trick. In future I could do with all DLLs, but later. – Borph Apr 26 '13 at 07:54