I have an analysis of THUNK in C
Key Words: C THUNK Memory Mode
Seeing such a code on the Internet, some netizens don't know, I simply analyze it.
#pragma pack (push, 1) // Structure to store the machine code struct thunk {char m_jmp; // Op code of jmp instruction unsigned long m_relproc; // relative jmp}; #pragma pack (POP)
// this Type of Structure CAN Contain THUNK CODE, Which Can Be Executed on The Fly. Let's Take a Look At The Simple Case In Which We Are Going to Execute Our Required Function by Thunk.
// Program 77 #include
class C {public: Thunk m_thunk; // virtual void g () {}; 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;}
C in achieving multiple inherits, requires a mechanism to achieve dynamic modifications to the THIS pointer, and a better implementation technology is to adopt Thunk technology, usually it is a program that implements address transformation and function calls completed by a small ASM. . The above code implements Thunk technology in C language. Everyone knows that after the program is transferred to memory: divided by low to high into: low ------ 0 system occupying area code area full data area pile area stack area DLL area [DLL own stack, etc. ] .... no occupation area high ----- 4GB
When the program is running, the function static void staticfun () {cout << "C :: staticfun" << Endl;} In the memory, AdRess has been determined, we assume that it is executed to c Objc when the main function is implemented as the main function;
When the OBJC is assigned an address in the data area-> stack, the memory block is fixed in this block in the data area-> stack, at least the memory block of the length SIZEOF (C) is fixed. Therefore, we can know that the full pointer g_pc, and the value of the C * PC in Static Void CallbackFun () is addr_data_objc [Remember it is in the stack], now we look at PC-> init (staticfun, pc); function interior: void Init pFUN pFun, void * pThis) {m_thunk.m_jmp = 0xe9; // first whether m_thunk.m_relproc = (int) pFun - ((int) this sizeof (Thunk)); FlushInstructionCache (GetCurrentProcess (), & m_thunk, sizeof (m_thunk ));
It is known from Class C to known that there is only THUNK M_THUNK in the Class C object OBJC memory; a data member. There is no VPTR. So we got the result & objc.m_thunk = addr_data_objc = (int) This
m_thunk.m_relproc = (int) PFUN - (INT) THIS SIZEOF (THUNK)); one sentence. M_relProc should be addr_fun_staticfun - (addr_data_objc sizeof (thunk) [Win32 Sizeof (THUNK) = 5]
Flushinstructioncache (getCurrentProcess (), & m_thunk, sizeof (m_thunk)); a function of filling the instruction buffer, putting the memory address as the size of the SIZEOF (M_thunk) to the instruction buffer [I think this function instruction It is an optimized role, there is nothing necessary].
In this way, it is understood that the memory address is started to be & objc.m_thunk = addr_data_objc [in the data stack] SIZEOF (THUNK) in the data stack is set to m_thunk.m_relproc = (int) PFUN - ((int) This sizeof (thunk); this part of the binary data of this part is a role in jump to addr_fun_staticfun from the code angle.
If you declare a member or add a virtual member function before the class C class, you will make (int) this <> & m_thunk, so code cannot work normally [this is built in the class object memory layout (Private, Public, pro ..) Member variable declares on the basis of ORDER assignment]
A considerable modification is made:
M_thunk.m_relproc = (int) PFUN - ((int) This sizeof (tHunk) sizeof (increasing variable));
Please refer to you.