今天,跟公司的人讨论了一个问题,感觉收益颇丰,故记录下来,以备后用。
问题的大致跟虚表有关,这里的问题主要是利用小技巧窃取虚表指针,达到另类的hook。
#include "stdafx.h"
#include <iostream>
using namespace std;
class A
{
public:
virtual void f()
{
cout<<"A::f"<<endl;
}
private:
int x;
};
class B : public A
{
public:
virtual void f()
{
cout<<"B::f"<<endl;
}
private:
int y;
};
class C
{
public:
virtual void f()
{
cout<<"C::f"<<endl;
}
};
int main(int argc, char* argv[])
{
A* pA = new A;
B* pB = new B;
C* pC = new C;
memcpy(pA, pB, sizeof(A));
memcpy(pC, pB, sizeof(C));
pA->f();
pC->f();
return 0;
}
以上的类A,B, C; 经过memcpy后,B将自己的vptr指针拷贝到了对象A,C的结构中,于是出现了输出:
B::f
B::f
的现象。
由此我们可以想象,假设我们有某个dll和头文件,我们就可以利用这里的机制,来hook自己的成员函数了。为了防止运行时的错误,我们可以引出如下假设。
If(sizeof(C)<=sizeof(B))
{
BYTE __LocateAddress BYTE[sizeof(B)];
……
用的时候,
pC = new (__LoacateAddress) C;
……
memcpy(pC, pB, sizeof(B));
这样,我们就可以万无一失的利用B的虚拟函数了。
}