CS420 课程笔记 P8 - 如何编辑汇编代码 (最终篇)

news2024/10/7 14:33:01

文章目录

    • Intro
    • Hardware
    • Return to virtual memory
    • Compiler
    • Finding assembly code
    • Example!
    • Assembly language
      • Registers
    • Assembly Example
      • Inc
      • Dec
      • Add
      • Sub
      • Mov!
      • Neg
      • Mul
      • Div
    • Assembly problem
    • 恭喜 Congratulations!

Intro

大多数人在走到这里之前就退出了,这里是 game hacking 开始变得真正有趣的地方,我们将开始学习程序集编辑,也就是汇编编辑,我们将依靠这个重写游戏代码,以使其执行我们希望它执行的操作,如果您从未编写过游戏也不要担心,课程接受你将学会使用汇编语言轻松开发自己的 game hacking command-line,同样的你也可以将这一过程看为:

  1. Find relevant assembly code
  2. Change it
  3. See if it worked

这里第一点和第二点实际上是2个不同方面的内容,他们都具有自己的学习曲线,找到汇编代码首先要知道汇编代码是什么以及如何工作

Hardware

首先我们先要了解一些硬件的知识,你的电脑有一个 CPU,复制处理代码,制造商决定哪些代码可以在 CPU 上面运行

  • x86/x64 台式机、笔记本、现在的 PS、XBOX 属于这个架构,绝大多数的关注重点
  • ARM 智能手机和手持设备倾向于使用 ARM,功效更高,功耗更好
  • PowerPC 一些旧游戏机使用它,你可能永远不会看到他除非现在回去深入他们

Return to virtual memory

我们重新审视虚拟内存中的数据排布,在 copied exe 和 DLL 中不止有静态数据还有静态代码,现在是我们学习代码的时候了

c7 40 04 32 00 00 00 90 83 6d f8 fc 48 8d 04 24 ff d5 …

现在我们可以把这些代码分组为汇编指令语言,并且不用担心理解这些东西

  • mov [rax+04],32 - C7 40 04 32 00 00 00 组成移动指令
  • nop - 90 组成无操作指令
  • sub dword ptr [rbp-08], -04 - 83 6D F8 FC 减法指令
  • lea rax, [rsp] - 48 8D 04 24
  • call rbp FF D5

在我们阅读 FF D5 时可以说他们是机器语言,但当我们把他们分组成一条指令,即汇编语言之后,就可以把相同的信息垂直堆栈起来,这就是大部分 game hacking tool 显示汇编语言的方式

Compiler

直接使用汇编工作是枯燥乏味且容易出错的,所以现在有 C、C++ 这样的高级语言,C++ 转换成汇编代码的过程就是编译器工作的过程,让我们看看编译器是如何工作的

大多数游戏都是用 C++ 编写的,游戏开发人员可以将 C++ 编译成机器语言,这对 game hacking 工作人员来说是不可读的,所以我们把机器语言 Disassembling 成汇编语言,然后我们可以编辑汇编语言以重新编程游戏

但想把机器语言逆向回 C++ 代码是不太可能的,让我们打开 godbolt.org 网站看看,他基本给你展示了 C++ 代码和汇编语言之间的联系

常见的第二个技术是 C#,当代许多游戏都是用 Unity 制作的,Java 也是一样的

这里视频作者放了一系列 PPT 来介绍 python、game maker 等等,说明了为什么 C++ 游戏比较适合汇编修改

如何确认游戏是用什么语言写的?

  1. 打开游戏文件夹
  2. 如果看到 Mono 一般是 Unity C#
  3. 看到 ue3 un4 一般是虚幻引擎制作也就是 C++

Finding assembly code

如何找到汇编代码?一个游戏可能有上百万行汇编指令,我们的目标只是找到其中的一条指令,例如伤害玩家的代码,或者购买物品时夺走我们金币的代码。

比方说,我们玩家的健康状况存储在玩家对象中,现在在 C++ 游戏中,所有代码都存储在 exe 中,所以我们知道 Player 对象处的代码负责更新此处玩家的生命值,我们的目标是找到那里的代码,我们可以在玩家的血量处设置一个叫做数据断点的东西,他会准确告诉我们 exe 中的哪一行代码尝试访问或更新玩家的生命值

Example!

首先我们还是启动游戏,然后仍然是去找到生命值或者金钱之类的你感兴趣的数值,想要找到编辑此数值的代码能做的就是右键然后点击 Find out what writes to this address,或者 Find out what accesses this address 正在读取这个数值的地址比如说死亡检测之类的东西。

比如我们查找是什么让我们受伤,肯定是有什么写入了数据,所以这里选择 Find out what writes to this address
在这里插入图片描述
当我们在游戏中改变这个数值时,会发现多了一条指令出现在这个列表
在这里插入图片描述
我们选中它并选择 Add to the codelist,最好给出一个名字比如 update gold / update health
在这里插入图片描述
在这里插入图片描述
很酷的是,我们可以右键 codelist 中的这条指令然后将其替换为不执行任何操作的代码,当然你也可以随后选择恢复成原来的代码样子。

我这里是植物大战僵尸的金币增加代码,如果这样做了,将会导致后续不再能够获取金币。

在这里插入图片描述
让我们重新打开植物大战僵尸,选择阳光作为我们的关注对象,当我们使用一个卡牌时可以捕获到这样一条指令

在这里插入图片描述
如果我们把它替换成 nop 无操作指令,在游戏中使用阳光你会发现什么都没有发生,没有阳光被消耗了(这里的逻辑是消耗,增加阳光或者其他更改阳光数值的逻辑途径不受影响!

不幸的是,有些游戏的受伤或者治疗代码适用于所有对象,也就是说,你不会受到伤害了,但怪物也不会了,这不是我们想要的

在这里插入图片描述
一个重要的点是:动态地址再重启游戏后不再会有效,但你找到的这些 code 他们是不会有变化的,因为这些代码都存放在 exe 中

Assembly language

所以我们找到了我们感兴趣的代码,也许可以用一些 nop 无操作指令来填充他,这对 90% 情况都够用了,我们可以把伤害玩家、夺走玩家金币的代码删除。但在某些情况下编写自定义汇编能够更有价值,但我们要先学会汇编语言

Registers

第一个概念是寄存器,寄存器是 CPU 中的临时存储,在我们深入了解我们需要的寄存器之前,了解代码如何在硬件上运行。我们知道当用户双击一个 exe 时,他会从硬盘复制到 RAM 中,但是我们需要该代码在 cpu 上运行,而 cpu 存储空间非常之小,我们不能只是复制所有游戏代码到 cpu 里面,因此,所有的代码都是逐行传输到 cpu 中,就像视频网站传输视频一样。

但是存在一个小问题,Code ‘streamed’ to CPU,但有时代码需要访问数据,CPU 可能会运行一些代码来读取玩家的生命值,然后更新一下数据再放回 RAM 中,不幸的是从 CPU 访问 RAM 实际上是相当昂贵的,所以人们在 CPU 上面放置了非常少量的存储空间,这就是寄存器

  • 硬盘离 CPU 非常远,访问速度相当慢,但存储相当多的东西
  • 内存离 CPU 较近,速度较快,中等存储量
  • CPU Memory 离 CPU 最近,速度最快,但容量极小

内存通过 L3 Cache -> L2 Cache -> L1 Cache(Code/Data) -> Registers 进入寄存器,其中1级缓存具有2个部分,分别存储代码和数据。幸运的是,对我们来说不需要关注中间的 Cache 缓存,只需要了解 Registers 中发生了什么即可

在我们想要进行操作之前我们要先把数据放到寄存器中,这样我们可以把玩家的生命值放到寄存器里,然后加载一些我们可能造成的伤害,然后把两者进行减法,然后写回 RAM 中

这是 32-bit game 中寄存器的示例,在 32-bit 计算机中寄存器有 4bytes :

  • EAX 0000 0064
  • EBX 0000 0005
  • ECX 0000 002C
  • EDX 0000 0019
  • EDI 018B 1000
  • ESI 018B 1000
  • EBP 6FF9 30CC
  • ESP 6FF9 3070
  • EIP 02C1 A07B

如果我们把游戏在此时冻结,可能会注意到 EAX = 64 可能是玩家的生命值,EBX = 5 可能是玩家即将受到的伤害

而 64-bit game 其实是类似的,只是寄存器长度翻倍为 8bytes,而且寄存器以 R 开头而不是 E:

  • x86 Assembly 32-bit games, push eax
  • x64 Assembly 64-bit games, push rax

x86 实际上是 intel 早期一些 cpu 命名,而 64-bit 出现时他们必须给一个新名字,所以就又变成了 x64,这看起来似乎有些愚蠢

区分 32位 和 64位 游戏很简单,当你使用你的 Tools 打开游戏看看里面的寄存器是 R 开头还是 E 开头就可以了,其他几乎一样

在寄存器中不要随便弄乱 EBP ESP EIP 这三个,他们一般用来指向下一条指令,而其他的指令一般都作为 General use,可以作为重点关注对象

Assembly Example

Inc

inc ecx 执行时给 ecx 的值 + 1
int [eax] 执行时给 eax 地址所在的值 + 1,比如 eax = 50393088,那么在地址 50393088 值为 12 变成了 13
int [edi + 8] 沿着 edi 地址,向下经过2个整数(4bytes),自增那个位置的数值

Dec

和 inc 的操作完全一样,只是变成了减 1

Add

add 拥有了2个寄存器作为参数
add eax, 2 给 eax 加 2
add ecx, edx 给 ecx 加 edx
add [ebp + 8], esi 结合上面的 Inc,也是类似的

Sub

和 add 的操作完全一样,只是加法变成了减法 subtracts

Mov!

比较重要的一个是 mov 移动指令,移动的工作原理是将一个值复制到该寄存器中
mov ebx, 200 200 覆盖到 ebx 上面
mov ecx, edx edx 的值覆盖到 ecx 上面
mov [eax], 10 10 覆盖到 eax 所在的地址位置
下面的省略,仍然和上面的指针版本一样,但需要注意的是,你不能在这里写 2个带 [ ] 的东西,比如 mov [eax], [edx] 这是不可能的,从 CPU 访问 RAM 的代价是昂贵的

Neg

neg 是一个简单的指令,只是对数字取反

Mul

mul 也是一个简单的指令,和 add 一样只不过现在是乘法 mul ebx, 2

Div

div 是所有指令中最令人恼火的一条,它的工作方式和乘法不同,只有一个寄存器可以作为参数传递给他
div ecx 比如此时 eax = 120,ecx = 12,当你执行这个指令时就会 使得 eax 除以您传递的任何值
当你执行之后 eax = 10, ecx = 12,如果你再执行一次,eax = 0,整数部分显然是 0,随后余数将会到 ecx 里面也就是 ecx = 2,这是非常奇怪的,他的工作方式和其他指令都不一样,可以尝试避免使用他!

Assembly problem

我们可以尝试着手修改,做一些简单事情作为例子,视频中使用了扫雷,将自增改变为 +2,随后你会发现一个问题,我们填写的代码长度和原有的代码长度不符,exe 的长度是固定的,我们不可能改变这里的代码长度
在这里插入图片描述
正确的思路是:生成一个新的代码块并分配新的内存,在那里编写代码并运行
在这里插入图片描述
现在我们选中这条指令,点击 Tools 里面的 Auto Assembly 或者按下 Ctrl + A
在这里插入图片描述
填入上面的内容以后点击 Template 里面的 Code inject,注意这里一定要选中你要修改的那条指令
在这里插入图片描述
在这里插入图片描述
这样就会生成一段 Code injection 代码,你可以删除一些自动生成的注释,同时记得把上面的 label 也删除:
在这里插入图片描述
在这里插入图片描述
总之,上面的 [Enable] 代码块包含了当我们启动时运行的代码,[Disable] 包含了当我们禁用时的代码。你会发现代码先通过alloc申请了内存,然后在 “popcapgame1.exe”+1F634 跳(jump)到了newmem内存块,所以我们现在可以在 newmem 上面进行修改了,比如把 sub 改成 add 这样的操作
在这里插入图片描述
然后我们选择 File - Assign to current cheat table 加入当前的 CE 表
在这里插入图片描述
接下来选中他最左一列的 Active 或者选中按空格就可以启动这个 Script 了,种下太阳花发现果然阳光不再减少而是加了 2!
在这里插入图片描述

恭喜 Congratulations!

到这里你已经掌握了 game hacking 的基础了,随着后续精进汇编语言,了解更多 game hacking 方法,你将学会游戏逆向的大多数内容。

作为一名游戏开发者,后续将更新如何应对这些 game hacking,也就是 anti-cheat 的基本思路和方法,敬请期待!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/973805.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

nginx--技术文档--基本概念--《十分钟快速扫盲》

nginx是什么? Nginx是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。它具有高并发性、稳定性和灵活性,并且使用事件驱动的方式处理请求,能够有效地处理大量并发连接。此外,Nginx还具有高效的内…

总结开发中一些数据处理方法的封装

摘要: 开发中经常会遇到一些组件需要的特定数据结构,后端不一定会返回你需要的数据结构的,所以还是要前端来处理的!这里来总结一下平常开发中遇到的需要处理结构的方法,下次遇到直接拿来用就可以了! 目录概…

云架构师学习------技术路线与总结

云架构师学习------技术路线与总结 云架构师学习------技术路线与总结一、什么是架构IT架构-数据架构-应用架构IT架构应用架构数据架构 架构的六个层面基础设施层数据层中间层基础服务层业务服务层用户接口层 二、云计算的历史演进与基本原理云计算的本质:资源到架构…

小度音响 小众安卓手机 个别车机等系列mtk芯片刷机 修改 导出系统 root等操作解析

目前很多机型采用的是mtk芯片。包括小度1C.个别车机 或者其他安卓设备。这类机型很少有官方固件或者未曾流出。有的机型限制刷机 root 安装软件等等。那么类似的设备有没有方法来root或者导出系统呢。其实前面几篇博文中我有介绍如何提取备份mtk芯片的系统。今天在这些博文的基…

企业文件数据透明加密保护——防泄密软件系统

天锐绿盾电脑文件数据透明加密、防泄密系统是一款全面的加密软件系统,主要从源头上保障数据安全和使用安全。该系统采用文件过滤驱动实现透明加解密,对用户完全透明,不影响用户操作习惯,从源头上保障企业数据安全。通过对电子文档…

ajax day2

1、 2、控制弹框显示和隐藏: 3、右键tr,编辑为html,可直接复制tr部分的代码 4、删除时,点击删除按钮,可以获取图书id: 5、编辑图书 快速赋值表单元素内容,用于回显: 6、hidden …

python开发之个微机器人的二次开发

简要描述: 取消消息接收 请求URL: http://域名地址/cancelHttpCallbackUrl 请求方式: POST 请求头Headers: Content-Type:application/json 参数: 参数名类型说明codestring1000成功,1…

MySql学习笔记12——数据库设计三范式

数据库设计三范式 第一范式:要求任何一张表必须有主键,每一个字段原子性不可再分。 第二范式:建立在第一范式之上,要求所有非主键字段必须完全依赖主键,不能部分依赖 第三范式:建立在第二范式之上&#…

分享2款微课录制软件,保证让你满意!

“录微课用什么软件呀,真的服了,平台自带的录屏画质太差了,完全看不清讲的内容,而且音质也不是很好,大家有没有微课录制的软件推荐,谢谢啦” 随着教育方式的转型和技术的发展,微课程成为了一种…

虚拟机(三)VMware Workstation 桥接模式下无法上网

目录 一、背景二、解决方式方式一:关闭防火墙方式二:查看桥接模式下的物理网卡是否对应正确方式三:查看物理主机的网络属性 一、背景 今天在使用 VMware Workstation 里面安装的 Windows 虚拟机的时候,发现虽然在 NAT 模式下可以…

2023年9月NPDP产品经理国际认证报名,当然弘博创新

产品经理国际资格认证NPDP是新产品开发方面的认证,集理论、方法与实践为一体的全方位的知识体系,为公司组织层级进行规划、决策、执行提供良好的方法体系支撑。 【认证机构】 产品开发与管理协会(PDMA)成立于1979年,是…

C#,数值计算——NRf1(UniVarRealValueFun)的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { public class NRf1 : UniVarRealValueFun { public RealValueFun y1; public RealValueFun y2; public NRf2 f2; public NRf1(RealValueFun y1, RealValueFun y2, RealValueFun z1,…

IMAU鸿蒙北向开发-2023年9月4日学习日志

1 HarmonyOS 1.1 南向设备开发与北向应用开发 上北下南,上层应用开发叫北向,底层设备开发叫南向。 北向:指的纯应用软件开发,基于官方提供的系统SDK进行应用开发,HarmonyOS 目前支持使用java、js、 ets、c、c进行开发…

丢失msvcp110.dll是什么意思?msvcp110.dll丢失的解决方法

当您在使用电脑时,可能会遇到这样的提示:“由于缺少msvcp110.dll文件,无法启动此程序。”那么,丢失msvcp110.dll到底是什么意思呢?又该如何解决这个问题呢?接下来,我将为您详细解答。 丢失msvcp…

笔记本家庭版本win11上win+r,运行cmd默认没有管理员权限,如何调整为有管理员权限的

华为matebookeGo 笔记本之前有段时间不知怎么回事,打开运行框,没有了那一行“使用管理权限创建此任务”,而且cmd也不再是默认的管理员下的,这很不方便,虽然每次winr ,输入cmd后可以按ctrlshitenter以管理员权限运行&am…

八路DI八路DO,开关量远程IO模块,Modbus TCP数据采集模块 YL90-RJ45

特点: ● 八路开关量输入,八路开关量输出 ● DI状态变化自动发送状态数据,可以捕获脉冲 ● 采用Socket自由协议编程简单、轻松应用 ● 开关量毫秒级响应速度适应多种场合 ● 内置网页功能,可以通过网页查询与控制 ● 同时也…

微型计算机原理知识点总结(一)

目录 一.微型计算机 二.微型计算机系统 1.微型计算机硬件系统 冯诺依曼体系结构 总线 (1)微处理器(CPU) 运算器 控制器 内部寄存器 (2)存储器 1.基本概念 2.内存的操作 3.内存的分类 (3)I/O接口与输入/输出设备 2.微型计算机软件系统 (1)系统软件 操作系统 …

SpringBoot实现发送邮件功能

平时注册或者登录一个网站时,可能收到过邮件用来发送验证码等,邮件在项目中经常会被用到,比如邮件发送通知,比如通过邮件注册,认证,找回密码,系统报警通知,报表信息等。 发送邮件用…

第一次做接口测试用例

一、简介 在开始接口测试之前,我们想一下,接口测试的流程是什么?说到这里,有些人就会产生好奇和疑问,心里mmp:接口测试要什么流程哈???不就是参考接口文档,直…

金蝶云星空对接打通赛意SMOM委外退料单接口与保存ASN数据接口

金蝶云星空对接打通赛意SMOM委外退料单接口与保存ASN数据接口 对接源平台:金蝶云星空 金蝶K/3Cloud(金蝶云星空)是移动互联网时代的新型ERP,是基于WEB2.0与云技术的新时代企业管理服务平台。金蝶K/3Cloud围绕着“生态、人人、体验”&#xff…