I have an analysis of THUNK in C ++

zhaozj2021-02-11  172

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 #include using namespace std; class c; c * g_pc = null; typedef void (* pfun) ();

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.

转载请注明原文地址:https://www.9cbs.com/read-5758.html

New Post(0)