Why does the address of a function change with every run?

烂漫一生 提交于 2020-12-25 04:29:19

问题


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.


回答1:


Address Space Layout Randomization




回答2:


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.




回答3:


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




回答4:


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.



来源:https://stackoverflow.com/questions/16214502/why-does-the-address-of-a-function-change-with-every-run

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!