当前位置: 首页 > backend >正文

5种隐蔽的外挂获取执行时机方法介绍

一、模拟前的设定

    本次模拟外挂获取执行时机,新建一MFC程序FakeGamke,并模拟游戏中玩家攻击后的伤害计算,界面如下:

            

    模拟游戏中玩家相关的类如下:

class CGameObject  //游戏对象基类

{

public:

    CGameObject()

    {

        m_pAttack = new int;

    }

    ~CGameObject()

    {

        delete m_pAttack;

    }

    int GetAttack()

    {

        return *m_pAttack;

    }

    void SetAttack(int nAttack)

    {

        *m_pAttack = nAttack;

    }

    int GetAdditionAttack()

    {

        return m_nAdditionAttack;

    }

    void SetAdditionAttack(int nAdditionAttack)

    {

        m_nAdditionAttack = nAdditionAttack;

    }

    

    virtual TCHAR * GetName()

    {

        return _T("");

    }

    //其他成员函数...

    virtual float ComputeDamage() //计算伤害

    {

        float fDamage = (GetAttack() + GetAdditionAttack()) * 1.0;

        return fDamage;

    }

private:

    int *m_pAttack;         //基础攻击力

    int m_nAdditionAttack; //攻击力加成

    //....游戏对象其他属性

};

class CGamePlayer : public CGameObject

{

public:

    CGamePlayer()

    {

        m_szPlayerName = new TCHAR[20];

        _tcscpy(m_szPlayerName, _T("天下第一"));

        SetAttack(55);

        SetAdditionAttack(12);

        SetPreAttack(0.234);

    }

    ~CGamePlayer()

    {

        delete[] m_szPlayerName;

    }

    float GetPreAttack()

    {

        return m_fPreAttrack;

    }

    void SetPreAttack(float fPreAttack)

    {

        m_fPreAttrack = fPreAttack;

    }

    virtual TCHAR * GetName()

    {

        return m_szPlayerName;

    }

    virtual float ComputeDamage()  //计算伤害的函数

    {

        float fDamage = (__super::ComputeDamage())*(1 + GetPreAttack());

        return fDamage;

    }

private:

    float m_fPreAttrack;     //攻击比例加成

    TCHAR* m_szPlayerName;   //玩家名称

    // ... 玩家其他属性

};

    其中假设 输出伤害 = (攻击力 + 攻击力加成)*(1+攻击比例加成)。当点击攻击按键时表示玩家攻击动作,此时计算输出伤害并显示。

#include "FakePlayer.h"

CGameObject* g_LocalPlayer = new CGamePlayer();  //本地玩家

void CFakeGameDlg::OnBnClickedButtonAttack()  //点击攻击将计算伤害

{

    float fDamage = g_LocalPlayer->ComputeDamage();

    CString stTmp;

    stTmp.Format(_T("%0.3f"), fDamage);

    SetDlgItemText(IDC_EDIT_DAMAGE, stTmp);

    stTmp.Format(_T("[TFFLAG] ThreadID:0x%x"), GetCurrentThreadId());

    OutputDebugString(stTmp);

}

void CFakeGameDlg::OnBnClickedButtonDisplay()  //点击显示玩家属性

{

    // TODO: Add your control notification handler code here

    CString stTmp;

    stTmp.Format(_T("%d"), g_LocalPlayer->GetAttack());

    SetDlgItemText(IDC_EDIT_ATTACKPOWER, stTmp);

    stTmp.Format(_T("%d"), g_LocalPlayer->GetAdditionAttack());

    SetDlgItemText(IDC_EDIT_ATTACKADDITION, stTmp);

    stTmp.Format(_T("%0.3f"), ((CGamePlayer*)g_LocalPlayer)->GetPreAttack());

    SetDlgItemText(IDC_EDIT_ATTACKPER, stTmp);

    stTmp.Format(_T("%s"), g_LocalPlayer->GetName());

    SetDlgItemText(IDC_EDIT_NAME, stTmp);

}

    此次模拟 输出伤害为82.678 = (55 + 12)*(1+0.234)。FakeGame正常执行可得伤害值82.678。现模拟如何获取FakeGame的伤害计算时机,并改变其中部分属性或输出伤害结果值,达到高额伤害效果。

二、方法

1、虚函数地址&虚表地址替换

C++中的虚函数的作用主要是实现了多态的机制,虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)来实现的。简称为V-Table。在这个表保存的是类的虚函数地址,这张表解决了类的继承、多态、覆盖问题。有虚函数的类的实例中这个表地址会被分配到这个实例的内存中。

既然虚表中存放的是类的成员函数的地址,那如果将其替换,就给了外挂代码一次执行的机会。在FakeGame中,CGamePlayer类继承于CGameObject类。其中ComputeAttack(计算伤害函数)为虚函数。这两个类的结构如下:

    CGameObject 与CGamePlayer的虚表会被分配到PE文件中的.rdata区段,具体如下:

    在生成CGameObject、CGamePlayer对象时,虚表地址会赋值为对象内存的第一个四字节。(C++对象的内存布局非本文重点,读者自己了解一下)。

    在CGamePlayer对象调用函数ComputeAttack时,通过对象地址获取虚表地址,再通过虚表获取函数地址。

    

    根据上面的知识,现在我们通过替换虚表内的函数地址的方式,替换CGamePlayer对象虚表内的ComputeAttack函数地址,使得FakeGame在攻击计算伤害时执行替换后的函数,以此达到劫持FakeGame执行时

http://www.xdnf.cn/news/1951.html

相关文章:

  • Ubuntu 上手动安装 Go 环境并解决“可执行文件格式错误”
  • 反射、枚举以及lambda表达式
  • 某些网站不允许复制怎么办
  • 蓝桥杯 4. 卡片换位
  • txtai:全能AI框架
  • 龙虎榜——20250425
  • spreadsheet 之websheet
  • vue项目前后端分离设计
  • 从氛围到节奏:情绪化配乐网站指南
  • 【Harmony_Bug】forEach + asyncawait 的异步陷阱
  • assertEquals()
  • 基于AIGC的3D场景生成实战:从文本描述到虚拟世界构建
  • 脚本分享:快速作图对比wannier拟合能带python脚本
  • 产品动态|千眼狼sCMOS科学相机捕获单分子荧光信号
  • Java代理讲解
  • 常见网络安全攻击类型深度剖析(三):DDoS攻击——分类、攻击机制及企业级防御策略
  • AI编程:[体验]从 0 到 1 开发一个项目的初体验
  • 利用车联网中的 V2V 通信技术传播公平的紧急信息
  • 【深度强化学习 DRL 快速实践】异步优势演员评论员算法 (A3C)
  • PCIe具体解释分析
  • 【基础IO上】复习C语言文件接口 | 学习系统文件接口 | 认识文件描述符 | Linux系统下,一切皆文件 | 重定向原理
  • 【kafka初学】启动执行命令
  • c#操作excel表格
  • Java与Kotlin在Android开发中的全面对比分析
  • 【Luogu】动态规划四
  • Hot100方法及易错点总结2
  • firewalld 详解
  • 微信小程序蓝牙连接打印机打印单据完整Demo【蓝牙小票打印】
  • 【prompt是什么?有哪些技巧?】
  • Linux操作系统复习