Click to See Complete Forum and Search --> : address of functions


zameericle
October 30th, 2002, 10:01 AM
can anyone explain the following code-snippet (found on codeproject - program 75 http://www.codeproject.com/atl/atl_underthehood_5.asp#xx321175xx)


#include <iostream>
#include <windows.h>
using namespace std;

class C;

C* g_pC = NULL;

typedef void(*pFUN)();

#pragma pack(push,1)
// structure to store the machine code
struct Thunk
{
BYTE m_jmp; // op code of jmp instruction
DWORD m_relproc; // relative jmp
};
#pragma pack(pop)

class C
{
public:
Thunk m_thunk;

void Init(pFUN pFun, void* pThis)
{
// op code of jump instruction
m_thunk.m_jmp = 0xe9;
// address of the appripriate function
m_thunk.m_relproc = (int)pFun - ((int)this+sizeof(Thunk));

FlushInstructionCache(GetCurrentProcess(),
&m_thunk, sizeof(m_thunk));
}

// this is cour call back function
static void CallBackFun()
{
C* pC = g_pC;

// initilize the thunk
pC->Init(StaticFun, pC);

// get the address of thunk code
pFUN pFun = (pFUN)&(pC->m_thunk);

// start executing thunk code which will call StaticFun
pFun();

cout << "C::CallBackFun" << endl;
}

static void StaticFun()
{
cout << "C::StaticFun" << endl;
}
};

int main()
{
C objC;
g_pC = &objC;
C::CallBackFun();
return 0;
}


the line that I am having difficulty with is:

m_thunk.m_relproc = (int)pFun - ((int)this+sizeof(Thunk));


What I don't understand is why you can't use (int)pFun as the address of the function, why the need for the math???

any help would be appreciate.. thanks

Zameer

galathaea
October 30th, 2002, 11:45 AM
One (of the many) defintion of thunk is an inserted jump to a procedure normally used to redirect or intercept a code call. This appears to be what the code is doing. It is inserting a function into the address space before the function that is to be called. The math calculates the start location of this interception code and replaces a call to the original function. This is the reason that it is not just storing the address of the function. It doesn't want to call the function (at least not at first). It first calls the thunk which then appears to make an appropriate jump to the code it wants to execute.

doublehook
October 30th, 2002, 05:41 PM
It seems a way for calculate an address value that is
the result of a substract operation. Casts the function
address to integer value and substracts the size of a piece
of code. It seems a sample of advanced code, but i don't know
if this is usefull and why he does this.

zameericle
October 31st, 2002, 02:41 AM
suppose C::StaticFunc is located at say 0x0000001

why doesn't the following call the function?

jmp 0xe9, 0x0000001

what does ((int)this + sizeof(Thunk)) have to do with calculating the address of where to jump?

unless ofcourse the jmp operand requires a relative address (relative to the program), while &C::StaticFun returns the global address (in memory). But then would that mean that if I defined another class before C, would I then have to use the following to calculate the relative address:

(int)this + sizeof(Thunk) + sizeof(newClass)

for doublehook: This is commonly used in ATL to associate a call back function with it's appropriate hwnd.