今天在atlaux2.h 里面发现一个类,很好奇。
因为他是下面的写法。。。
//ATLAUX2.h -- COM/ATL Useful Helpers
#pragma pack(push, 1)
template <class T>
class CAuxThunk
{
BYTE m_mov; // mov ecx, %pThis
DWORD m_this; //
BYTE m_jmp; // jmp func
DWORD m_relproc; // relative jmp
public:
typedef void (T::*TMFP)();
void InitThunk(TMFP method, const T* pThis)
{
union {
DWORD func;
TMFP method;
} addr;
addr.method = method;
m_mov = 0xB9;
m_this = (DWORD)pThis;
m_jmp = 0xE9;
m_relproc = addr.func - (DWORD)(this+1);
FlushInstructionCache(GetCurrentProcess(), this, sizeof(*this));
}
FARPROC GetThunk() const {
_ASSERTE(m_mov == 0xB9);
return (FARPROC)this; }
};
我们知道类在内存里面的结构。。
类名 -> (内存)也是变量 和函数地址存放的地方。
现在这个类是在模拟一个 汇编语言的操作。
BYTE 实际上是char 一个字节
0012FF58 B9 58 FF 12 00 E9 8B 筙...閶
0012FF5F 14 2D 00
我的模拟测试
#include <map> #include <string> #include <iostream> using namespace std; #pragma pack(push, 1) template <class T> class CAuxThunk { unsigned char m_mov; // mov ecx, %pThis unsigned long m_this; // unsigned char m_jmp; // jmp func unsigned long m_relproc; // relative jmp public: typedef void (T::*TMFP)(); void InitThunk(TMFP method, const T* pThis) { union { unsigned long func; TMFP method; } addr; addr.method = method; m_mov = 0xB9; m_this = (unsigned long)pThis; m_jmp = 0xE9; m_relproc = addr.func - (unsigned long)(this+1); //FlushInstructionCache(GetCurrentProcess(), this, sizeof(*this)); } // FARPROC GetThunk() const { // _ASSERTE(m_mov == 0xB9); // return (FARPROC)this; } }; class a:public CAuxThunk<a> { int ain; public: void fun() {cout<<"dd"<<endl;} void test_InitThunk(void){ InitThunk( fun, this); } }; #pragma pack(pop, 1) int main() { CAuxThunk<a> s; a testa; testa.test_InitThunk(); return 0; }
看到同样 mov 操作,但是不同操作数就要用不同16进制代码。
这里 B9 地址 ecx是默认调用的。