我對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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 我對技術潮流的一些看法
- Thunk程式的實現原理以及在iOS中的應用iOS
- [精華] RDMA技術原理分析、主流實現對比和解析
- Thunk程式的實現原理以及在iOS中的應用(二)iOS
- 灰度釋出的一種技術實踐
- 六種實現負載均衡技術的方式負載
- 【轉載】SAP 系統中STO+VC 技術實現
- IPv4向IPv6轉換的幾種技術分析
- ?【Alibaba中介軟體技術系列】「RocketMQ技術專題」讓我們一起探索一下DefaultMQPushConsumer的實現原理及原始碼分析MQ原始碼
- OLAP:實現高效BI分析的必備技術
- 理解thunk函式的作用及co的實現函式
- [轉] 細數Javascript技術棧中的四種依賴注入JavaScript依賴注入
- 使用vue實現行列轉換的一種方法。Vue
- 集智學園知識星空——前端技術實現分析(一)前端
- 在 Python 中實現 COMET 技術Python
- C++的技術C++
- 快速排序的三種實現方法 (C++)排序C++
- 基於python爬蟲技術對於淘寶的資料分析的設計與實現Python爬蟲
- 技術分享 | 一種針對PHP物件注入漏洞的新型利用方法PHP物件
- 現如今的技術浪潮中,我們到底該做些什麼?
- 聊聊 C++ 中的四種型別轉換符C++型別
- TDSQL | 在整個技術解決方案中HTAP對應的混合交易以及分析系統應該如何實現?SQL
- #MyBatis多表查詢 #多對一、一對多的兩種實現方式 @FDDLCMyBatis
- Android技術分享| 【你畫我猜】Android 快速實現Android
- vue中實現路由跳轉的三種方式(精選)Vue路由
- 技術週刊的轉變:如何平衡熱愛與現實?
- C++的引用技術C++
- 我的那些年(12)~公司技術轉行,我也跟著轉到java了Java
- Ipv6轉換難點分析之一:協議轉換技術協議
- ATL Thunk機制深入分析
- 一對一社交原始碼在直播中最佳化技術的幾種形式原始碼
- 中科三方:IPv4向IPv6轉換的幾種技術分析
- AI不是一種技術,而是一種思考方式AI
- 從 0 到 1:我的 Flutter 技術實踐 | 掘金技術徵文Flutter
- ReactiveProgramming一種技術,各自表述React
- 分析技術在PMP中的應用
- IPv6轉換技術是什麼?淺談IPv6轉換的兩種技術方式
- Python中4種方法實現 xls 檔案轉 xlsxPython
- 客戶端跳轉技術,服務端跳轉技術,兩種跳轉的各自使用場合和特點客戶端服務端