NS版暗黑破坏神3金手指开发教程(4)

article/2025/10/4 12:05:17

上一节,我们讲了基于公式明文的金手指制作方法,这一节,我们将进阶到更高级的基于程序修改的金手指制作方法,从现在开始,对读者的技术水平有了一个更高的要求,读者最好有汇编和C/C++高级语言的一些基础,至少了解过汇编,这样不会太吃力

1. 运行神器IDA,然后打开原始版本的DiabloIIINX64ra.elf ,等待反汇编完成(因为带调试符号,时间可能比较长,请耐心等待,或者去做一些其他事情,大概在10分钟左右,与电脑配置有关,输出窗口显示内容不再更新代表已经完成),如果每次打开IDA窗口布局不对,或者少了一些窗口,建议点击窗口->重设窗口来复位一下布局。

2. 我们要修改的是远古传奇掉落机制,所以要先搜索远古的英文ancient,首先点击左边函数窗口里任意一个函数,然后在编辑里点击快速筛选,然后左下方输入ancient,不出所料,筛选后的函数只剩下6个,分析一下名称,可以知道最有可能的是LootRollForAncientLegendary这个函数,因为字面意思就是对战利品随机出远古传奇,然后我们双击这个函数,可以在右边的IDA View里看到这个函数的汇编代码

3. 因为汇编代码直接看不是很好看,我们可以在视图->子视图->生成伪代码或者直接按F5生成伪代码,怎么样,很惊喜吧,汇编代码直接被翻译成C++风格的伪代码了,这样很利于我们分析程序逻辑

4. 沿着函数伪代码往下拉,在接近函数底部的时候我们发现了一些非常可疑的代码,if ( (float)((float)RandGetDWord(v28) * 2.3283e-10) <= v27 ) v2->eAncientRank = 2; 这一句非常重要,根据函数名,可以猜测这是获取一个随机数然后乘以一个小数后判断是否大于一个值,如果小于的话就把eAncientRank的值改为2,我们发现整个函数eAncientRank的值会被赋值成1或2,因此猜测eAncientRank的值如果是2的话就代表太古,1代表远古,于是可以从这个随机数判断上入手,可以让这个条件始终成立,那么eAncientRank就始终为2了,那么我们掉落的传奇是不是就一定是太古级别了呢?

5. 在<=上点击一下,可以看到这个地址是928BA8,然后再点击IDA View, 点击跳转->跳转到指定地址里输入928BA8,就到了这里的汇编代码,我们要修改的就是928BA4上的FCMP            S0, S9,原因就是当鼠标在v27这个变量上停留时,显示的就是s9,为了让下一句B.HI            loc_928BB4  不跳转,我们可以在FCMP  S0, S9上鼠标右键快速修补神器->修补,把原指令改为FCMP S0, S0, 这样结果始终相等,<=的条件就始终成立了,如果想在IDA View里显示指令字节码和注释,可以在选项->常规里按照下图配置一下就可以了

6. 修补之后,我们突然想到一个问题,现在是基于原始版本修改的,但是游戏已经是2.6.6版本了,怎么办?不用担心,我们可以采用另一种方法去找到2.6.6版本对应的地址,再次启动另外一个IDA实例,打开2.6.6的main.elf,搜索原始版本FCMP附近的指令字节码,可以是前面的,也可以是后面的,如果搜索不到,那就扩大范围,记住,尽量搜索一些不容易被改变的指令,比如常量等等, 我们就在2.6.6里面搜字节序列00 00 23 1E 00 08 28 1E 然后发现第二个搜索结果和原始版本附近的指令最相似,那么基本可以判断,第二个搜索结果就是2.6.6对应的地址啦,2.6.6对应的FCMP地址就是00000000008610B4,用同样的方法改成FCMP S0, S0

7. 目前为止,我们已经完成了太古级别判断的修改,那么还有一个问题,可以从伪代码分析中得知,要判断太古的话,首先这个掉落的传奇装备要先进行远古级别判断,成功后还要进行当前玩家Solo单人大秘境层数是否大于等于70的判断,大于70层才会进行远古级别的判断,因此,前两个条件同样需要修改成始终成立,转到汇编代码我们确实可以看到nMinimumAchievedRiftLevelToRollPrimalAncients和nHighestSoloRiftLevel的比较,也就是单人solo大秘境层数与生成太古装备所需最低层数的比较

8. 知道了原始版本的远古太古以及层数判断,那么接下来我们可以去2.6.6版本的伪代码当中找到对应的地方,当然由于2.6.6的main不带调试信息,因此不太容易看,不过通过代码结构还是很容易分析出对应关系,但是我们暂时没找到远古的判断位置,只找到了后两个判断

9. 不过这阻挡不了我们逆向的决心,伪代码往上面分析,我们看到了一个v8的变量乘了一个很小的数,因此分析出v8一定是远古判断的随机数

10. 往下找v8出现的位置,可以发现v8有两个地方进行了比较判断,其中第一个位置才是进行远古的判断位置

11. 现在我们已经找到了2.6.6main里面的3处判断位置,程序逻辑流程就是先生成随机数进行远古判断,是远古了然后判断玩家大秘境层数大于等于最小层,成功后再生成随机数进行太古判断,成功了就是远古装备,因此,只需要修改这三个判断始终为真,那么最后怪物掉落的一定是太古装备,我们分别找到这三处判断对应的汇编指令,然后进行修改如下:

12. 我们总算完成了三个判断的修改,那么接下来就是制作金手指代码的时刻了,将三处地址修改后指令字节码写成3行金手指格式码即可,当然我们也可以不修改远古概率的判断,这样传奇掉落一旦判定为远古,那么就必为太古,因为传奇是远古的概率是10%,所以太古的概率也就是10%了,另外,把三处指令写回程序原始的判断指令,那么就相当于恢复了太古正常概率,所以我们可以得到三个金手指功能了:

11. 保存成txt放到相应目录下,运行游戏,切到金手指界面开启太古100%概率,为了增加传奇掉落,可以同时开启魔法装备掉率999999900%(这个是需要游戏启动后一秒去开启,不然无效),回到游戏,去小秘境杀几组精英怪,或者打一层大秘境,你会发现,GOD,满地红光太古,闪瞎双眼。。

12. 爽了一翻,你可能会发现,咦,为什么还有一些黄光普通传奇呢,不是100%太古么?这是因为掉落机制非常复杂,大部分情况会掉落职业相关的装备,此时就是100%太古了,当小概率掉落其他职业装备时,暴雪为了游戏平衡,设置了不进行太古判断的开关,这里可以提示一下,至于怎么改,还是比较简单的,就交给读者自己去实践了

好了,本节到此结束,这一节内容比较重要,通过此节,读者应该掌握了对程序进行逆向分析和修改的技巧,如果有不明白的地方,可以补充一下arm64的汇编知识,下一节我们将进阶到更高阶的金手指制作:程序Hack,可以在游戏中实时去修改人物的各项属性,动态开启和关闭,甚至添加自己的程序代码


http://chatgpt.dhexx.cn/article/luamN9tt.shtml

相关文章

NS版暗黑破坏神3金手指开发教程(17)

终于到最后一节了&#xff0c;在这一节中我们将讲解如何利用hack制作出丰富多彩的世界&#xff0c;开个玩笑&#xff0c;其实是因为由于暗黑三的AMIIBO功能很有意思&#xff0c;不但可以用普通手办在城外召唤出一组精英怪&#xff0c;而且在城内用专用哥布林手办还能开启宝藏秘…

NS版暗黑破坏神3金手指开发教程(5)

上一节&#xff0c;我们学会了通过修改程序指令的方式制作金手指&#xff0c;这一节&#xff0c;将引出真正的高手级金手指开发方法 除了必掉太古这个极其护肝和有用的金手指外&#xff0c;我们能想到的另一个金手指就是人物背包里的素材&#xff0c;包括金钱&#xff0c;宝石…

暗黑破坏神2 符文自动合成--按键精灵源码

最近玩了一个暗黑破坏神mod服 发现2个符文可以合成一个大号符文.不过手动合成实在太费劲了.于是乎我就写了一个自动合成的脚本. 需要用到图灵插件,不知道的自己百度一下. 还是挺有意思的这类脚本.还需要有一个自己的算法. 源码如下. Function 移动鼠标点左键(x1, y1)MoveT…

Unity脚本(二)

视频教程&#xff1a;https://www.bilibili.com/video/BV12s411g7gU?p122 目录 Transform GameObject Object GetComponentInParent LookAt GetSiblingIndex、SetSiblingIndex Instantiate Transform 对象的位置、旋转和缩放 场景中的每个对象都有一个Transform&…

Unity 剧情类游戏基础脚本

本文主要用于给新人提供实现剧情类游戏的基本思路。 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; 然后是一个很重要的 [System.Serializable] 它的作用是使得在检查器窗口来看到我i们自己创建的类从而实现在检…

Unity脚本(三)

视频教程&#xff1a;https://www.bilibili.com/video/BV12s411g7gU?p128 目录 Time Prefab Animation Time Time.time&#xff1a;自应用程序启动以来&#xff0c;每帧的开始时间&#xff08;只读&#xff09; Time.deltaTime&#xff1a;每帧间隔&#xff0c;或说完…

NS版暗黑破坏神3金手指开发教程(1)

最近重温了NS版的暗黑三&#xff0c;因为空闲时间实在有限&#xff0c;面对这样一款刷刷刷的经典作品&#xff0c;为了护肝以及更爽快的游玩&#xff0c;同时为了弥补自己丢失已久的汇编技能&#xff0c;加上NS版暗黑三最初版本里有带完整调试信息的elf文件&#xff0c;于是有了…

NS版暗黑破坏神3金手指开发教程(3)

上一节&#xff0c;我们初步介绍了修改人物力量的方法&#xff0c;也大致说了一下hexworkshop和IDA的简单操作&#xff0c;这一节&#xff0c;我们将进阶到复杂度高一些的人物全属性修改&#xff0c;搜索方法基本跟上一节的力量公式一样&#xff0c;需要一定的耐心和细心&#…

Unity入门3——脚本基础

一、生命周期函数 ​ 所有继承 MonoBehavior 的脚本&#xff0c;最终都会挂载到 GameObject 游戏对象上 ​ 生命周期函数就是该脚本对象依附的 GameObject 对象从出生到消亡整个生命周期中 ​ 会通过反射自动调用的一些特殊函数 ​ Unity 帮助我们记录了一个 GameObject 对象依…

4.实现csdn暗黑模式-油猴脚本实战1

4.实现csdn暗黑模式-油猴脚本实战1 Start 前面的文章&#xff0c;对油猴脚本做了基础的介绍。今天来我们来实战一下&#xff0c;编写一个有实际作用的油猴脚本。 如果我希望我的csdn是暗黑模式&#xff0c;怎么办&#xff1f; 看我表演&#xff1f; 注意&#xff01;本文仅用…

6. unity之脚本

1. 说明 当整个游戏运行起来之后,我们无法再借助鼠标来控制物体,此时可以使用脚本来更改物体的各种姿态,驱动游戏的整体运动逻辑。 2. 脚本添加 首先在Assets目录中,新创建一个Scripts文件夹,在该文件内右键鼠标选择创建脚本选项,即可创建一个脚本文件,可命名为Sampl…

Unity入门03——Unity脚本

1.脚本基本规则 1.设置编程用工具 2.基本规则 1.创建规则 不在VS中创建脚本了可以放在Assets文件夹下的任何位置&#xff08;建议同一文件夹管理)类名和文件名必须一致,不然不能挂载(因为反射机制创建对象&#xff0c;会通过文件名去找Type)建议不要使用中文名命名没有特殊…

你可能还不知道的暗黑3常用小技巧

以下是上次活动热心坛友发来的游戏小技巧&#xff0c;经过我的搜集和加入一些自己和朋友们分享的经验整合编辑而成。再次感谢大家的热心参与。都非常实用哟&#xff01;&#xff01;&#xff01; 操作篇 1&#xff0c;如果你不希望朋友进入你的游戏时&#xff0c;按ESC&#xf…

jq linux获取数组长度,数组长度用size还是length

数组长度用length属性。length是js的原生方法&#xff0c;可获取元素的个数和对象的长度&#xff1b;而size()函数是jQuery方法&#xff0c;只能作用于对象上&#xff0c;用于返回当前jQuery对象封装的元素个数。获取一个数组的长度或者参数的长度&#xff0c;只能用lenth。 本…

delphi 获取数组长度_数组的介绍及使用

JavaScript 中的数组常用于在单个变量中存储多个值。数组就是一组数据的集合&#xff0c;在内存中表现为一段连续的内存地址(保存在堆内存)。创建数组的目的就是为了保存更多的数据。 数组概念和语法 概念&#xff1a;数组是一个特殊变量&#xff0c;一次可以容纳多个值。 特点…

js 填充数组长度

js 填充的方法有以下三种 const array new Array(100).fill()Array.from(new Array(100).keys())let arr Array.from({length:100}, (_v,k) > k);如果下面有这么一个场景&#xff0c;你在接口中获取了一个数组对象&#xff0c;如下&#xff1a; [{id:1},{id:2},{id:3},{…

c语言中文网 数组的长度,数组的长度如何获取?

获取数组长度的方法&#xff1a; 1、在java与JavaScript中可以使用“数组名.length”方法获取数组长度 javaScriptvar arrnew Array(); arr[0] "a"; arr[1] "b"; var lenarr.length; java 2、c语言中可以使用关键字 sizeof获取数组长度 用 sizeof 可以获…

c语言 json数组长度,js 获取json数组里面数组的长度

作为一个前端页面开发者第一次处理json数据,遇到了‘js 获取json数组里面数组的长度’?竟然不知道 json没有.length属性(真是要嘲讽下自己),少壮不努力老大徒伤悲啊!以前都是去寻求男朋友帮助,但是最近尝试自己去解决遇到的问题。 我遇到的问题是这样的:***.jsp结尾的页面…

vue 获取数组长度_Vue数据响应式

响应式是一种设计模式。 页面响应式布局就是根据页面缩放大小调整布局,数据响应式就是代码根据数据变化作出反应。 深入响应式原理 — Vue.js​cn.vuejs.org 简单来说,当我们把一个 JavaScript 对象传入 Vue 实例作为data选项时,Vue将遍历此对象所有的 property,使用Object…

Javascript 获取数组长度, 对象成员个数, 字符串数

1.应用场景 主要用于获取数组长度, 对象成员个数, 字符串数. 2.学习/操作 Q1.Javascript怎么得到数组长度(也就是数组的元素个数)? Q2.Javascript怎么获取对象的成员个数? Q1 你肯定想到了array.length!? 那么我们来测试一下下面这个例子. <script type"text/jav…