?? zthunk.h
字號:
/*-======================- Copyright (c) 2007 -======================-
程序作者:
Hacker Ans : 駭客任務組Ans軟件工作室
聯系方式:
QQ:360038060
[oopfans]群:13161288
修改時間:
2007-03-09
功能描述:
thunk技術實現.利用這個類可以把回調函數完全封裝成類成員函數.使用這
個類時,一定要確保類實例的生命周期,如下所示:
-----------------------------------------------------------------
正確調用如下(一):
class T
{
private:
ZThunk m_thunk; // 將ZThunk聲明為數據成員
public:
void MemberFunction()
{
m_thunk.CallBack(parameters ... ); // ok!
}
}
-----------------------------------------------------------------
正確調用如下(二):
ZThunk m_thunk; // 將ZThunk聲明全局對像
class T
{
public:
void MemberFunction()
{
m_thunk.CallBack(parameters ... ); // ok!
}
}
-----------------------------------------------------------------
錯誤調用如下:
class T
{
public:
void MemberFunction()
{
ZThunk m_thunk; // 將ZThunk聲明為局部對像,
// 不會有語法錯誤,但是下面的調用會失敗!
m_thunk.CallBack(parameters ... ); // error!
}
}
-----------------------------------------------------------------
調用綜合示例:
class CTimer
{
private:
//thunk對像
ZThunk m_thunk;
//定時器回調函數
void TimerProc(HWND hWnd, DWORD dwMsg , WPARAM wPa, LPARAM lPa);
public:
//安裝定時器
void Set(HWND hWnd,int TimerID,int TimerSpeed)
{
//(TIMERPROC)m_thunk.CallBack(this,&CTimer::TimerProc,ZThunk::THISCALL)
//上面一句指示了定時器回調函數為CTimer類的TimerProc成員函數,也可以指定
//其他類中的成員函數
::SetTimer(hWnd,TimerID,TimerSpeed,
(TIMERPROC)m_thunk.CallBack(this,&CTimer::TimerProc,ZThunk::THISCALL));
}
};
版權聲明:
許可任何單位,個人隨意使用,拷貝,修改,散布及出售這份代碼,但是必須保
留此版權信息,以慰藉作者辛勤的勞動,及表明此代碼的來源,如若此份代碼
有任何BUG,請通知作者,以便彌補作者由于水平所限而導致的一些錯誤和不
足,謝謝!
此份代碼是作者跟據一位網友[JERKII.SHANG (JERKII@HOTMAIL.COM)]的一
篇文章[一種實現Win32窗口過程函數(Window Procedure)的新方法--
基于Thunk實現的類成員消息處理函數]修改而成,在此對原作者開源的精神
致敬!
-======================- Copyright (c) 2006 -======================-*/
#ifndef _ZTHUNK
#define _ZTHUNK
class ZThunk
{
private:
unsigned char m_ThiscallCode[10];
unsigned char m_StdcallCode[16];
public:
enum CALLINGCONVENTIONS
{
STDCALL = 1,
THISCALL= 2
};
public:
template <class T>
void* Callback(void* pThis,T MemberAddr,CALLINGCONVENTIONS WhichCalling=STDCALL)
{
// these codes only use in stdcall
if(WhichCalling==STDCALL)
{
// Encoded machine instruction Equivalent assembly languate notation
// --------------------------- -------------------------------------
// FF 34 24 push dword ptr [esp] ; Save (or duplicate) ; the Return Addr into stack
// C7 44 24 04 ?? ?? ?? ?? mov dword ptr [esp+4], pThis ; Overwite the old ; Return Addr with 'this pointer'
// E9 ?? ?? ?? ?? jmp target addr ; Jump to target message handler
char Buf[33]={0};
sprintf(Buf,"%d",MemberAddr);
unsigned long JmpAddr = (unsigned long) atol(Buf) - (unsigned long) &m_StdcallCode[0] - 16;
m_StdcallCode[11] = 0xE9;
*((unsigned long *) &m_StdcallCode[ 0]) = 0x002434FF;
*((unsigned long *) &m_StdcallCode[ 3]) = 0x042444C7;
*((unsigned long *) &m_StdcallCode[ 7]) = (unsigned long) pThis;
*((unsigned long *) &m_StdcallCode[12]) = JmpAddr;
return (void*)m_StdcallCode;
}
// these codes only use in thiscall
else if(WhichCalling==THISCALL)
{
// Encoded machine instruction Equivalent assembly languate notation
// --------------------------- -------------------------------------
// B9 ?? ?? ?? ?? mov ecx, pThis ; Load ecx with this pointer
// E9 ?? ?? ?? ?? jmp target addr ; Jump to target message handler
char Buf[33]={0};
sprintf(Buf,"%d",MemberAddr);
unsigned long JmpAddr = (unsigned long) atol(Buf) - (unsigned long) &m_ThiscallCode[0] - 10;
m_ThiscallCode[0] = 0xB9;
m_ThiscallCode[5] = 0xE9;
*((unsigned long *) &m_ThiscallCode[1]) = (unsigned long) pThis;
*((unsigned long *) &m_ThiscallCode[6]) = JmpAddr;
return (void*)m_ThiscallCode;
}return 0;
}
};
#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -