2

I've heard that it is possible to override / hijack / hack a function's implementation by linking against the object file the function resides in with another one that you authored. I've been playing around, and it seems like I can only get this to work in one situation. However, I was wondering if it's possible to achieve this result (shown below) in other situations besides the one described.

Compiler used: TDM-GCC 4.9.2

OS: Windows 8 64-bit

The following describes the situation where hijacking is "successful":

Here's a sample source called sample.cpp

#include <iostream>

int returnOne();

int main()
{
    std::cout << "returnOne() returns " << returnOne();

    return 0;
}

Compilation:

g++ -c sample.cpp -o sample.o

After checking the object file with nm.exe, my function's mangled name is: __Z9returnOnev

So, off into another source hack.cpp:

extern "C" int _Z9returnOnev()
{
    return 5;  //rather than return 1
}

Compilation:

g++ -c hack.cpp -o hack.o

Now I "recreate" the executable with the hack.o file:

g++ -Wl,--allow-multiple-definition hack.o sample.o -o sample.exe

When ran, sample.exe produces:

returnOne() returns 5

So the hijack was successful.

Now, if at any point do I provide the implementation of returnOne() in the original source, this technique no longer works. As in:

#include <iostream>

int returnOne();

int main()
{
    std::cout << "returnOne() returns " << returnOne();

    return 0;
}

int returnOne()
{
    return 1;
}

It compiles fine, but when invoked, the function uses the original implementation every time.

So, I'm wondering if it's possible to "hijack" a function's implementation in this fashion if it's implementation is already defined in the original source, or is only possible if only it's prototype is defined?


Edit (7/15/15):
I also compiled w/o optimizations, as in:

g++ -Wl,--allow-multiple-definition,-O0 hack.o sample.o -o sample.exe

However, the problem persists.


Edit2 (7/15/15):
Ok, I cleaned, then compiled and linked everything w/ the -O0 switch:

g++ -O0 -c sample.cpp -o sample.o

g++ -O0 -c hack.cpp -o hack.o

g++ -Wl,--allow-multiple-definition,-O0 hack.o sample.o -o sample.exe

It's still returning 1.

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Paul Rich
  • 209
  • 2
  • 10

1 Answers1

1

No, it is not possible to override the function implementation in that case.

What your compiler usually does when it compiles a source file is that it creates a table with function signatures (identifier + parameter types) and function addresses. When you have a function invocation in your code, the compiler tries to call the function with this signature. This is why you need a linker - the #include statement actually copies all the declarations into your code before compiling so that you have the right signatures. The linker then adds the address of the callable function. If you have a function definition in your main.cpp, there is no need for the compiler/linker to look up a definition anywhere else.

J. D.
  • 113
  • 13