先写个类来说明问题
class TestClass
{
public:
void PublicFunc()
{
cout<<"PublicFunc\n";
}
private:
virtual void PrivateFunc()
{
cout<<"PrivateFunc\n";
}
};
TestClass testClass;
testClass.PublicFunc();//No problem
testClass.PrivateFunc();//Compile Err
正如注释,第二个调用编译器会报错;总是好奇,想绕过private的限制(纯属蛋疼)。
(另示例中的私有成员函数有virtual虚函数限定符)
为了能够直接访问私有成员函数,想必要拿到其成员函数指针:
eg
typedef void (TestClass::* pPrivateFunc)();
pPrivateFunc func = &TestClass::PrivateFunc;//当然这种方式是欺骗不了编译器了
当然这样也不可以:
DWORD dwFooAddrPtr = 0;
dwFooAddrPtr = (DWORD)&TestClass:PrvateFunc;//Err
dwFooAddrPtr = reinterprt_cast<DWORD>(&TestClass:PrvateFunc);//Err
用union 来骗过编译器
template<class Tdst,class Tsrc>
Tdst union_cast(Tsrc src)
{
union
{
Tsrc _src;
Tdst _dst;
}format;
format._src = src;
return format._dst;
}
好了,下面干活了,至于怎么从对象地址获取虚函数表我就不多说了:
typedef void (__stdcall* pPrivateFunc)();
DWORD* pDwVt = union_cast<DWORD*>(&testClass);
DWORD* pdwVt0 = (DWORD*)*pDwVt;
pPrivateFunc pfunc = unino_cast<pPrivateFunc>(*pdwVt0);
if(pfunc)
{
pfunc();
}
好了,这样就可以顺利调用类私有成员函数;但是在实际测试中,虽然能够进入私有成员函数,但是无法访问其成员变量,就显得这么做没有任何意义;
不过稍加思考,其实C++调用其成员函数是,默认会在ecx寄存器里保存this指针,据此加了个patch,就可以解决这个问题了:
if(pfunc)
{
__asm
{
lea eax,dword ptr[testClass]
mov ecx,eax
}
pfunc()
}
至此理论上完美解决了标题的问题了,不过实际应用中没有什么应用价值,只不过是对C++的成员函数模拟了一下。