游戏开发论坛

 找回密码
 立即注册
搜索
查看: 980|回复: 0

thunk初探 wxh zt

[复制链接]

1367

主题

1993

帖子

2118

积分

金牌会员

Rank: 6Rank: 6

积分
2118
发表于 2006-2-13 21:50:00 | 显示全部楼层 |阅读模式
(莫名春秋发表)

在看vc知识库38期的com部分《atl布幔之下的秘密》一文中,开始的时候对thunk非常的不理解,在跟一位学长探讨之后,呵呵,主要是学到了vc下如何得到察看程序的汇编代码。终于明白了是怎么一回事。

开始对mov dword ptr [esp+0x4], pThis中[esp+0x4]指向WindowProc函数的hwnd参数非常的不理解,似乎按照函数的入栈规则,[esp+0x4]是不可能指向WindowProc函数的hwnd参数。懂得察看汇编代码后,发现在窗口建立过程只运行一次的StartWndProc中对thunk初始化(init函数)后,得到了WNDPROC pProc = (WNDPROC)&(pThis->m_thunk.thunk);(注意这里typedef LRESULT (CALLBACK* WNDPROC)(HWND, UINT, WPARAM, LPARAM);)

改变窗口过程为pProc后,然后就是调用pProc,首先将4个参数压入栈中,这段汇编代码如下:

004014FF   mov         esi,esp

00401501   mov         ecx,dword ptr [ebp+14h]

00401504   push        ecx

00401505   mov         edx,dword ptr [ebp+10h]

00401508   push        edx

00401509   mov         eax,dword ptr [ebp+0Ch]

0040150C   push        eax

0040150D   mov         ecx,dword ptr [ebp+8]

00401510   push        ecx

00401511   call        dword ptr [ebp-8]        ;调用thunk代码

前面push就是把参数入栈,call调用要保存返回地址,所以相当push一次。所以这个时候[esp+4]刚好就是hwnd的堆栈地址。然后通过call调用thunk代码。

Thunk代码如下:

0012FED0   mov         dword ptr [esp+4],12FEC8h

0012FED8   jmp         @ILT+95(ZWindow::WindowProc) (00401064)

下面就是进入了windowProc的处理过程之中。

    所以这个thunk就是在 windowProc执行之前,将hwnd指向正确的地方,因为每一个window都包含一个WndProcThunk变量,所以可以保持唯一性。WNDPROC的声明形式也能保证参数的准确入栈操作。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-23 10:43

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表