1

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.

bathtub
  • 426
  • 3
  • 15
  • 1
    How are you going to deal with the fact that the functions all have different signatures? What's your map going to look like? – Joseph Mansfield Mar 26 '13 at 22:31
  • Even if it is technically safe, it's hardly type-safe – at least your example isn't. You're going to end up with a lot of weird type lookup and void pointer casting. It's certainly better to do this with some kind of class hierarchy; after all you're in C++ anyway and performance concerns are unlikely to matter if you're reading from a file! – leftaroundabout Mar 26 '13 at 22:33
  • I would write the functions, and I would try to maintain a consistency with the signatures double (*)(double, double) – bathtub Mar 26 '13 at 22:38

3 Answers3

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.

j_mcnally
  • 6,928
  • 2
  • 31
  • 46
2

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.

Johannes Overmann
  • 4,914
  • 22
  • 38
  • 1
    I think the point is that he wants the addresses to be the same *between* invocations of the program. – Joseph Mansfield Mar 26 '13 at 22:31
  • So these addresses could change between compiles. I would need to generate a new file every compile? That would be easy to accomplish, I just want to be clear. – bathtub Mar 26 '13 at 22:32
  • Not compile, per run. – j_mcnally Mar 26 '13 at 22:39
  • The edited would work, but it wouldn't make sense because I wouldn't put all of those conditions in if I'm just going to be putting all of those function addresses in memory anyway – bathtub Mar 26 '13 at 22:40
1

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);
Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • I was thinking about this. I could write the functions in such a way that they always appeared in the same order. What I just need to use the `sizeof` on the signature of the functions to get the function intervals? – bathtub Mar 26 '13 at 22:36
  • @bathtub, `sizeof` will only give you the size of the pointer, not of the code block itself. – Mark Ransom Mar 26 '13 at 22:37
  • If I did this index thing statically in the code itself, I wouldn't have to worry about reading from a file and indexing the functions anyway. – bathtub Mar 26 '13 at 22:43
  • @bathtub, the only thing that knows the location of the code is the code. I don't think you'll be able to get around putting something into the code. – Mark Ransom Mar 26 '13 at 22:50
  • In response to your previous edit, this is what I want my code to end up doing. It looks like I'm going to need to code the functions I'm using in directly. Thank you for your help – bathtub Mar 26 '13 at 23:35