A9VG电玩部落论坛

 找回密码
 注册
搜索
查看: 16099|回复: 13

[原创][HACK]FC/NES版《魂斗罗》日、美版无闪烁无敌 静态修改金手指与HACK ROM

[复制链接]

精华
0
帖子
478
威望
0 点
积分
629 点
种子
12 点
注册时间
2008-3-13
最后登录
2024-8-5
 楼主| 发表于 2012-4-16 23:23  ·  吉林 | 显示全部楼层 |阅读模式
本帖最后由 ly63 于 2012-4-17 09:46 编辑

相似的HACK之前有人做过,就不转载了,百度百科《魂斗罗》条目上就有。
但是之前的HACK人物一直闪烁,我觉得不完美,而且有BUG:所有敌人都停止攻击(拿枪的小兵不开枪、炮台只是瞄准你却一弹不发,就连BOSS也是如此),所以我分析了一下ROM,制作了这个新的金手指码。

平台:FC/NES
游戏:魂斗罗 Contra (USA)
游戏ROM容量:日版256Kib;美版128Kib
ROM名称:
               日版:Gryzor (Japan).nes
               美版:Contra (USA).nes


金手指码格式:GameGenie

无敌(无闪烁)日版
AVNVZPAZ
无敌(无闪烁)美版
AVKVPZAZ

HACK好的ROM在3楼
由于FCROM运行时有BankSwitching的特点,所以直接锁定非WORK RAM区的数值是危险的,很可能造成死机(错误改写了其它bank的ROM数据)所以就不发RAW格式的地址了,而GameGenie代码会检测目标位置数值,符合验证码才会写入,这样才不会出错。


附赠游戏ROM修改地址,有兴趣的话你可以自己用HEX Editor修改ROM。

无敌(无闪烁)日版
1E20A 原始数据为20,请修改为60
无敌(无闪烁)美版
1E2D9 原始数据为20,请修改为60

注意:目标ROM要求为原版ROM,刀版的可能无效。

修改原理:
直接取消敌方攻击判定,玩家本身没有无敌属性,但是任何攻击都没有判定,所以最终效果也是无敌,当然掉进沟里还是会死的。
此修改不影响吃到无敌道具时的原始行为(全身金光的无敌属性)。

改动程度:
1字节

已知BUG:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
该用户已被禁言

精华
0
帖子
3561
威望
0 点
积分
3605 点
种子
7 点
注册时间
2007-3-27
最后登录
2022-11-12
发表于 2012-4-17 08:51  ·  浙江 | 显示全部楼层
HACK好的ROM  在哪里?????????????


我要 HACK好的ROM  啊.................................

我是小白啊..............................

精华
0
帖子
478
威望
0 点
积分
629 点
种子
12 点
注册时间
2008-3-13
最后登录
2024-8-5
 楼主| 发表于 2012-4-17 09:43  ·  吉林 | 显示全部楼层
本帖最后由 ly63 于 2012-4-17 09:44 编辑

唉...只是修改1字节数据,自己动下手就这么难么?

日版:


美版:



HASH:

日版:
MD5:    6c3e924d8abd7229bbd5a29e4c7337b3
SHA-1:  9484e01b3652a79afbd1b574e305ad4fe57da26d
美版:
MD5:    d7a7c2bd1392fb57bff352bfa9a728e8
SHA-1:  2d2a587fc015305e14423c2060adca1dda198f1f

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

精华
0
帖子
62
威望
0 点
积分
62 点
种子
10 点
注册时间
2012-3-3
最后登录
2024-11-14
发表于 2012-4-17 20:20  ·  丹麦 | 显示全部楼层
LZ可不可以再深入讲解一下这个修改的思路?比如程序是如何确认被击中判定产生,以及掉下悬崖是如何判定的等等?学习一下,谢谢!

精华
0
帖子
478
威望
0 点
积分
629 点
种子
12 点
注册时间
2008-3-13
最后登录
2024-8-5
 楼主| 发表于 2012-4-18 00:50  ·  吉林 | 显示全部楼层
绫波贩子 发表于 2012-4-17 20:20
LZ可不可以再深入讲解一下这个修改的思路?比如程序是如何确认被击中判定产生,以及掉下悬崖是如何判定的等 ...

呃...终于有人对修改过程感兴趣了............
下面就说一下此游戏的hack过程


修改的切入点可以利用已知内存数据,比如内存位置$AE 为1P的无敌(透明闪烁)时间,你可以新建一个断点:条件设置为读取地址$AE时中断。
然后找个没有敌人的地方观察会有哪些程序段读取这个值,记住这些指令的地址,这些是呆会你要排除掉的地址,那么为什么要排除掉这些地址?比如此游戏魂斗罗,每显示一帧图像程序都会检测2次$AE的值,一次是当大于0时递减此值(否则你就是一直无敌了),另一次是测试此值是否为0,如不为0则转到使角色闪烁的程序,使你的角色看起来是透明的。这些地址与攻击判定无关,所以我们要忽略掉。

地址1:
07:D38D:B5 AE     LDA $AE,X @ $00AE = #$00
07:D38F:F0 05     BEQ $D396
07:D391:D6 AE     DEC $AE,X @ $00AE = #$00
07:D393:4C A0 D3  JMP $D3A0
07:D396:B5 90     LDA $90,X @ $0090 = #$01
07:D398:C9 01     CMP #$01
...
...

地址2:
02:A501:B5 AE     LDA $AE,X @ $00AE = #$00
02:A503:F0 07     BEQ $A50C
02:A505:A5 1A     LDA $001A = #$C7
02:A507:4A        LSR
02:A508:90 02     BCC $A50C
02:A50A:A0 00     LDY #$00
...
...

记下这两处地址之后,暂时关闭刚才设置的断点,控制任务走到有敌人的地方,当敌人近身时启用断点,然后不断点击(要慢点,因为只有一次判断,错过之后就要等下一个角色出现时再观察了)"run'按钮观察CPU寄存器PC的值,直到你看到了不同与刚才记下的2个地址处的指令读取$AE时,这里就已经是攻击判断子程序内了。

地址3:
07:E1F2:B5 AE     LDA $AE,X @ $00AE = #$00
07:E1F4:D0 97     BNE $E18D
07:E1F6:B5 B0     LDA $B0,X @ $00B0 = #$00
07:E1F8:D0 0D     BNE $E207
07:E1FA:20 74 D4  JSR $D474                   # 地狱入口
07:E1FD:B9 28 05  LDA $0528,Y @ $0537 = #$05
07:E200:C9 01     CMP #$01
07:E202:F0 6D     BEQ $E271
07:E204:A6 83     LDX $0083 = #$0F
07:E206:60        RTS

这里就是决定你生死的地方了,解释一下程序的意义:(按行)

读取$AE,x到寄存器A             ($AE是透明无敌的Timer)
如果A!=0跳转到$E18D
读取$B0,x到寄存器A             ($B0是金身无敌的Timer)
如果A!=0跳转到$E207
转子程序$D474
...
...

子程序$D474就是让你"死"的地狱入口,所以只要把这个死门关上,你就死不了了。
下面要做的就是HACK代码,把地址07:E1FA处的指令JSR 替换成RTS就OK了,只需要改动1字节,查6502指令集,RTS指令机器码是60,改之,OK了。后面的两字结数据是原来JSR指令的地址参数,现在变成了Unknown opcode,但是不用管,因为它们永远也不会被执行。

至此你的魂斗罗已经变成了不死之身(除了掉沟里),这样改不会产生BUG。

其实还有不同的实现方法,比如"不金身"的金身无敌和Buggy的永远透明无敌(吃金身无敌道具也无效),如何实现自己想吧,已经都解释到这个程度了。

精华
0
帖子
478
威望
0 点
积分
629 点
种子
12 点
注册时间
2008-3-13
最后登录
2024-8-5
 楼主| 发表于 2012-4-18 01:04  ·  吉林 | 显示全部楼层
还有不要打掉进悬崖的判断程序的主意,游戏没有设计人物掉悬崖之后还未死的处理程序,如果取消掉沟判断很可能导致人物卡在那里不能动或直接死机的严重BUG,这样的修改是无意义的。

精华
0
帖子
62
威望
0 点
积分
62 点
种子
10 点
注册时间
2012-3-3
最后登录
2024-11-14
发表于 2012-4-18 01:46  ·  丹麦 | 显示全部楼层
ly63 发表于 2012-4-18 00:50
呃...终于有人对修改过程感兴趣了............
下面就说一下此游戏的hack过程

学习了!之前真的没有意识到其实“死”是由一个子程序控制的,光在考虑中弹判定的产生了——不断比较子弹坐标和人物边框坐标的重叠吗等等,真的只要再往后想一步,重叠了然后呢?然后,就让他没有然后就行了!之前只是简单的追过无敌时间然后把步减NOP掉来保持半透明无敌,比较害怕JSR,BNE这类跳转命令(看不懂,呵呵)。这下看起来完全可以活用STR来杀子程序以达到更多的修改效果。关于掉沟的判定出现后,应该也是转入“死”的这个子程序吧?我在考虑第一关一开始从飞机跳下来那一段是否也是一个子程序呢?如果是的话可不可以把跳转地址改成这个子程序的入口,那么掉到沟里的话能不能从上方降下来?瞎想的,错了不要笑话我:-p

精华
0
帖子
478
威望
0 点
积分
629 点
种子
12 点
注册时间
2008-3-13
最后登录
2024-8-5
 楼主| 发表于 2012-4-18 02:58  ·  吉林 | 显示全部楼层
绫波贩子 发表于 2012-4-18 01:46
学习了!之前真的没有意识到其实“死”是由一个子程序控制的,光在考虑中弹判定的产生了——不断比较子弹 ...

RTS指令是不能乱用的,应该分析程序的走向,分析各种可能的分支,不是所有时候都能提前用RTS让程序返回的,上面的例子中当所有条件判断都为False的时候不再有新的分支,直接调用子程序然后设置透明无敌时间、人物状态后就返回,所以可以提前结束子程序,否则的话可能会产生BUG。

还有HACK程序的时候应慎用JSR跳转到自己写的子程序,因为游戏机的Stack容量非常有限(FC/NES只有256字节Stack),过多嵌***程序调用的话有可能造成Stack Overflow,丢失重要参数造成程序运行错误。一定要用的话最好还是用JMP或JML(SFC Only),尽量不要去动Stack,只是这样写的程序就不简洁了......

骑士

流放者大刀

精华
0
帖子
1305
威望
0 点
积分
2324 点
种子
406 点
注册时间
2007-11-9
最后登录
2024-10-3
发表于 2012-4-18 10:58  ·  四川 | 显示全部楼层
期待LZ把魂斗罗2也修改了

精华
0
帖子
478
威望
0 点
积分
629 点
种子
12 点
注册时间
2008-3-13
最后登录
2024-8-5
 楼主| 发表于 2012-4-18 12:59  ·  吉林 | 显示全部楼层
qwer1982 发表于 2012-4-18 10:58
期待LZ把魂斗罗2也修改了

在这:
https://bbs.a9vg.com/thread-2242232-1-1.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|A9VG电玩部落 川公网安备 51019002005286号

GMT+8, 2024-11-14 14:35 , Processed in 0.183764 second(s), 14 queries , Redis On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

返回顶部