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

C++游戏分析与破解方法介绍

1、C++游戏简介

目前手机游戏直接用C++开发的已经不多,使用C++开发的多是早期的基于cocos2dx的游戏,因此我们这里就以cocos2d-x为例讲解C++游戏的分析与破解方法。

Cocos2d-x是一个移动端游戏开发框架,可以使用C++或者lua进行开发,也可以混合使用。在使用C++开发时,游戏主逻辑模块默认名字是“libgame.so”,跟其他的native模块一样,放在游戏的“lib”目录下。也就是Android手机上的“/data/app-lib/包名/”目录,或者直接apk解包后的“lib\armeabi-v7a”目录,其中“armeabi-v7a”取决于当前CPU架构。

为了进一步确定游戏引擎,可以把“libgame.so”载入IDA分析,搜索是否有包含“cocos2dx”字符串的函数名,如图:
在这里插入图片描述
由于cocos2d-x引擎也支持lua,可以继续搜索lua相关函数,如果没有搜到,基本可以确定这个游戏是基于cocos2d-x引擎且使用C++编写的游戏。

2、C++基础

C++语言以及C++程序的逆向分析是很大的话题,这里仅简单提一下,如果读者很欠缺C++相关的知识,应该先找相关书籍学习,不可急于求成。

2.1 类指针

C++语言是兼容C语言的偏底层语言,因此在介绍C++的面向对象的概念之前首先需要了解一下指针。

通常语境下,我们说“指针”其实全称是“指针变量”,也就是说它其实是一个变量,“指针”其实就是“内存地址”的意思,所以“指针变量”就可以理解为“内存地址变量”,就是一个保存内存地址的变量。对应的,不同类型的指针,说的就是那个内存地址保存的变量的类型,比如“函数指针”,我们就可以理解为,这是一个变量,这个变量保存的是一个地址,这个地址指向的位置是一个函数。

“类指针”就是一种指针变量,这个指针的类型不是C++的基本类型,而是我们自定义的“类”。类指针通常用来作为基址,索引类的成员变量,或者虚函数。所谓“基址”,跟汇编中说的基址是一个意思。

2.2 虚表

如果一个类有虚函数,那么它的内存结构中,头部就首先会有4个字节用来存储一个指针变量。这个指针变量就叫“虚表指针”,它指向的位置是一个函数指针数组,这个数组就叫“虚表”,也就是一连串的函数地址。这个数组里的每一个元素,都是这个类的虚函数的地址。同一个类的所有对象共享一个虚表。如果两个类的虚函数不同,那么就会有不同的虚表。

虚表稍微了解即可,它的存在主要是为了实现多态。这里介绍是方便大家了解类的内存结构,如果一个类有虚函数,则它实例的头部4个字节留给虚表指针,其余位置放置成员变量;如果没有虚函数,则内存全放置成员变量。

2.3 类的成员函数

类的成员函数与一般的全局函数或者静态函数唯一的区别在于,它的第一个参数是一个“隐式”的参数,这个参数就是它所属的对象的this指针。“隐式”说的其实是在语言层面看不见,但是在汇编代码中可以看到。

所以在分析的时候如果看到函数的第一个参数是一个指针,那它可能就是一个对象的指针,而这个函数就有可能是个成员函数。

3、C++游戏分析方法

C++编写的游戏分析起来会相对要难,但具体修改起来就会相对简单,因此破解的重点还是在如何找到关键的函数,或者关键的数据。这是一个逆向发散的过程,因此有许多方法都可以尝试。

这里仅讨论无符号或者仅有少数与游戏逻辑无关的符号下的游戏逻辑模块的分析。区分一个游戏逻辑模块有无符号,可以简单地通过在IDA的函数列表中搜索关键字符串看结束,比如“HP”、“Boss”、“Player”等。

有符号的情况相对就会简单很多,因此如有可能,最好拿到有符号的样本进行分析。有符号的模块样本通常会出现在游戏早期版本,或者某个特定的版本由于开发人员的疏忽而遗漏出来。尽管版本会不一致,但还是有很多可以借鉴的地方。

常规的C++程序逆向分析就是通过看汇编代码,从而理解函数的功能。也可以通过函数的参数以及返回值去猜测函数功能,最后通过理解一个个函数功能而把整个程序的流程厘清,再找到关键点。这是一个费时费力的过程,因此一般仅用在关键函数分析处。整个分析过程还是有许多其他的技巧和方法可以提高效率,下面就介绍几个常用的方法。

3.1 借助字符串信息

由于游戏开发过程中免不了要打印Log用于调试,或者由于别的原因在程序中保留了敏感字符串信息。因此直接在IDA中按快捷键“Shift+F12”列出所有字符串就可以获取到相当多的信息。如图:
在这里插入图片描述
根据字符串信息,可以索引到相关函数,方便对函数的功能进行分析。

3.2 send函数回溯

游戏总会进行网络通信,而Android系统底层处理网络通信的函数就是send函数。动态调试的时候可以在send函数处下断,就可以断到游戏与服务器的交互数据。但send函数过于底层,一般游戏都会有加密,这里断到的数据通常都是加密后的数据,因此需要向上回溯。

在向上回溯的过程中同时注意分析各层函数的作用,有些只是send函数的封装,有些就可能会涉及到加密,或者组包。我们的目的是找到组包函数和它的上层。在组包函数处修改,就可以影响游戏与服务器的底层通信数据;组包函数的上层一般就是功能函数,直接修改功能函数就可以影响游戏逻辑,最终可以更“自然”地影响到游戏的封包。

这个过程中可以借助IDA脚本,过滤一些频繁调用的函数,比如心跳函数;也可以打印log,分析调用来源和它们的调用频率。

3.3 输出log

在一些频繁被调用的函数,或者是有明文信息的函数处,如果有必要,也可以采用IDA脚本编程的方式打印log进行分析。如果调用过于频繁,脚本的速度跟不上,也可以采用注入进程并下Hook的方式打印log,速度就会快很多。具体的注入方法详见其他篇,这里不多说。

4、破解

C++游戏的破解相对比较简单,通常都是注入游戏进程,然后干涉游戏逻辑,具体来说可以用以下几种方法:

   1、Hook关键函数,修改传入参数。比如存在一个set_MaxHP函数,可以修改传入的参数,修改怪物或者玩家的血量。2、Hook关键函数,修改返回值。比如存在一个computeDamge函数,可以修改函数的返回值,实现秒怪或者无敌的功能。3、Hook关键函数,多次调用。比如存在一个hit函数,可以多次调用该函数实现多次打击。4、Hook关键函数,直接返回。比如存在一个dead函数,直接跳过执行,可以实现不死效果。5、直接修改判断逻辑。注入到进程,或者远程ptrace后直接在二进制层面直接修改汇编指令。比如存在一个判断,杀怪数大于10则通关,可以修改为杀怪数小于10则通关。

相关文章:

C++游戏分析与破解方法介绍

1、C游戏简介 目前手机游戏直接用C开发的已经不多,使用C开发的多是早期的基于cocos2dx的游戏,因此我们这里就以cocos2d-x为例讲解C游戏的分析与破解方法。 Cocos2d-x是一个移动端游戏开发框架,可以使用C或者lua进行开发,也可以混…...

食堂总是拥挤不堪?解决用餐拥挤,教你一招

随着近几年科技的快速发展,行业里出现了很多新的名词,比如智慧社区、智慧旅游、智慧建筑,那么智慧食堂是什么呢?它又是如何实现全自助、全智能消费? 在先进的智能技术以及市场需求带动下,智慧食堂经历了由传…...

ubuntu系统安装时 MBR和GPT的区别

主引导记录(Master Boot Record , MBR)是指一个存储设备的开头 512 字节。它包含操作系统的引导器和存储设备的分区表。   全局唯一标识分区表(GUID Partition Table,缩写:GPT)是一个实体硬盘…...

我在windows10下,使用msys64 mingw64终端

系列文章目录 文章目录系列文章目录前言一、MSYS2是什么?前言 msys2官网 MSYS2 (Minimal SYStem 2) 是一个MSYS的独立改写版本,主要用于 shell 命令行开发环境。 同时它也是一个在Cygwin (POSIX 兼容性层&#xff09…...

个人2023FALL CS申请总结(PhD/MPhil/保研夏令营)

个人2023FALL CS申请总结(PhD/MPhil/保研夏令营)写在最前个人BG及申请情况个人BG申请情况MPhilPhD收获一句话总结:心态爆炸没用,脸皮够厚够勇就行 写在最前 真是一场恶战。有几天,我每天早上都海投几封套瓷邮件&…...

【优化算法】使用遗传算法优化MLP神经网络参数(TensorFlow2)

文章目录任务查看当前的准确率情况使用遗传算法进行优化完整代码任务 使用启发式优化算法遗传算法对多层感知机中中间层神经个数进行优化,以提高模型的准确率。 待优化的模型: 基于TensorFlow2实现的Mnist手写数字识别多层感知机MLP # MLP手写数字识别…...

CAM类激活映射 |神经网络可视化 | 热力图

文章目录前言:安装库:分类案例--ResNet50分割案例AttributeError: ‘tuple‘ object has no attribute ‘cpu‘RuntimeError: grad can be implicitly created only for scalar outputsTypeError: cant convert cuda:0 device type tensor to numpy. Use…...

RecyclerView+BaseRecyclerViewAdapterHelper显示不全只显示第一行item的解决问题

RecyclerViewBaseRecyclerViewAdapterHelper显示不全只显示第一行item,我懵了…,我不说多,直接说吧 先看一下适配器代码中的convert()方法: class MineRadioAdapter(layoutResId: Int R.layout.item_my_live) :BaseQuickAdapte…...

解决后端无法对前端的ajax请求重定向

本章目录: 问题描述 AJAX请求后端直接重定向失败解决方案 后端拦截请为响应头添加重定向标志后端拦截器为响应头添加重定向路径前端响应拦截器获取响应头数据,并通过location.href url 完成页面跳转一、问题描述 本来想在拦截器里设置未登录用户访问指…...

【Python】1分钟就能制作精美的框架图?太棒啦

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言一、准备二、基本使用与例子1.初始化与导出2.节点类型3.集群块4.自定义线的颜色与属性总结前言 Diagrams 是一个基于Python绘制云系统架构的模块,它能…...

淘宝必备的补单技巧及注意事项!

补单,是优化善后的s单。单只是模拟用户的购物习惯,而补单同时还要模拟整个店铺的综合数据,包括点击率、转化率等等,补到略高于同行、竞品的平均数据时,淘宝会判断为买家比较喜欢你的商品,从而给你更多推荐机…...

【实用篇】SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud分布式

文章目录一、服务拆分1.1 服务拆分Demo1.2 微服务远程调用二、Eureka2.1 Eureka原理2.2 Eureka-server服务搭建2.3 eureka-client服务注册2.4 eureka-client服务复制2.5 eureka服务发现三、Ribbon负载均衡3.1 负载均衡原理3.2 负载均衡策略3.3 自定义负载均衡策略3.4 饥饿加载与…...

私人飞机、公务机包机会成为富豪圈的主流出行方式吗?

从炫耀性消费到按需使用,私人飞机的消费群体正在被拓宽,但离“成为主流”还有一段距离。“时间就是金钱”为有钱人消费私人飞机提供合理动机,而这群高净值人群的数量增长则成为撑起市场基本面。据相关数据显示,2018年全球超级富豪…...

Oracle组织架构

组织架构 (一)业务组(BG) (二)法律实体(LE) (三)业务实体(OU) (四)库存组织(INV) …...

最小公倍数

目录 最小公倍数 程序设计 程序分析 最小公倍数 【问题描述】给定两个正整数,计算这两个数的最小公倍数。 【输入形式】输入包含多组测试数据,每组只有一行,包括两个不大于1000的正整数. 【输出形式】 对于每个测试用例,给出这两个数的最小公倍数,每个实例输出一行。…...

二叉树的后序遍历(力扣145)

目录 题目描述: 解法一:递归法 解法二:迭代法 解法三:Morris遍历 二叉树的后序遍历 题目描述: 给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 。 示例 1: 输入:root …...

《Effective C++》读书纪实 -- 诸君同享

文章目录《Effective C》是一本经典的C编程指南,共包含50条C编程的最佳实践。 确定你的构造函数的行为 在构造函数中,应该尽可能地避免调用虚函数、非静态成员函数和虚基类的函数。 尽量使用const、enum、inline替换#define 使用const、enum、inline可以…...

【云原生】K8S-ConfigMap 实现应用和配置分离

文章目录前言ConfigMap 背景ConfigMap 创建方式ConfigMap 的使用使用 ConfigMap 的注意事项总结前言 Kubernetes 是目前最流行的容器编排系统之一,它提供了丰富的功能来支持容器化应用程序的管理和部署。 ConfigMap 是 Kubernetes 中重要的资源对象,用…...

java -测距工具(经纬度)

代码 /*** 测距工具* author qb*/ public class DistanceUtils {/*** 赤道半径*/private static final double EARTH_RADIUS 6378.137;private static double rad(double d) {return d * Math.PI / 180.0;}/*** Description : 通过经纬度获取距离(单位:米)* Group…...

postgres分区表的创建-基于继承

参考文档: http://postgres.cn/docs/12/ddl-partitioning.html 创建基于继承的分区表的步骤 1 创建父表 2 创建子表,从父表继承过来 3 创建函数及触发器,使插入的数据根据规则,插入到对应的子表中 -- 创建父表 CREATE TABLE a…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

css实现圆环展示百分比,根据值动态展示所占比例

代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

Java面试专项一-准备篇

一、企业简历筛选规则 一般企业的简历筛选流程&#xff1a;首先由HR先筛选一部分简历后&#xff0c;在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如&#xff1a;Boss直聘&#xff08;招聘方平台&#xff09; 直接按照条件进行筛选 例如&#xff1a…...