研究《绿色军团》NSF的音乐引擎(2)反汇编

维京猎人

引子

上回说到我们得了音乐引擎的代码。用软件反汇编得到的代码,不是最终代码。因为的部分程序会被数据混淆了。那么如何分析?先要人工区分代码和数据。然后整理变量,清除反汇编信息,才得到真正的代码。才是反汇编成功。本编说说如何人工区分被数据混淆的代码。

介绍一下反汇编的码:

左边是地址,冒号后面是数据,右边是代码,你可看出代码来。中间的数据是代码的机器码。

如果不能识别成代码,就会有以下形式:

addr:        xx DB        $xx

当然数很少是单独的,它的前后都会是数据,但被错认为是指令。

还有代码被混淆后,数据与代码错误相连,做成错位。

只有当一个单字节的指令(BRK除外)被识别出来,它后面很大会重新排对位置。然而碰到新的数据又开始混淆。

一、找出(从开头)连续的程序段。

上次保存的A575.asm可能编码不是太好,用VSCode打开,先编辑器,暂时选文本编辑器好了,或者用别的代码编辑器,这不是重点。

因为确定开始地址就是4710跳转的落脚点,所以我不用担心,肯定程序起始正确。向下看。代码看上去都正常,真到ABE6,它下面的程序隅尔出现数据。这说明数据与程序混淆。我贴部分出来:

ABCF: BD 7F 02  LDA $027F,x
ABD2:    09 02  ORA #$02
ABD4: 9D 7F 02  STA $027F,x
ABD7:       60  RTS
ABD8: BD 7F 02  LDA $027F,x
ABDB:    29 02  AND #$02
ABDD:       48  PHA
ABDE: 5D 7F 02  EOR $027F,x
ABE1: 9D 7F 02  STA $027F,x
ABE4:       68  PLA
ABE5:       60  RTS              ;程序正常的结束。
ABE6: 2C AC CF  BIT $CFAC        ;这一行判断为混淆的开始。
ABE9:         ABDB  $AB
ABEA:         32DB  $32
ABEB: AC 39 AC  LDY $AC39
ABEE:         3FDB  $3F
ABEF: AC 4D AC  LDY $AC4D
ABF2:         64DB  $64
ABF3: AC 6B AC  LDY $AC6B
ABF6:         72DB  $72
ABF7: AC 7E AC  LDY $AC7E
ABFA: CD AC A9  CMP $A9AC
ABFD: AC B5 AC  LDY $ACB5
AC00: 9D AC C1  STA $C1AC,x
AC03: AC E3 AC  LDY $ACE3
AC06:    06 AD  ASL $AD
AC08: 1E AD 25  ASL $25AD,x
AC0B: AD 3D AD  LDA $AD3D
AC0E:         2BDB  $2B

可以看见ABE6上面每几行就一个RTS,这是返回指令。很正常的。就它下面时不时的几个数,识别不出指令,可以认为ABE6开始就是数据。而ABE5是一个RTS。这是程序结束。

当然这样还是有点武断。代码在穿过RTS有3个方法,(1)子程序调用(2)无条件跳转(3)相对跳转。

(1)排除“子程序调用”,我们搜索JSR,并记下地址,范围从开始直到ABE5。新建一个XLSX表格,找出来的JSR指向的地址记录在表格中。记得左边的范围不要超越ABE5。记录的是JSR后面的地址,然后排序,去掉重复。结果出现大于ABE5的地址,说明这些数据并不长。但是,ABE5开始的数据已经打乱了后面程序识别的次序。还要继续找。

(2)排除“无条件跳转“,我们搜索JMP,并记下地址,范围从开始直到ABE5。新建一个XLSX表格,找出来的JMP指向的地址记录在表格中。记得左边的范围不要超越ABE5。记录的是JMP后面的地址,然后排序。没有发现大于ABE5的地址,这很正常。一般不会多写一个指令跳过数据,说明这些数据是依附着附近某个子程序。

然后,我真的发现ABE6是数据的实锤证据:LDA $ABE6,Y

见代码,这段数据长度可能的MAX=256。搜索全部代码只发现这两行。

AB5E:       A8  TAY
AB5F: B9 E6 AB  LDA $ABE6,y    ;证据
AB62:    85 06  STA $06
AB64:       C8  INY
AB65: B9 E6 AB  LDA $ABE6,y    ;证据
AB68:    85 07  STA $07
AB6A:    A4 00  LDY $00
AB6C:       C8  INY
AB6D:    A9 AA  LDA #$AA
AB6F:       48  PHA
AB70:    A9 37  LDA #$37
AB72:       48  PHA
AB73: 6C 06 00  JMP ($0006)    ;这才是难点,有可能是突破点

但是这个JMP($0006),说明这堆数据是一堆跳转地址。

(3)排除”BCC/BCS/BEQ/BNE/BVC/BVS/BMI/BPL“,从ABE5向后数256个字节,即AAE5,找找这几个指令,因为都是B字母开头,我可以搜索:空格+"B"会很快找出来。同样记下指向的地址。(虽然实际机器码是相对地址,但汇编上是写绝对值的)记得不要超越ABE5。然后排序,去掉重复。结果发明同样没有大于ABE5的地址。这就合理了。除非这些代码非常短。写代码的人水平很高,控制代码能力很强。不过这样的人不会写这种麻烦代码。所以相对跳转是不会跳过一段数据的。

最后只有JSR指向在地址越过ABE5。JSR指向的地址都是子程序入口,这非常有价值。(而JMP和相对跳转指向的是条件分支,这一段都在子程序内部。)我们现在将一整个子程序看成一个模块,后面分析和理解就很方便。我们还要对各个子程序段进行注释。

现在确定一段连续的程序是A575-ABE5

而ABE6开始是一段数据,估计长度256以内。

二、确定下一段数据的长度。

上面发现只有JSR指向在地址跨过数据段,那么离ABE6最近的地址应是新一段程序的开始。

JSRA60C
A6A3
A6DE
A802
AA0F
ABAE
ABC6
ADCE
ADE0
AE31
AFCD
B026
B0DE
B1C4
B3FA
B655
B6D2
B6E9
B8F3
BC7A
BD5B

我从中找到ADCE

我去看了ADCE,它的上几句ADC6正好是RTS,再向上看,也有好多正常的程序。就是说数据打乱了后面的反汇编程序,但过了一段之后又正常了。就是说数据的真正结束点不是ADCE。我猜测ADCE之后的程序会向前调用,(即调用ABE6-ADC6)。我要确定数据段,将混淆的代码找出来,写正确。

工作量有点大,因为我只过了10%的代码。

现在的思路是,(1)缩小混淆代码的范围,(2)试试从近处识一下,有没有向这个区域跳转的或调用的。(3)上面说过这段数据是一对对地址,那就将它们展开,看跳转是否合理。

实施:

(1)我将数据段缩到ABE6-AC38

ABE6: 2C AC CF  BIT $CFAC
ABE9:         ABDB  $AB
ABEA:         32DB  $32
ABEB: AC 39 AC  LDY $AC39
ABEE:         3FDB  $3F
ABEF: AC 4D AC  LDY $AC4D
ABF2:         64DB  $64
ABF3: AC 6B AC  LDY $AC6B
ABF6:         72DB  $72
ABF7: AC 7E AC  LDY $AC7E
ABFA: CD AC A9  CMP $A9AC
ABFD: AC B5 AC  LDY $ACB5
AC00: 9D AC C1  STA $C1AC,x
AC03: AC E3 AC  LDY $ACE3
AC06:    06 AD  ASL $AD
AC08: 1E AD 25  ASL $25AD,x
AC0B: AD 3D AD  LDA $AD3D
AC0E:         2BDB  $2B
AC0F: AD DC AC  LDA $ACDC
AC12:         37DB  $37
AC13: AD 47 AD  LDA $AD47
AC16: 4D AD 59  EOR $59AD
AC19: AD 65 AD  LDA $AD65
AC1C:         74DB  $74
AC1D: AD B3 AD  LDA $ADB3
AC20:    C1 AD  CMP ($AD,x)
AC22:         9CDB  $9C
AC23: AD 90 AD  LDA $AD90
AC26:    56 AC  LSR $AC,x
AC28:    A5 AD  LDA $AD
AC2A: AC AD 20  LDY $20AD
AC2D:       A8  TAY
AC2E:         ABDB  $AB
AC2F: 4C E9 B6  JMP B6E9
AC32: 20 A8 AB  JSR ABA8
AC35: 9D 97 02  STA $0297,x
AC38:       60  RTS

我是怎么做的呢,一来是看见它下面程序都比较合理,二来,我找的是单个60数据。因为60就是RTS。

如果它被其它数连在一起组成了另一个指令,那么后面继续混淆。如它被单独得到,那么后面就会很大机会是正常了。单看这个也不够,还要看后面是否全都识别成程序。因为如果不是向着写程序而定的数据,不可能全都识别的成程序,这个机率太低,总会有出新混淆的现象。如果没有,那么这个 RTS就是混淆的结束。

我的意思是我认为,上面这段的前半段是数据,后半段是混淆的程序。

(2)我试试识别,调用指令。因为其它两种的可能性很低。找过了ABEX,ABFX,AC1X,AC2X,AC3X都没有被调用。(搜索ABE,ABF,AC1,AC2,等)这说明,我上一步错了,这缩小范围是一种错误。以60为结束只是一种巧合。数据段的猜测还是在ABE6-ADC6

继续找AC4X到ADBX都没有被调用的地址。从ABE6到ADBF都没有被其它代码直接作为子程序调用。很有可能完全是数据。

到了ADCX(我是直接搜索ADC)我找到 JSR ADC7,还出现2次。还有之前的 JSR ADCE

ADF2:       38  SEC
ADF3:    E9 01  SBC #$01
ADF5:    E0 03  CPX #$03
ADF7:    F0 34  BEQ $AE2DH
ADF9:       48  PHA
ADFA: AD 0A 02  LDA $020A
ADFD:    29 04  AND #$04
ADFF:    D0 16  BNE $AE17H
AE01: 20 C7 AD  JSR ADC7        ; 看这一行
AE04:       68  PLA
AE05:       0A  ASL A
AE06:    84 00  STY $00
AE08:       A8  TAY
AE09:    B1 0C  LDA ($0C),y
AE0B: 9D AE 02  STA $02AE,x
AE0E:       C8  INY
AE0F:    B1 0C  LDA ($0C),y
AE11: 9D A7 02  STA $02A7,x
AE14:    A4 00  LDY $00
AE16:       60  RTS

这一段是在ADCE之后,可以认为ABE6-ADC6就是一段数据。

(3)这段数据的前256字节有可能是128个地址,我还是整理了出来。同样的用VNES DUMP出来ABE6-ADC6。转成汇编DB之后,从前面截取到35个地址,都是在数据段中的地址,再下两个字节作为地址的话,就不合理了,超出了。所以只取这些来试验。

AC2C ABCF    AC32    AC39    AC3F    AC4D    AC64    AC6B
AC72    AC7E    ACCD    ACA9    ACB5    AC9D    ACC1    ACE3
AD06    AD1E    AD25    AD3D    AD2B    ACDC    AD37    AD47
AD4D    AD59    AD65    AD74    ADB3    ADC1    AD9C    AD90
AC65    ADA5    ADAC

又是排序,找出最前的地址ABCF,这是 AB73:  JMP ($0006) 要跳转的第一个落脚点。但这个在ABE6-ADC6数据段之前,是已有程序,找第二个AC2C,这个肯定是被混淆的程序的开始点。这样应该是分辨出程序来了。

再次用VNES DUMP出来,ABE6-AC2B,和 AC2C-ADC6。前一个肯定是数据,后一肯定是程序。

很神奇,ABE6-AC2B,但到的数据,就是上面那35个地址,不多不少。

果然,AC2C-ADC6,反汇编得到的代码很正常。我将它们替换回代码中。

到这里,我完成了第一段数据的确定。

嗯,真是困难呀,没有毅力的同学趁早放弃出坑。

阶段性成果,看看

ABD8: BD 7F 02  LDA $027F,x
ABDB:    29 02  AND #$02
ABDD:       48  PHA
ABDE: 5D 7F 02  EOR $027F,x
ABE1: 9D 7F 02  STA $027F,x
ABE4:       68  PLA
ABE5:       60  RTS
ABE6:                       ;ABE6-AC2B.DB $2C, $AC, $CF, $AB, $32, $AC, $39, $AC, $3F, $AC, $4D, $AC, $64, $AC, $6B, $AC.DB $72, $AC, $7E, $AC, $CD, $AC, $A9, $AC, $B5, $AC, $9D, $AC, $C1, $AC, $E3, $AC.DB $06, $AD, $1E, $AD, $25, $AD, $3D, $AD, $2B, $AD, $DC, $AC, $37, $AD, $47, $AD.DB $4D, $AD, $59, $AD, $65, $AD, $74, $AD, $B3, $AD, $C1, $AD, $9C, $AD, $90, $AD.DB $56, $AC, $A5, $AD, $AC, $ADAC2C: 20 A8 AB  JSR ABA8
AC2F: 4C E9 B6  JMP B6E9
AC32: 20 A8 AB  JSR ABA8
AC35: 9D 97 02  STA $0297,x
AC38:       60  RTS                ;按第1个思路,就是找到这一行,认定前面就是混淆的段。
AC39:    A9 FF  LDA #$FF
AC3B: 9D 97 02  STA $0297,x
AC3E:       60  RTS

之前凭经验,找到AC38,其实也是对的,只是路子走到头了。

【原创】研究《绿色军团》NSF的音乐引擎(2)反汇编相关推荐

  1. 【原创】研究《绿色军团》NSF的音乐引擎(3)再取样再开始

    [原创]研究<绿色军团>NSF的音乐引擎(3) 维京猎人 引子 两期发布后收到好多意建.让我开拓了一些视野.但最重要的是我不小心发现,我选的nsf小样不是apu音源的,而是更高级的VRC6 ...

  2. 计算机问题求解需要研究的要素,关于计算机音乐制作的空间构成要素的研究

    摘要: 进入21世纪以来,随着计算机技术的快速发展,它对数据处理能力日益增强,使计算机在音乐创作,编辑,录制,后期处理等方面的核心地位更加凸显.在社会音乐实践活动中,如在电影,电视,音乐晚会,音乐专辑 ...

  3. 浪浪潮信息为数据中心实现绿色低碳提供强劲的“引擎”

    基于新一代数据中心PUE在建设运作中出现的新诉求,浪潮信息全面升级液冷技术,打造亚洲最大的液冷基地--浪潮信息天池液冷产业基地,为实现数据中心的绿色低碳提供强劲的"引擎". 浪潮信 ...

  4. 信息科学部鼓励科学家更多瞄准“原创”研究

    来源:<中国科学报> (2020-09-28 第4版 自然科学基金) 信息科学是研究信号/信息的产生.获取.传输.处理.存储.显示和应用及其相互关系的科学.在引导申请人进行分类申请方面,信 ...

  5. 南云等PNAS研究论文:揭示儿童音乐学习向语言领域迁移的脑机制

    来源:神经科技 摘要:南云等的研究结果表明,半年的钢琴训练提升了4到5岁儿童大脑对跨音乐与语言领域的音高变化的敏感性 2018年6月25日,美国科学院院刊PNAS在线发表了北京师范大学认知神经科学与学 ...

  6. javascript清除map所占内存_【原创.54期】 JavaScript的V8引擎初探

    本文主要就下面三块内容展开 栈和堆空间 垃圾回收 解释器和编译器 一.栈空间和堆空间 先回顾下基本知识 1.静态语言就是强类型?二者的关系 (1-1)静态语言, 使用前 要确定数据类型 (1-2)动态 ...

  7. 【原创】高通 Android ThermalEngine 温度引擎

    不知道各位有没有从 logcat 观察到一种日志 没错就是这样,看PID就知道是内核进程,那是啥玩意呢,google一下,找到这个 https://developer.qualcomm.com/qfi ...

  8. 国外部分音乐人工智能/音乐科技研究机构科研项目简介

    转载自我的个人网站 https://wzw21.cn/2022/02/26/music-ai-tech-group/ 本文对国外部分音乐人工智能/音乐科技科研机构的科研项目与教学课程设置作简要介绍,包 ...

  9. 【原创】如何做一张原创8BIT音乐的NES音乐卡片

    我陷入了深思...... 第一步是创作一首8BIT音乐.我介绍两个NES用的音乐工具:FamiTracker 和 FamiStudio. 选FamiTracker的原因是,有完美教程呀.红鸡将他的教程 ...

最新文章

  1. 计算机c语言循环作业,C语言计算机作业编程.doc
  2. Linux下显示前10个占用空间最大的文件或目录命令
  3. Hadoop集群的安全模式
  4. 用c#开发微信(2)扫描二维码,用户授权后获取用户基本信息 (源码下载)
  5. 论文被拒稿后怎么办?这些事情你要知道
  6. Golang二进制转换十进制代码
  7. 2020年首届算法竞赛网络挑战赛直播讲解课程
  8. python爬虫验证码的识别_Python爬虫识别验证码
  9. Linux下俄罗斯方块程序设计(c++)-转
  10. 使用AT指令给飞信号发短信失败
  11. 字符串转python对象
  12. 30 多个有内味道且笑死的人代码注释
  13. 推荐|10本不得不看的算法书籍,挖掘数据的灵魂!
  14. 忙活了一周时间,开发了一个年会抽奖系统,免费开放给大家(含操作视频及下载地址)
  15. 吴恩达《深度学习专项》笔记+代码实战(六):改进梯度下降算法(mini-batch, Momentum, Adam)
  16. 使用BottomSheetDialogFragment实现购买出商品,底部弹出商品属性的效果
  17. 冲马桶你会盖盖子吗?
  18. sgu207:Robbers(贪心)
  19. Debian11 更换软件源
  20. ae怎么设置gpu渲染_AE渲染慢?有可能是你没有配置显卡支持。

热门文章

  1. 修改TrustedInstaller权限文件
  2. Aspose.Cells转Pdf正确姿势
  3. 手把手教你绩效管理体系-OKR
  4. C 字符串转大小写strupr , strlowr, tolower, toupper
  5. C语言小题,将字符串a复制为字符串b,然后输出字符串b。(地址法和指针变量法)(通过指针引用字符串)
  6. 诛仙手游-情缘高攻路线是低道法的最佳选择
  7. Windows10中安装 docker desktop 报错:【WSL 2 installation is incomplete.】
  8. 如何设置下拉框的选中项
  9. 中兴面经-南京(9-7号一面)
  10. NLP之文本分词综述