之前写了一篇blog,描述 Windows 在x86 下,如何确定Virtual Function在Table中的位置。
没有写x64的情况,主要原因是x64不支持内联汇编。
我们知道MSVC编译器不会直接访问Table,而是会写一个thunk间接访问。
我们第一步要获得这个thunk的地址,用伪代码就是: &Class::vfn_name
c++认为这是一个成员函数指针,他是无法转化为void*的。(还是有办法的)
所以在上一篇blog中,我们用如下的泛型函数和内联汇编实现
template<typename src_type>
void* pointer_cast(src_type src)
{
void* ret = NULL;
__asm
{
mov eax, src
mov ret, eax
}
return ret;
}
调用如下:
void* p_thunk_fn = pointer_cast(&Class::vfn_name);
这样就通过”黑魔法“获得了这个thunk的地址。
当然,到了x64这个方法就行不通了。
后来我在咨询deepseek的时候,他偶尔提了一嘴,说可以用Union的方法
然后我想起来还有这个玩法,以前看到过。
这样直接通过Union就可以骗过编译器,获得thunk的地址
实现如下:
union FunctionPointer {
void (Class::*vfn_name)(int arg);
void* ptr;
};
FunctionPointer fp;
fp.vfn_name = &Class::vfn_name;
void* thunk = fn.ptr; //getchu~
当然,我们为了获取所有地址,需要每一个函数都写一个这样的FunctionPointer
这样要疯掉。
让deepseek给我写了一个泛型,这时候体现出ai作为工具能极大提高工作效率!
template <typename T>
union TFP;
// 特化模板,支持成员函数指针
template <typename ClassType, typename ReturnType, typename.