我對C++中THUNK一種實現技術的分析 (轉)
我對C++中THUNK一種實現技術的分析:namespace prefix = o ns = "urn:schemas--com::office" />
KEY S:C++ THUNK
在網際網路上看到這樣一段程式碼,有些網友不知其然,我簡單的把它分析一下。
#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 then 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 <.h>
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++在實現多重繼承中,要求有一種機制來實現對this指標的動態修改,比較好的一種實現技術就是採用THUNK技術,通常它是由一小段ASM所完成的實現地址轉變和的程式。上面這段程式碼採用C++語言實現THUNK技術。
大家都知道,在調到記憶體中後:
由低到高把記憶體分為:
低------0
佔用區
程式碼區
全程資料區
堆區
棧區
DLL區[有DLL自己的堆疊等]
....
沒有佔用區
高-----4GB
當程式執行時,函式
static void StaticFun()
{
cout << "C::StaticFun" << endl;
}
在記憶體的中adress已經確定了,我們假設它為 addr_fun_staticfun
當main函式到
C objC;
時,就為objC在資料區->棧內分配一個地址為 addr_data_objC ,長度為sizeof(C)的記憶體塊
至少這段塊記憶體在main函式執行其間是固定不變的。因此我們可知全程指標 g_pC ,以及static void CallBackFun()中的C* pC的值都是addr_data_objC[記得它是棧內],現在我們看pC->Init(StaticFun, pC);函式內部:
void Init(pFUN pFun, void* pThis)
{
m_thunk.m_jmp = 0xe9; //先不管
m_thunk.m_relproc = (int)pFun - ((int)this+sizeof(Thunk));
FlushInstructionCache(GetCurrentProcess(),
&m_thunk, sizeof(m_thunk));
}
由C類宣告可知,C類objC記憶體佈局中只有 Thunk m_thunk;一個資料成員 。連vptr也沒有。
所以我們得出結果 &objC.m_thunk = addr_data_objC = (int)this
m_thunk.m_relproc = (int)pFun - ((int)this+sizeof(Thunk));一句
的.m_relproc的值應為addr_fun_staticfun – (addr_data_objC + sizeof(Thunk)) [ 中sizeof(Thunk) = 5]
FlushInstructionCache(GetCurrentProcess(), &m_thunk, sizeof(m_thunk));
一句的作用,是填指令緩衝區 ,將記憶體地址為 &objC.m_thunk 處起大小為 sizeof(m_thunk)填充到指令緩衝[我覺得這句函式指令是起到的作用,沒有什麼必要性]。
這樣,可以理解為在函式Init內部把在記憶體地址起始為&objC.m_thunk = addr_data_objC 起[在資料棧內] sizeof(thunk)一段資料設定為
m_thunk.m_jmp = 0xe9;
m_thunk.m_relproc = (int)pFun - ((int)this+sizeof(Thunk));
而這部分資料的二進位制資料從程式碼角度講是起跳轉到addr_fun_staticfun的作用。
如果在C類中位於m_thunk之前宣告一個成員或增加類虛擬成員函式,那會讓(int)this <> &m_thunk,所以程式碼不能正常工作[這是建立在類物件記憶體佈局按用一範圍(Private,Public,pro..)成員變數宣告ORDER分配的基礎上],如果想要程式碼正常工作,就要在
m_thunk.m_relproc = (int)pFun - ((int)this+sizeof(Thunk));
處作出相當的修改:
m_thunk.m_relproc = (int)pFun - ((int)this+sizeof(Thunk)+SIZEOF(增加的變數));
請大家指正。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-993130/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Delphi中停靠技術的實現 (轉)
- C++中實現回撥機制的幾種方式[轉]C++
- 我對技術潮流的一些看法
- 體驗C++中介面與實現分離的技術(轉)C++
- WMI Series 1:實現Windows管理的各種技術概述 (轉)Windows
- 學習C++(一) 我現在理解的C++ (轉)C++
- ORACLE同步軟體技術實現對比(轉載)Oracle
- [精華] RDMA技術原理分析、主流實現對比和解析
- Thunk程式的實現原理以及在iOS中的應用iOS
- 一種新穎的技術:Delphi for DOS!!! (轉)
- Apache中URLRewrite技術的實現Apache
- 我走過的學習之路(記我對技術的選擇) (轉)
- 用 Thunk 實現 COM 的掛鉤
- 我對C++中虛擬函式、純虛擬函式在實現多型中作用的一點淺薄認識 (轉)C++函式多型
- 對C# 2.0中匿名方法的種種懷疑分析(轉)C#
- ATL中的Thunk機制學習 (轉)
- Thunk程式的實現原理以及在iOS中的應用(二)iOS
- 灰度釋出的一種技術實踐
- 再造一個WinZip ——C++流技術物件導向分析與設計(一) (轉)C++物件
- 六種實現負載均衡技術的方式負載
- .net中ajax技術實現(自我總結,也許不對)
- 【轉載】SAP 系統中STO+VC 技術實現
- OLAP:實現高效BI分析的必備技術
- 再造一個WinZip ——C++流技術物件導向分析與設計(二) (轉)C++物件
- 批判性地看待一種可行的表示技術:JavaServerPages servlet技術(上) (轉)JavaServerServlet
- 理解thunk函式的作用及co的實現函式
- 集智學園知識星空——前端技術實現分析(一)前端
- IPv4向IPv6轉換的幾種技術分析
- oracle同步軟體技術實現對比Oracle
- 元件技術的本質COM例項分析一 (轉)元件
- 在C++中實現“屬性 (Property)” (轉)C++
- 純技術貼:討論一個現實中的需求的架構架構
- [轉] 細數Javascript技術棧中的四種依賴注入JavaScript依賴注入
- ?【Alibaba中介軟體技術系列】「RocketMQ技術專題」讓我們一起探索一下DefaultMQPushConsumer的實現原理及原始碼分析MQ原始碼
- 現如今的技術浪潮中,我們到底該做些什麼?
- "陷阱"技術探秘 ──動態漢化Windows技術的分析 (轉)Windows
- 陷阱"技術探秘 ──動態漢化Windows技術的分析 (轉)Windows
- 不懂技術的人不要對懂技術的人說這很容易實現