WEB开发网
开发学院软件开发VC 通用Thunk 阅读

通用Thunk

 2010-07-15 20:45:23 来源:WEB开发网   
核心提示:3、使用__cdecl 的成员函数使用 RET 返回CdeclToCdecl类与ThisToCdecl十分相似:thunk对象调用一个 Hook函数来准备this指针,保存old_esp,通用Thunk(12),返回地址,然后跳转到被调用者,如果你认为有,请在 ThunkBase.cpp中定义 THUNK_FLUSHI

3、使用__cdecl 的成员函数使用 RET 返回

CdeclToCdecl类与ThisToCdecl十分相似:

thunk对象调用一个 Hook函数来准备this指针,保存old_esp,返回地址,然后跳转到被调用者。

被调用者返回之后,thunk代码修改ESP,然后跳转到调用者。

不同之处在Hook函数,它将this指针插入到参数1与返回值之间,而不是将它传送到ECX。

更详细的实现见 CdeclToCdecl.h 和CdeclToCdecl.cpp

设计 StdToCdecl

让我们拿它和CdeclToCdecl做比较。

唯一不同的是,成员函数使用RET N+4而不是 RET。

当被调用者返回后,不管是RET N+4,还是RET,ESP都将被恢复。

因此,CdeclToCdecl可以胜任StdToCdecl

所以,StdToCdecl 只是一个 typedef “typedef CdeclToCdecl StdToCdecl;” ^_^

设计 CdeclToStd

使用__stdcall 的调用者将堆栈平衡工作交给被调用者。

使用__cdecl 的被调用者使用RET返回到调用者。

而关于ESP的信息在这之中丢失了!

非常不幸,我没办法设计出一个通用的thunk类。 -_-

关于 __fastcall 和更进一步的工作

__fastcall调用约定将小于或等于dword的头2个参数用ECX和EDX传递。

所以设计出一个通用的thunk类似乎是不可能的。(因为和参数相关)

但是特殊的解决方案是存在的。

我认为Thunk的理论比实现更重要。

在你打算解决一个特定的问题 (比如为了特定参数的 __fastcall 和 CdeclToStd ),在另一平台上实现,或者想继续优化这份实现的时候,如果这篇文章能对你有所帮助,我非常高兴 ^_^

源代码可以任意使用,作者不会为此承担任何责任 ^_^。

关于FlushInstructionCache

这些类通常是按如下方式被使用:class CNeedCallback {
private:
CThunk m_thunk;
public:
CNeedCallback() :m_thunk(this,Thunk::Helper::PointerToInt32(&CNeedCallback::Callback)) {}
private:
returnType Callback(….) {}
}

所以,每个thunk对象的Obj和Method属性在构造后就不再改变。我不知道在这种情况下FlushInstructionCache是否有必要。如果你认为有,请在 ThunkBase.cpp中定义 THUNK_FLUSHINSTRUCTIONCACHE ,或者简单的去掉第4行注释。

特别感谢

Illidan_Ne 和Sean Ewington ^_^.

本文配套源码

上一页  7 8 9 10 11 12 

Tags:通用 Thunk

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接