石头门第四集33秒处代码解析

这东西乍眼一看就是乱打的是吧,其实不是。
注意看8B和5X出现了多少次:8B是x86的MOV指令 MOV REG,MEM;5X是x86的push和pop
画面里面有8B 55 D4 52,8B E5 5D C3,8B 45 0C 50,8B 4D 08 51,8B 55 FC,8B 45 08 89 42 3C,8B EC 51 89 4D FC 8B 45 EC
这些分别是
MOV DX,[DI-2Ch]
PUSH DX
MOV SP,BP
POP BP
RET
MOV AX,[DI+Ch]
PUSH AX
MOV CX,[DI+8]
PUSH CX
MOV DX,[DI-4]
MOV AX,[DI+8]
MOV [BP+SI+3Ch],AX
MOV BP,SP
PUSH CX
MOV [DI-4],CX
MOV AX,[DI-14h]
我来解释一下
动漫描述这个是用来破译信息的,那么它的逻辑就不希望被人轻易看懂,所以经常压弹栈并把数据满内存乱放是很正常的。而且有个细节——总是用DS:DI——这个就指明了这是在操作数据,DS是“数据段”的意思,DI是“目标地址指针”的意思。
然后我找到了一个重要的东西——U駆——Shift_JIS编码55 8B EC——x86堆栈传参子程序常用开头——
PUSH BP
MOV BP,SP
意思是把基址(BP)保存下来,然后让BP指向栈顶(SP),这样就可以用SS:BP+xx来访问堆栈上的参数
同时对应结尾
MOV SP,BP
POP BP
RET
意思是恢复栈顶,因为程序里面会压栈弹栈,而且压的可能比弹得多,为了栈平衡(为了在子程序返回时候不会返回到错误地址以及不会破坏调用者数据)有时候用 ADD SP,xx,有时候一堆POP(尤其喜欢POP CX),但是偷懒点也可以让SP直接指BP所指,毕竟BP就是直接复制的SP。PUSH了就要POP,所以POP BP与前文PUSH BP相对应,然后RET,返回到调用者。
你也看到了,一个子程序的结尾就在第五行末端。
那么能读出更连续的内容吗?可以。这个画面里面的十六进制编辑器左边是十六进制区,宽9字节,右边是文本区(Shift_JIS编码),宽8字节。这玩意一行十六字节,刚好能凑够,所以我就试了下——

(到现在我都不知道那个两字节的点是什么)
55 PUSH BP
8B EC MOV BP,SP
51 PUSH CX ;这里PUSH因为后面动CX了
89 4D ?? MOV [DI+disp8],CX ;disp8就是缺损的那个字节
8B 45 0C MOV AX,[DI+Ch]
50 PUSH AX ;这两行的格式特别常见,因为IBM51XX系列用的Intel8088还不支持后面的x86那种直接PUSH MEM
8B 4D 08 MOV CX,[DI+8]
51 PUSH CX ;格式同上
8B 20 MOV SP,[BP+SI] ;这一句稍微有些莫名其妙,但是这个操作还能弥补
x86是变长指令集,如果不知道第一字节就绝对无法译指,x86一条指令可以一字节两字节三字节四字节等等,就像文言文断句,俩字断不开若是后面没提示就一大长串断不了了。
总结,这个估计是找了个什么程序直接复制出来的,并不是胡打的。回到剧情,桶子这么牛逼怎么可能不了解这指令集——这现在满大街都用的,随便抓个程序员都会说见过的指令集?唯一的解释就是这个世界很像现实世界,但是,x86可能被ARM打败并完全替代,严重到x86指令集都丢了,那么Intel和AMD绝对倒闭了,没人挤牙膏了,放眼望去恐怕满眼高通联发科吧,悲惨的世界……
PS:为了駆和窺两个字,我搜索了半天其对应平假名,吃了文化的窺(笑哭