还是Thunk的问题,实现我已经实现,不过还有些细节没弄明白。

BlueAtlantis 2003-07-23 11:27:32
首先,资源共享一下。
在atlbase.h中有个CStdCallThunk类。可以用做通用的thunk实现,而且支持大部分的CPU。


好了,说问题。
CStdCallThunk是将第一个参数替换成对象指针pThis。
在这里,
pthunk->m_mov = 0x0424444c7;
pthunk->m_this = (DWORD) pThis;
代表着
mov dword ptr [esp+0x4], pThis

我试过,无论函数参数有多少,总是正确的。也就是说第一个参数总是在esp+0x4上。

msdn上说stdcall调用方式是参数从右往左压栈,也就是说第一个参数是最后一个压栈的。那么它的位置应该是不定的,与参数们的类型和多少有关。
为什么它总在esp+0x4呢。
还有第二参数会在哪个位置呢?第三个呢?(esp增吗)

嗯,下面是那个类的使用代码:

#include <iostream>
#include <stdlib.h>
#include <windows.h>
#include <atlbase.h>
#include "Main.h"

using namespace ATL;
using namespace std;

class MyClass
{
public:
void out()
{
printf ("%d\n", m_ncount);
}

static void staticout(MyClass * pThis)
{
pThis->out();
}

int m_ncount;
};

typedef void(*MyCallBack)();

main()
{
MyClass myObject;
myObject.m_ncount = 12;
MyCallBack Caller = NULL;

CStdCallThunk thunk;
thunk.Init((DWORD_PTR) myObject.staticout, &myObject);
Caller =(MyCallBack) thunk.GetCodeAddress();

Caller();
}
...全文
34 点赞 收藏 5
写回复
5 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
BlueAtlantis 2003-07-23
当然总是最前面,可是地址不应该是固定的呀(esp+0x4),
而且这里没有this指针的事情.
回复
Analyst 2003-07-23
从右往左是没错,不过你要记住这个堆栈的数据结构是栈,后进先出,所以最后一个入栈的this,总是排在最前面的。
回复
BlueAtlantis 2003-07-23
哦,原来如此,多谢,多谢。
回复
Analyst 2003-07-23
笔误,堆栈是从上往下增长的,每压一个字节,esp就减1。
回复
Analyst 2003-07-23
堆栈是从下往上增长的,esp是栈顶指针,[esp]是返回地址,[esp+4]就是第一个参数,[esp+8]就是第二个参数,依次类推。
回复
发帖
ATL
创建于2007-09-28

3214

社区成员

ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
申请成为版主
帖子事件
创建了帖子
2003-07-23 11:27
社区公告
暂无公告