Taha Rehman Siddiqui
Taha Rehman Siddiqui

Reputation: 2533

c++ function addresses coming out different in attached profiler library than in the subject code base

I have written an instrument-er in C++ to log entry and exit functions by hooking on enter and exit calls. It is working as supposed to with a legacy code base. However on hooking with a project that I downloaded from git, function addresses that I save in an extern variable in the subject code, they are coming out different in the profiler library. That is messing up the function pointer comparison between hooked and saved functions.

Function address in subject code main file, breakpoint is inside the _penter hook function in the profiler code currently enter image description here

The same entry is showing a different address with a "_" preceding the function name, in the profiler code The same entry is showing a different address with a "_" preceding the function

I have no idea how it is changing the addresses and want to know if I am doing something wrong.

The way I am doing it is, I have an extern array of function pointers( and their names) that is initialized with subject code functions' references in the subject main file(where all functions are available). In hook function (_penter) of the library, I get the address of the function just entered. So I compare it with the addresses in the extern array, and if it is a match, I log the entered function.

SNIPPET FROM PROFILE.H (profiler)

extern Signature FuncTable[3000]; 

SNIPPET FROM PROFILE.CPP (profiler)

void _stdcall EnterFunc0(unsigned * pStack)
{
    void      * pCaller;
    pCaller = (void *)(pStack[0] - 5); // the instruction for calling _penter is 5 bytes long
    Signature * funct = FuncTable; //the table that has references to functions and their names
    funct = FuncTable;
    while (funct->function)
    {
        //const BYTE * func = (const BYTE *)funct->function;
        if ((void *)(pStack[0] - 5) == (void *)(funct->function))
        {
            int a = 0;
            linesBuffer = linesBuffer + "Entering " + funct->signature + ";";
            linesBuffer = linesBuffer + "\n";
            WriteToFile(false); //function buffers 100kb before writing
            break;
        }
        funct++;
    }
}
extern "C" __declspec(naked) void __cdecl _penter()
{
    _asm
    {
        pushad              // save all general purpose registers
            mov    eax, esp     // current stack pointer
            add    eax, 32      // stack pointer before pushad
            push   eax          // push pointer to return address as parameter to EnterFunc0

            call   EnterFunc0

            popad               // restore general purpose registers
            ret                 // start executing original function
    }
}

SNIPPET FROM main.c (subject code main file)

#include "../Profile/Profile.h"
Signature FuncTable[] = {
    { (int)TetrisView_ProcessPauseMenu, "TetrisView_ProcessPauseMenu" },
    { NULL }
};

Upvotes: 1

Views: 430

Answers (1)

geza
geza

Reputation: 29970

I think it is because of Incremental Linking. When it is turned on, you'll get an Incremental Linking Table (ILT). ILT contains a jump table. When a function is called, it is called via this ILT.

In FuncTable, you'll get an address which is in ILT, it won't be the address of the actual function. But in _penter, its return address will be the actual function (this is what is put in pCaller).

Turn off incremental linking, and you'll be fine.

Upvotes: 1

Related Questions