- 精华
- 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的永远透明无敌(吃金身无敌道具也无效),如何实现自己想吧,已经都解释到这个程度了。 |
|