今天看不懂了程序员2003第六期 的thunk机制问题 请教各位。(等待)

fvv 2003-07-14 01:08:02
不用研究代码。书上的代码是说明怎样通过thunk机制。实现回调函数怎样封装成类的成员函数。不避免很多全局函数出现。满足O-O思想。
在代码中出现了很多象

m_mov = 0xB8;
m_this = (DWORD)pThis;
m_xchg_push = 0x50240487;
m_jmp = 0xE9;
这些0x50240487;0xE9;是怎么来的,写程序的人怎么才能知道这些。怎么才能了解这方面的内容;看了很多VC的书从没看到这方面的内容。什么书籍讲述这些知识。很多VC++底层机制哪种书籍讲述?

////书籍部分代码


template <class T>
class CAuxStdThunk
{
BYTE m_mov; // mov eax, %pThis
DWORD m_this; //
DWORD m_xchg_push; // xchg eax, [esp] : push eax
BYTE m_jmp; // jmp func
DWORD m_relproc; // relative jmp
public:
typedef void (__stdcall T::*TMFP)();
void InitThunk(TMFP method, const T* pThis)
{
union {
DWORD func;
TMFP method;
} addr;
addr.method = method;
m_mov = 0xB8;
m_this = (DWORD)pThis;
m_xchg_push = 0x50240487;
m_jmp = 0xE9;
m_relproc = addr.func - (DWORD)(this+1);
FlushInstructionCache(GetCurrentProcess(), this, sizeof(*this));
}
FARPROC GetThunk() const {
_ASSERTE(m_mov == 0xB8);
return (FARPROC)this; }
};
...全文
39 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
fvv 2003-07-15
  • 打赏
  • 举报
回复
哦 是吗。我没想到。sorry
fvv 2003-07-15
  • 打赏
  • 举报
回复
也就是说jmp func 在没有编译的时候怎么知道jmp到哪里。怎么想,m_jmp 也应该是在编译时赋值啊。
Analyst 2003-07-15
  • 打赏
  • 举报
回复
faint~~~~~~告诉你了这是80x86的机器指令,比如0xe9就是jmp
fvv 2003-07-15
  • 打赏
  • 举报
回复
你好! 我是说0x50240487,0xe9这些值是什么来了。因为在设计类时就把它们赋值了。 它应该有特别的含义。这些含义从哪得知。这是我比较迷惑的。
Analyst 2003-07-14
  • 打赏
  • 举报
回复
m_mov = 0xB8;
m_this = (DWORD)pThis;
m_xchg_push = 0x50240487;
m_jmp = 0xE9;
这些是标准的80x86机器指令,至于怎么来的只要把下面这段代码汇编一下就知道了。写程序的人根本没必要知道这些,用汇编器帮你翻译就可以了。反过来也一样,用反汇编。
mov eax, pThis
xchg eax, [esp]
jmp func
fvv 2003-07-14
  • 打赏
  • 举报
回复
哦 非常感谢你!!
我学过x86的汇编 我觉得当然是没有这方面的内容。win32汇编我没有听说过(可怜..),我想我肯定是没有这方面的知识 而且我也最需要这方面的知识。这方面的书有中文版吗?能给我介绍几本吗?
arxing 2003-07-14
  • 打赏
  • 举报
回复
噢,搞错了,我还以为你说的是CWindowImpl<>的thunk呢。
不过各种thunk原理是一样的。这些内容书上不可能讲,msdn好像也没有,因为它依赖机器,没有公共标准,如果你掌握win32汇编,就很容易明白了。
arxing 2003-07-14
  • 打赏
  • 举报
回复
如果写程序的人不知道这些,那编译器怎么出来的?
你这段代码不知道是哪种cpu的,不同的cpu应该有不同的格式。
X86机器上应该是
struct _WndProcThunk
{
DWORD m_mov; // mov dword ptr [esp+0x4], pThis (esp+0x4 is hWnd)
DWORD m_this; //
BYTE m_jmp; // jmp WndProc
DWORD m_relproc; // relative jmp
};
看窗口消息处理函数格式 LRESULT(CALLBACK*WNDPROC)(HWND, UINT, WPARAM, LPARAM),
根据C++参数压栈规则,在函数入口处,堆栈顶的第一个参数是HWND的位置,也就是当前栈指针+4.
因此这个结构充当代码段的话,就变成了
mov dword ptr[esp+0x4], m_this
jmp m_relproc
这样,当跳转到了目标函数m_relproc入口时,堆栈顶的指已经不是HWND了,而是窗口类的指针。

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧