user3766053
user3766053

Reputation: 41

How to find address of a function without using any pointer or &

I was asked in an interview to find out the address of a function without using any pointer or &. I couldn't answer his question but when i checked with him for the answer, he has given the following example in which function f1() calls function f2(). So, when function f2() gets invoked, the stack stores the return address which is nothing but the address of function f1(). In function f2() we can read the stack and then find out the address stored in stack which is of the function f1(). Can any one explain it in detail how we can read the stack from function f2() and find out the address of f1().

int main()
{
    f1();
    return 0;
}
void f1()
{
    f2();
}

Upvotes: 4

Views: 578

Answers (1)

merlin2011
merlin2011

Reputation: 75555

With the caveat that this method is utterly unportable as T.C. mentions, and the additional caveat that it almost certainly will not work if optimizations are turned on, you can read the return address from the stack by reading off the end of a buffer, as in the example below.

int main()
{
    f1();
    return 0;
}
void f1()
{
    f2();
}
void f2() {
    char buf[4];
    printf("%p\n", *(void**)(buf + 8));
}

Note that the number 8 above will vary based on operating system, architecture, and compiler padding, so you will most likely have to try a variety of different numbers to make it work. The choice of 8 for the example assumes padding up to a 4-byte boundary, and 4-byte pointers on a 32-bit system.

You also have to make sure optimizations are turned off.

The reason why this works at all is because the structure of the stack immediately after a function call looks kind of like this.

|Return Address|
|Saved Frame Pointer|
|Local Variables|

Observe that the return address is at a higher address than the Local Variables. That is the reason that reading past the end of a buffer will allow you to potentially read the return address.

The reason why this breaks with optimizations is that compiler might decide to inline one or both functions, or realize one of them is doing nothing at all and optimize the function call away entirely, which blows aside the assumptions about the stack.

Upvotes: 4

Related Questions