街机模拟游戏逆向工程(HACKROM)教程:[4]MAME的作弊功能

需要对游戏进行逆向分析,我们首先需要了解游戏的内存系统。在一个游戏的运行过程中,游戏中所有的变动,比如玩家的血量,敌人的血量,玩家所在位置,场景的位置,剩余时间,等等一切,都在内存中有所体现。所有的数据,都保存在内存的某个地址。

比如一个玩家血量减少的大概逻辑为:

1、当被敌人攻击,程序分析敌人的攻击力数据。

2、从玩家血量的内存地址读取玩家的当前血量,把当前血量以敌人的攻击力大小减少相对应的值,再把已减少的值写入玩家血量的内存地址。

3、玩家的血量是否为空,如果为空,进入死亡程序分支。如果不为空,进入非死亡程序分支。

在这个逻辑下,我们首先需要知道玩家的血量的内存地址。我们如何找到玩家血量的内存地址呢,MAME内自带内存搜索指令,可以方便地搜索内存数据,下面,我们尝试用MAME自带的指令来搜索到"恐龙新世纪"游戏中1号机位对应玩家的血量。

我们搜索一个内存数据的逻辑为,我们首先在一定的情况下,把内存的所有数据保存下来,比如我们当前需要搜索玩家血量:

1、我们在玩家血量为满的情况下,把所有内存的数据保存下来。

2、我们再次进入游戏,利用敌人或其它方式让玩家的血量发生变化,再次搜索之前保存下来的数据,因为血量已经发生了变化,相对于之前的数据,血量的内存数据也必定发生了变化,我们把之前的数据与已变化的数据进行对比,筛选出已经发生变化的数据。

3、因为内存里的数据量通常比较大,虽然血量发生了变化,但可能有无数的数据也同样发生了变化,所以,我们通过不断地让血量发生变化,通过多次的筛选,来一步步地减少所筛选出来地址数量,直到找到对应玩家血量的地址。

我们介绍一下MAME内存搜索功能指令:

cheatinit(ci)            -初始化搜索选定的内存区域

cheatinit [[<sign>[<width>[<swap>]]],[<address>,<length>[,<space>]]]

参数1 
<sign> 可以是 u(表示无符号)或 s(表示有符号),
<width> 可以是 b(表示 8 位(字节))、w(表示 16 位(字))、d(表示 32 位(双字))或 q对于 64 位(四字); 
<swap> 可以是 s 来表示相反的字节顺序。  如果第一个参数被省略或为空,则使用上一次作弊搜索的数据格式,如果这是第一次作弊搜索,则使用无符号 8 位格式。

参数2
<address> 指定开始搜索的地址,
<length> 指定要搜索的内存量。  如果指定,将搜索 <address> 到 <address>+<length>-1(含)范围内的可写 RAM;  否则,将搜索地址空间中所有可写的RAM。
cheatrange(cr)        -添加选定的内存区域进行作弊搜索

cheatrange <address>,<length>

参数:
<address> 指定开始搜索的地址,
<length> 指定要搜索的内存量。  <地址> 到 <地址>+<长度>-1(含)范围内的可写 RAM 将添加到要搜索的区域。
cheatnext (cn)         -通过与之前的值进行比较来筛选对应的地址
cheatnextf(cn)         -通过与初始化的值进行比较来筛选对应的地址

cheatnext <condition>[,<comparisonvalue>]
cheatnextf <condition>[,<comparisonvalue>]

参数1:
all                                 更新最后的值
equal (eq)                          如果没有 <comparisonvalue>,则搜索与之前搜索相同的值;  使用 <comparisonvalue>,搜索等于 <comparisonvalue> 的值。
notequal (ne)                       如果没有<comparisonvalue>,则搜索不等于之前搜索的值;  使用 <comparisonvalue>,搜索不等于 <comparisonvalue> 的值。
decrease (de, -)                    如果没有<comparisonvalue>,则搜索自上次搜索以来减少的值;  使用 <comparisonvalue>,搜索自上次搜索以来减少了 <comparisonvalue> 的值。
increase (in, +)                    如果没有<comparisonvalue>,则搜索自上次搜索以来增加的值;  使用 <comparisonvalue>,搜索自上次搜索以来增加了 <comparisonvalue> 的值。
decreaseorequal (deeq)              搜索自上次搜索以来已减少或未更改的值(不使用 <comparisonvalue>)。
increaseorequal (ineq)              搜索自上次搜索后增加或不变的值(不使用 <comparisonvalue>)。
smallerof (lt, <)                   搜索小于 <comparisonvalue> 的值(<comparisonvalue> 是必需的)。
greaterof (gt, >)                   搜索大于 <comparisonvalue> 的值(<comparisonvalue> 是必需的)。
changedby (ch, ~)                   搜索自上次搜索以来已按 <comparisonvalue> 更改的值(<comparisonvalue> 是必需的)。

cheatlist(cl)            -显示已搜索相匹配的列表,或将它们保存到文件中

cheatlist [<filename>]


 

cheatundo(cu)         -撤消最后一次作弊搜索(仅限状态)

cheatundo

我们进入游戏来实际测试一下:

首先,我们进入游戏,最好的方式是保持满血,场景内保留一个敌人,场景内保留一个回血的道具,在"恐龙新世纪"中,比较好的地方为第一个场景进入门后会有一个回血道具,我们清理完场景,保留一个敌人和一个回血道具,在此时,我们保留一个存档:

此时,我们按键盘的"~"键进入DEBUG调试器,在命令框中输入:

ci

按F12回到游戏,让玩家的血量发生变化(被敌人攻击,或使用扣血技能,或拾取回血道具),发生了变化后,按"~"再次进入DEBUG调试器,在命令框中输入:

cn -

//如果血量减少时使用减号"-"参数;
//如果血量增加使用加号"+"参数;
//如果血量不变使用"eq"参数;

这里提示,对比筛选出59个对应的地址。

再次按F12回到游戏,让玩家的血量发生变化(被敌人攻击,或使用扣血技能,或拾取回血道具),发生了变化后,按"~"再次进入DEBUG调试器,在命令框中输入:

cn -

//如果血量减少时使用减号"-"参数;
//如果血量增加使用加号"+"参数;
//如果血量不变使用"eq"参数;

尽量多次循环以上步骤,直到得到的地址足够少,最好可以得到唯一地址。

如果未能得到唯一地址,可以使用命令:

cl

列出已经得到的地址列表,尝试一个个测试得到的地址。

我们现在得到了唯一的地址:FFB2E1

我们在调试器中,新建一个内存窗口:

输入我们得到的地址:

在68000中,我们最好使用偶数地址,比如FFB2E1,我们选择偶数地址:FFB2E0

 

我们可以看到,当前FFB2E1地址的值为3D,这是一个16进制值。也就是说,当前玩家的血量对应的值为3D,我们可以尝试在内存窗口把该值进得更改,鼠标选中该值,在键盘输入你想需要的值,如50:

回到游戏,我们会发现,血条并未发生变化,因为血量发生变化后,游戏的显示并未发生变化,这其中的逻辑为,当血量发生变化后,会调用血条显示的程序。但这时通过其它方法去更改玩家的血量时,程序并不会进入血条显示的程序。所以,在显示上,血条并未发生变化。我们尝试再次在游戏中让血量发生变化(被敌人攻击,或使用扣血技能,或拾取回血道具),才可以测试出,我们对血量的改动是否成功。

以上就是对于MAME搜索内存的介绍,几乎所有逆向工程的开始都基于对于内存的搜索,所以,在之后对于游戏的所有逆向研究,几乎都会用到内存搜索功能。建议对该功能更加详尽地了解。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【部署LLaMa到自己的Linux服务器】

部署LLaMa到自己的Linux服务器 1、Llama2 项目获取方法1&#xff1a;有git可以直接克隆到本地方法2&#xff1a;直接下载 2、LLama2 项目部署3、申请Llama2许可4、下载模型权重5、运行 1、Llama2 项目获取 方法1&#xff1a;有git可以直接克隆到本地 创建一个空文件夹然后鼠标…

Pandas加载大数据集

Scaling to large datasets — pandas 2.1.4 documentationhttps://pandas.pydata.org/docs/user_guide/scale.html#use-efficient-datatypes官方文档提供了4种方法&#xff1a;只加载需要的列、转化数据类型、使用chunking&#xff08;转化文件存储格式&#xff09;、使用Dask…

使用OAK-D双目深度相机为turtlebot3小型移动机器人添加视觉系统

编辑&#xff1a;OAK中国 首发&#xff1a;oakchina.cn 喜欢的话&#xff0c;请多多&#x1f44d;⭐️✍ 内容可能会不定期更新&#xff0c;官网内容都是最新的&#xff0c;请查看首发地址链接。 ▌前言 Hello&#xff0c;大家好&#xff0c;这里是OAK中国&#xff0c;我是Ash…

Postman中文文档——安装与更新

前言 postman好不好用&#xff0c;只有自己去用过了才知道&#xff0c;如果你之前没有使用过的&#xff0c;那我建议尝试去安装使用一下。 postman是一款支持http协议的接口调试与测试工具&#xff0c;其主要特点就是功能强大&#xff0c;使用简单且易用性好 。 无论是开发人…

Istio 实战:WasmPlugin(Proxy-Wasm 插件)功能拓展

功能一&#xff1a;添加 header&#xff08;在代码里写死的 header&#xff0c;不做修改&#xff09; 代码分析 主要是通过 proxywasm 库提供的 AddHttpRequestHeader 和 AddHttpResponseHeader 添加 header&#xff0c;同理可以实现 header 的删除和修改 部署生效 tinygo …

【控制篇 / 分流】(7.4) ❀ 02. 对不同运营商IP网段访问进行分流 ❀ FortiGate 防火墙

【简介】公司有两条宽带用来上网&#xff0c;一条电信&#xff0c;一条联通&#xff0c;访问常用的某些网站速度时快时慢。领导要求&#xff0c;根据上网流量的目标运营商IP归属&#xff0c;将流量送到相应的运营商出口去&#xff0c;避免跨运营商上网。那么应该怎么做&#xf…

vivado 使用IP Integrator源

使用IP Integrator源 在Vivado Design Suite中&#xff0c;您可以在RTL中添加和管理IP子系统块设计&#xff08;.bd&#xff09;项目或设计。使用Vivado IP集成程序&#xff0c;您可以创建IP子系统块设计。IP集成程序使您能够通过实例化和将Vivado IP目录中的多个IP核互连。可…

【PostgreSQL内核学习(二十一)—— 执行器(InitPlan)】

执行器&#xff08;InitPlan&#xff09; 概述InitPlan 函数代码段解释ExecInitNode 函数 总结 声明&#xff1a;本文的部分内容参考了他人的文章。在编写过程中&#xff0c;我们尊重他人的知识产权和学术成果&#xff0c;力求遵循合理使用原则&#xff0c;并在适用的情况下注明…

最新使用宝塔反代openai官方API接口搭建详细教程及502 Bad Gateway错误问题解决

一、前言 宝塔反代openai官方API接口详细教程&#xff0c;实现国内使用ChatGPT502 Bad Gateway问题解决&#xff0c; 此方法最简单快捷&#xff0c;没有复杂步骤&#xff0c;不容易出错&#xff0c;即最简单&#xff0c;零代码、零部署的方法。 二、实现前提 一台海外VPS服务…

SpringBoot教程(七) | SpringBoot解决跨域问题

SpringBoot教程(七) | SpringBoot解决跨域问题 上篇文章我们介绍了SpringBoot的拦截器的写法&#xff0c;其中有一个比较重要的步骤&#xff0c;就是把我们写好的拦截器注册到Spring的一个配置类中&#xff0c;这个类是实现了WebMvcConfigurer 接口&#xff0c;这个类很重要&a…

PRU pruss, rproc_pru和prueth uboot源码分析

概述 首先看一下PRU_ICSSG的功能框图&#xff0c;对于&#xff21;&#xff2d;&#xff16;&#xff14;来说&#xff0c;包含两个PRU_ICSSG模块。每个PRU_ICSSG共包含两个slice。 每个PRU core自己Local Instruction RAM, 容量不同。 PRU 内核执行任何指令之前&#xff0c;…

NXP-RT1176开发(一)——环境搭建(MCUXpressoIDE/VSCode)

目录 1. 安装IDE 1.1 官方开发的IDE软件 1.2 Config工具下载 1.3 说明&#xff08;需先有SDK&#xff09; 2. 下载SDK 3. VScode环境下编译 3.1 安装插件 3.2 确保本地有交叉编译工具链和CMAKE 3.3 加载本地SDK 3.4 导入例程编译 1. 安装IDE 该处理器编译规则可以MDK…

科普丨数据泄露防护DLP是什么(DLP数据泄露防护系统推荐)

在数字化时代&#xff0c;数据泄露的风险日益严峻&#xff0c;给企业和组织带来了巨大的威胁。为了应对这一挑战&#xff0c;数据泄露防护DLP&#xff08;Data Loss Prevention&#xff09;应运而生&#xff0c;成为保护数据安全的重要手段之一。 一、DLP数据泄露防护系统是什么…

高级RAG技术、以及算法实现

知识库地址&#xff1a;Advanced RAG techniques 检索增强生成&#xff08;Retrieval Augmented Generation, RAG&#xff09;为大语言模型&#xff08;Large Language Model, LLM&#xff09;提供了一种机制&#xff0c;通过从数据源检索到的信息为其生成的答案提供依据。简而…

C语言--质数算法和最大公约数算法

文章目录 1.在C语言中&#xff0c;判断质数的常见算法有以下几种&#xff1a;1.1.试除法&#xff08;暴力算法&#xff09;&#xff1a;1.2.优化试除法&#xff1a;1.3.埃拉托色尼筛法&#xff1a;1.4.米勒-拉宾素性检验&#xff1a;1.5.线性筛法&#xff1a;1.6.费马小定理&am…

【前端发版】vue前端发版 步骤

1、 提交代码 代码合并通过之后到deb分支 2、git checkout 切换到dev分支上 运行起来看看自己刚刚提交的代码有没有错误 3、拉取最新代码 git pull 3、yarn run build 4、打包好的文件叫dist 重新命名为服务器里替换包名 5、登录文件传输 开始替换 替换的过程中 首先删除备…

如何一台电脑操作两个adb 设备

1.首先使用 adb devies 命令 2.然后使用 adb -s 上面的返回的id号 shell 进入对应的开发板

优化您的服务请求,增强用户体验和服务交付

您的服务请求模板是否像一个复杂的迷宫&#xff0c;给您的团队带来延误和困惑&#xff1f;您的技术人员是否厌倦了为了解最终用户的需求而与他们来回奔波&#xff1f;强大且可定制的请求模板可能正是您所需要的&#xff01; 服务交付团队&#xff08;尤其是 IT&#xff09;的…

ubuntu服务器安装Slurm

相关内容&#xff0c;网上不少&#xff0c;这里记录一下自己出现的问题和解决方法&#xff0c;采用的是Ubuntu22.04&#xff0c;方法可以参考知乎上面这篇文章Ubuntu服务器安装配置slurm&#xff0c;整个安装过程没有什么问题&#xff0c;主要步骤贴在这里但在使用过程中&#…

Vue3响应式系统(一)

一、副作用函数。 副作用函数指的是会产生副作用的函数。例如&#xff1a;effect函数会直接或间接影响其他函数的执行&#xff0c;这时我们便说effect函数产生了副作用。 function effect(){document.body.innerText hello vue3 } 再例如&#xff1a; //全局变量let val 2f…