简单的虚表Hook

最近在学习C++虚函数表的Hook,这里简单上传一个小例子,是64位32位通用的


// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//



#include <windows.h>
#include <stdio.h>
/// <param name="__vfptr">虚表指针的地址</param>
/// <param name="pHookFunc">fake函数地址</param>
/// <param name="IndexInVT">欲Hook函数的引索</param>
/// <param name="pOldFunc">保存原函数地址</param>
BOOL HookVT(IN PVOID __vfptr, IN PVOID pHookFunc, IN DWORD IndexInVT,OUT ULONG_PTR* pOldFunc);
#define UnHookVT(vtptr,pOldFunc,Index)  HookVT(vtptr,pOldFunc,Index,NULL)

class MyClass
{
public:
    virtual void printdata();
    MyClass();
    ~MyClass();
};

void MyClass::printdata()
{
}

MyClass::MyClass()
{
}

MyClass::~MyClass()
{
}


class Son : public MyClass
{
public:
     void printdata()
     {
         printf("s\n");
    };
};
void FakePrintdata()
{
    printf("FAKE\n");
}

int main()
{
    Son* myclass = new Son();
    myclass->printdata();       //未Hook之前

    ULONG_PTR pOldFunc = NULL;  //保存原函数地址

    HookVT(&myclass,FakePrintdata, 0, &pOldFunc);//虚表指针就在对象的开头4/8字节
    myclass->printdata();       //Hook之后

    UnHookVT(&myclass, (PVOID)pOldFunc, 0);
    myclass->printdata();//UnHook之后

    Son myclass02;
    myclass02.printdata();  //不用指针的形式调用,编译器将解释为Son::printdata绕过虚表
    return 0;
}

BOOL HookVT(IN PVOID __vfptr, IN PVOID pHookFunc, IN DWORD IndexInVT, OUT ULONG_PTR* pOldFunc)
{
    auto Hooked = FALSE;
    auto Vtable =(ULONG_PTR*) (*(ULONG_PTR *)(*(ULONG_PTR*)__vfptr));   //*虚表指针地址->*虚表指针->*虚表地址
    DWORD Flags = PAGE_READWRITE;
    DWORD oldFlags = 0;
    if (VirtualProtect(Vtable, sizeof(ULONG_PTR), Flags, &oldFlags))
    {
        if (!pOldFunc == NULL)
        {
            *pOldFunc = Vtable[IndexInVT];
        }
        Vtable[IndexInVT] = (ULONG_PTR)pHookFunc;
        Hooked = TRUE;
        return Hooked;
        VirtualProtect(Vtable, sizeof(ULONG_PTR), oldFlags, &Flags);    //恢复原保护属性
    }
    return Hooked;
}


运行结果如下

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值