Does the address of a function change per runtime [duplicate]

北城以北 提交于 2020-01-16 01:01:15

问题


I'm writing something in c++ where I want to read text from a file that indicates correlations between Strings and Functions I have declared in my program. For example the file could read:

sin:sin
PI:getPi
+:add

I wanted the code to take this and create a hash table or vector of String and Function Pointer data structures. Unfortunately, I realize that code would not be able to find the name of functions at run-time, so I want to be able to put the addresses of these functions in the file. But this system would, of course, not work if the addresses of the functions were different every time the program ran or compiled. Enlightenment, or alternative solution to any of these problems would be great.


回答1:


You can safely take addresses of functions (function pointers) at compile time. It is the image loaders task to relocate your function addresses when you start your program. You do not have to worry about the addresses of functions changing.

What you must not do of course is printing the address of a function to stdout and put this address as a numeric value into your program. That would suffer from the problem you describe.

To get the address of C++ function sin() just use &sin in your code.

To get the address of C++ function by string you will have to have code like:

if (function_name == "sin") return &sin;
else if (function_name == "add") return &add;
else ...

or a suitable data structure with string/function pointer pairs.

The point is: Do not store numeric function addresses in a file. Take and use function addresses in your program directly. The numeric function address should not matter to your program in any way.




回答2:


maybe?

Is your system using ASLR?

Adress Space Layout Randomization, its a technique used by modern systems to prevent exploits from executing private or privledged function from executing ROP attacks.

Basically it randomizes the location of functions in memory. This is defeatable if you know the location of the base image, because everything is still relative. You'll often see notation like 0xDEADBEEF+13.

See ASLR for more info.




回答3:


You cannot rely on addresses staying fixed, because the OS may employ address space layout randomization to reduce the effectiveness of exploits.

You might be able to rely on the relative addresses of functions, if they're all within the same linked binary. Choose one to be the base, and subtract it from all the others.

Naturally this would all be off if you recompile and/or relink. I'd try to find a different method.

One such method would be to use integer indexes for each function, and keep a table of which index corresponds to which function. It introduces another layer of indirection but would be much more robust.

Edit: If you don't want to create a static table, you can let the code build one up at program initialization by using static objects and constructors.

struct FunctionTable
{
    typedef std::unordered_map<std::string, void *> table;
    static table& get()
    {
        static table the_table;
        return the_table;
    }
    FunctionTable(std::string name, void * func)
    {
        get().insert(name, func);
    }
};

double getPi()
{
    return 3.14159;
}
static FunctionTable ft_getPi = FunctionTable("getPi", getPi);


来源:https://stackoverflow.com/questions/15648582/does-the-address-of-a-function-change-per-runtime

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