COM Hook原理

掌握C++对象模型底层知识的人都知道,C++利用虚函数的机制来实现运行期的多态。

例如一个类申明如下:

 

class  A
{
public :
    A(){}
    
~ A(){}

    
virtual   void  f1(){ printf( " Founction f1 called\n " ); }

    
virtual   void  f2(){ printf( " Founction f2 called\n " ); }

    
virtual   void  f3(){ printf( " Founction f3 called\n " ); }

private :
    
int  n;
};
 

那么A对象在内存中的结构图大概如下:

 

  (缺失)

 

如上图:可以看到A对象的前4个字节是虚函数表的指针vptr,而虚函数表本身又是一个数组。所以vptr可以看作一个指向指针的指针。
那么已知pA为A对象指针,我们如果想得到虚函数表的地址,只需要如下即可。
long** pplVrtable= (long**)(pA);
我们可以为类A添加一个成员函数确认一下。
void A::reset_f1()
{
long** pplVrtable= (long**)(this); //取得虚函数表的指针
*pplVrtable = *pplVrtable +1;//将虚函数表的指针指向虚函数表第二个值。
}
测试代码:
int main(int argc, char* argv[])
{
A* pA = new A;
pA->reset_f1();

pA->f1();

delete pA;

return 0;
}
运行输出:
Founction f2 called.
结果证实虚函数表的指针已经被成功修改,对于成员函数f1的调用变成了对f2的调用.
但是我们这里修改的只是虚函数指针,那么我们可不可以直接修改虚函数表那?
试一下看看,修改代码如下:
void A::reset_f1()
{

long** pplVrtable= (long**)(this); //取得虚函数表的指针

(*pplVrtable)[0]= (*pplVrtable)[1];//将虚函数表的第一个值设置为虚函数表第二个值。
}
运行,结果程序crash了,看样子虚函数表这块内存是被系统保护了,看似山重水复疑无路了,不过没关系,Windows提供了一组针对内存保护的函数:
VirtualQueryEx, VirtualProtectEx,(相关定义和使用方法,可以看看MSDN).
利用这两个函数我们可以实现修改虚函数表的功能,再次修改代码如下:

     void  reset_f1()
    {
        
// long** pplVrtable= (long**)(this);     // 取得虚函数表的指针
        
// *pplVrtable = *pplVrtable +1;         // 将虚函数表的指针指向虚函数表第二个值。
        
        
// long** pplVrtable= (long**)(this);  // 取得虚函数表的指针
        
// (*pplVrtable)[0]= (*pplVrtable)[1]; // 将虚函数表的第一个值设置为虚函数表第二个值。

        
long **  pplVrtable =  ( long ** )( this );
        HANDLE hProcess 
=  OpenProcess(PROCESS_ALL_ACCESS, FALSE, ::GetCurrentProcessId());
        MEMORY_BASIC_INFORMATION mbi 
=  { 0 };
        
if  (VirtualQueryEx(hProcess, (LPVOID)( * pplVrtable),  & mbi,  sizeof (mbi))  !=   sizeof (mbi))
            
return ;

        DWORD dwOldProtect 
=   0 ;
        
if ( ! ::VirtualProtectEx(hProcess, mbi.BaseAddress,  4 , PAGE_EXECUTE_READWRITE,  & dwOldProtect)) 
            
return ;

        (
* pplVrtable)[ 0 =  ( * pplVrtable)[ 1 ];

        DWORD dwTemp 
=   0 ;
        ::VirtualProtectEx(hProcess, mbi.BaseAddress, 
4 , dwOldProtect,  & dwTemp);
        CloseHandle(hProcess);
    }

运行输出:
Founction f2 called.
结果与预期一样,虚函数表终于被成功修改了.
因为COM接口是没有成员变量的只有纯虚函数的类,其虚函数指针在内存分配上具有唯一性,所以我们可以通过以上的技术实现对所有COM接口成员函数的HOOK. ,


 

转载于:https://www.cnblogs.com/weiqubo/archive/2011/06/17/2083361.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值