通用 Thunk
2008-05-25 21:39:20 来源:WEB开发网2. 被调用者如何得到参数与返回地址?(它希望何种方式?)
一个和上述普通C函数具有相同参数列表,使用__stdcall的成员函数,希望参数,返回地址和this指针像这样准备 :
参数 m <- ESP + 8 + N
参数 m-1
…
参数 1 < -ESP + 8
this < -ESP +4
返回地址 <-ESP
3. 被调用者如何返回?
它使用 RET N+4 返回。
所以我们的工作是在参数1和返回地址之间插入this指针,然后跳转到成员函数。
(我们插入了一个this指针使得栈增加了4,所以被调用者使用 RET N+4 是正确的)
在设计 StdToStd 之前,让我们定义一些有用的宏。
相信我,这将使得源代码更加容易阅读和改进。
MachineCodeMacro.h
宏 CONST CODE_FIRST(byte,POP_EAX,0x58) 在StdToStd.h 中,将被替换成: “const byte POP_EAX;”
#undef CONST
#undef CODE
#undef CODE_FIRST
#ifndef THUNK_MACHINE_CODE_IMPLEMENT
#define CONST const
#define CODE(type,name,value) type name;
#define CODE_FIRST(type,name,value) type name;
#else
#define CONST
#define CODE(type,name,value) ,name(value)
#define CODE_FIRST(type,name,value) :name(value)
#endif
ThunkBase.h
#include “MachineCodeMacro.h”
namespace Thunk {
typedef unsigned char byte;
typedef unsigend short word;
typedef int dword;
typedef const void* dword_ptr;
}
StdToStd.h
#include <ThunkBase.h>
#define STD_TO_STD_CODES()
/* POP EAX */
CONST CODE_FIRST(byte,POP_EAX,0x58)
/* PUSH m_this */
CONST CODE(byte,PUSH,0x68)
CODE(dword_ptr,m_this,0)
/* PUSH EAX */
CONST CODE(byte,PUSH_EAX,0x50)
/* JMP m_memFunc(offset) */
CONST CODE(byte,JMP,0xE9)
CONST CODE(dword,m_memFunc,0)
namespace Thunk {
class StdToStd {
public:
StdToStd(const void *Obj = 0,int memFunc = 0);
StdToStd(const StdToStd &src);
const void* Attach(const void *newObj);
int Attach(int newMemFunc);
private:
#pragma pack( push ,1 )
STD_TO_STD_CODES()
#pragma pack( pop )
};
StdToStd.cpp
#include <StdToStd.h>
#define THUNK_MACHINE_CODE_IMPLEMENT
#include <MachineCodeMacro.h>
namespace Thunk {
StdToStd::StdToStd(dword_ptr Obj,dword memFunc)
STD_TO_STD_CODES()
{
Attach(Obj);
Attach(memFunc);
}
StdToStd::StdToStd(const StdToStd &src)
STD_TO_STD_CODES()
{
Attach(src.m_this);
Attach( GetTransferDST(&src.JMP) );
}
dwrod_ptr StdToStd::Attach(dword_ptr newObj) {
dword_ptr oldObj = m_this;
m_this = newObj;
return oldObj;
}
dword StdToStd::Attach(dword newMemFunc) {
dword oldMemFunc = GetTransferDST(&JMP);
SetTransferDST(&JMP,newMemFunc);
return oldMemFunc;
}
}
更多精彩
赞助商链接