# 接续上一篇。开始之前再次说一下。这东西我并没有完全看懂──
# 这篇会比上一篇难很多。
# 我没有实作过。我甚至没有玩过四色版。
# 事实上我也是这两天才爬文尝试看懂的。
# 我觉得必要的拼图还缺了一块。希望有看得懂的人可以补上。
嘘 Append: (メ^_^) 你这其实是一篇幻想文?
.............. > (;・∀・)
嘘 Append: (# ゚Д゚) 所以你这是当你个版在贴读书心得囉?
.............. > (; ・`д・′)
4!> \(°▽ °*)/
┌──────┐
│ ACE原理-8F │
└──────┘
一样,首先附上原本推文中的参考资料
推 a23962787: https://wiki.52poke.com/zh-hant/任意代码注入(漏洞)
更详细的介绍我推荐GlitchCity https://tinyurl.com/yactg6es
另外会需要内存位址对应 https://tinyurl.com/y6vpyjan
这里有提到一个奇妙的道具"8F"。
在四色版触发ACE的众多方法之中,
透过道具"8F"触发ACE应该是最容易理解与自己尝试的,
因此受到许多ACE玩家的推荐。
# 请注意这次推卡车的部分不是用这方法
# 这边介绍8F是为了更方便的描述并理解ACE的实作原理
8F是个正常游戏过程中通常不会取得的道具,需要透过其他漏洞取得;
他的功能是“执行$D163开始的代码”,
或者更直白的说──“把内存中$D163位置之后的资料当成程式码开始执行”;
那么从$D163开始,游戏原本在这里存了什么资料呢?
│ ... │ │
├───┼─────────────────────────┤
│$D163 │ 队伍里的PM数量 │
├───┼─────────────────────────┤
│$D164 │ 队伍中每只PM的种类。$D164是第一只PM的种类 │
│ ... │ .... │
│$D169 │ $D169是第六只PM的种类 │
├───┼─────────────────────────┤
│$D16A │ 队伍清单结束,默认填入FF。 │
├───┼─────────────────────────┤
│$D16B │ 第一只PM的数据。$D16B这格是种类,会和$D164一样 │
│ ... │ $D16C-$D16D两格会装这只PM的HP │
│$D196 │ .... │
├───┼─────────────────────────┤
│ ... │ │
也就是说,只要准确的安排这些PM跟属性,就能产生正确顺序的代码,
然后在使用道具"8F"的时候执行他。
欸...虽然听起来很有道理,但是PM属性能够控制的部分满少的,
所以这边流行的实作都是在这里写一段程式码‘去执行$D322开始的程式码’
这个组合可以用以下的PM队伍(刚好五只,照以下顺序)办到:
波波(HP233)、派拉斯特、大岩蛇、玛瑙水母、袋兽
这样的队伍是现在最流行的"8F Bootstrap Setup",
先准备好这组,然后使用"8F",游戏就会把$D322开始的资料当作程式码开始执行。
那$D322是什么位置呢?
$D322是道具栏中第三个道具的种类。他之后则是数量。
这之后则是第四、第五、...第二十个道具的数量。依序。
从第三个道具到第二十个道具,18个道具总共有36byte的空间可以使用;
除此之外,"道具下溢错误"(item underflow glitch)能够让背包道具数变成255。
中文说明 https://tinyurl.com/ybuq2l6j
英文说明 https://tinyurl.com/yc5evjq8
顺带一提,目前流行的道具下溢错误的setup是由 Luckytyphlosion 提出的,
而 Luckytyphlosion 同时也是这次推卡车ACE的设计者。
也就是说,准备好队伍里五只固定顺序的PM,准备好一个"8F",
剩下的问题就是准备第三格开始的道具列表。
道具列表的准备需要更多的漏洞,这边列出一些第一世代的漏洞做为参考。
https://tinyurl.com/yaonr77h
也就是说,想好需要的程式码,写成组合语言,翻译成机械代码,
然后反过来推算这应该对应到什么样的道具列表,
然后把这个道具列表用其他的漏洞凑出来,排好顺序和数量,
在需要的地方使用"8F",就能够骗游戏去执行这些程式码。
如果想要自己实作一次看看,这边推荐 TheZZAZZGlitch 频道的许多影片:
https://youtu.be/Sw0h7ImFsAs
https://youtu.be/98_azamLeh4
https://youtu.be/D3EvpRHL_vk
单纯想从0开始操作看看8F的话,这边有个给初学者的教学:
https://youtu.be/22EYJ0QXPBQ
不过以上我通通都没有自己尝试过。我其实没有玩过四色版。
(坦白说我不是很推荐去自己尝试啦。每个看起来都要很久很久...)
┌──────┐
│地图脚本指标│
└──────┘
8F法操作上比较直接,你需要的时候就使用道具"8F"去触发ACE。
但是...如果我希望他不断地执行某段程式码,应该要怎么办到呢?
一直按8F? \(°▽°* )
欸...这也不失为一个有效的办法...
不过邪恶的TAS玩家们当然不是这样做的。
这里先回到GDQ影片的表演者回应。
关于GDQ推卡车的细节: https://pastebin.com/UqRzNKxm
感谢 Luckytyphlosion 提出的构想,并且整理了专文回应。
上面那篇pastebin里面,Luckytyphlosion 整理了许多必要的资讯,
还有他如何构想并设计出这样的程式码;
对ASM版本的程式码本身有兴趣的可以参考连结 https://pastebin.com/6VWNfEKG
这之中有提到另一个核心概念 "Map Script Pointer"(地图脚本指标):
"游戏每两frame都会执行一次这格指向位址的程式码,位置存在 $D36E-$D36F。"
欸这很方便阿,透过这个机制可以不断执行一些条件检查,不用每次都在那边8F。
所以除了要跑什么程式码以外,同时产生了另一个问题:
要怎么更改这格内存,让他指向我们能够存程式码的地方?
这个部分有提到的介绍就很少了──这比较困难一些。
GlitchCity并没有非常详细的说明,但是他有提到 https://tinyurl.com/y9nksucp
"透过修改第41个道具种类和数量可以触发这个漏洞"
(可以参考一下上面的8F法,有提到$D322是第三格道具,与$D36E位置相差不远。)
除此之外,我稍微Google了一下关于Map script pointer的部分,找到这个影片:
https://youtu.be/2_NO8Dyubu4 (请注意画面会强烈闪烁,请避免久盯)
他设计了一些物品顺序,然后在2:00左右离开选单;
离开选单之后Map script pointer自动触发,
让主角不断的旋转跳,同时改变画面的颜色构成。
3:15左右他进行存盘,然后重开游戏,读档──效果竟然有保留下来!
这个方法会把当前的Map script pointer也存起来,读取后会继续自动执行。
但是当他往下走离开这个房间,效果就消失了。
很明显,这是因为换一张地图的时候,游戏写入了Map script pointer,
因此原本的自订脚本就不会被执行了。
欸这看起来很棒啊,刚好满足了制作存盘的需求。
这样就能先制作好ACE然后触发他,存盘再拿去GDQ现场开机了。
┌──────┐
│回到梦幻卡车│
└──────┘
嗯,看起来不错,如果是这种情况,如果能走到卡车旁边,
准备好梦幻卡车的程式码,然后把Map script pointer指向他,存盘──
下次读档的时候就可以推卡车给朋友看了! <( ̄︶ ̄)>
事实上这就是 Luckytyphlosion 最一开始提出来的构想。
2014年他在 Glitch City 贴了这段code https://tinyurl.com/y8b65op4
同时有一点小小的讨论,不过他后来忙了其他东西就搁置了这个构想。
一年后他想到,
"如果能够在比较大的场合,像是AGDQ,实作出这个,听起来好像很酷!"
于是他们正式着手这个计画。
跑者 Shenanagans 建议同时介绍"如何回到圣特安努号",
然后在这个过程才去推卡车,然后发现底下冒出一只梦幻。
我读到这里的时候,觉得这样就会有几个考量:
(1) 这大概不能使用8F触发。
如果要为了节目效果,装成不小心发现底下有只梦幻,
就没办法打开选单按一下8F。
(2) 如果透过 Map script pointer 触发ACE,
能够事先准备好这样的存盘,然后让跑者拿到节目上,
就能够避开"在观众面前手动触发"的部分;
以节目效果来说这点不错──
但是 Map script pointer换画面会被游戏自己的资料盖过去,怎么办?
Luckytyphlosion说。这确实困难了一点,但是并不太难。
每张地图有自己的 "Tileset" (图像素材的集合),
其中第7个位元跟图像无关──他是用来判断游戏有没有需要重新读取地图物件。
通过这个机制,在跑者冲浪存盘越过剪票员后,往下切换地图时,
就能够骗游戏不读取这张地图的物件,也因此不会把程式码盖掉──
欸...不读取物件的话不就没有地图了吗? /( ̄口 ̄;)\
所以,Luckytyphlosion 设计的这套程式码里面,
有判断当前的地图ID,自己去读取地图需要的物件。 (...这真的是很大的工程...)
最后就是实际上把梦幻卡车的脚本写下来啦。
检查有没有在使用劲力,是不是站在卡车旁边,有没有面对卡车,
把角色图像改成移动装作那是在推,实际上移动卡车图像的座标,
放出推石头的音效,弄出推石头的沙尘动画,放一只梦幻在地图上,...
然后准备好一个自订文字的对话框,跟梦幻对话的时候放出来,
然后call进入战斗,设定梦幻为5等,...
然后在战斗结束后清掉这些图像,把Map script pointer改回原本游戏设定的值。
以上全部都用ACE的方式做出来。而且还有更多细节在上面没有全部提到。
确实是非常非常巨大的工程。
┌──────┐
│ 总 结 │
└──────┘
总结一下──这边引用 Reddit讨论里面的总结, https://tinyurl.com/y7zp9gjl
(1) AGDQ的表演确实是使用游戏主机 (实际上是Game Cube + Game Boy Player)
(2) 游戏卡带读取的存盘是 Luckytyphlosion 在模拟器中制作的,
(3) Luckytyphlosion 透过 stump 提供的 flasher 把存盘写进卡带里面。
(4) 这中间并没有运作 Gameshark 或是任何类似的金手指工具。
(5) 使用模拟器制作存盘只是因为需要动用的工程太大,用模拟器比较容易控制。
这边附上一些我目前没有弄懂的地方:
(1) 这个程式码很长,ASM有三百多行。不知道实作的时候会存在哪里。
2014年的讨论有提到这点,当初有人提议要另外写输入 (像是那些手把输入),
那时候结论是如果存盘在卡车旁边应该不会太长;
但是现在这个版本真的复杂非常多,很难想像道具栏竟然塞的下。
嗯...不过组语看起来真的很省byte数,说不定真的可以?
(2) Luckytyphlosion 目前没有提供这个存盘。他有另外写一段
Unfortunately, I didn't create a setup to store this code in memory.
stump (twitch.tv/stumpdotio) had a save flasher which he used in order
to flash the save which had the code stored on using an emulator.
If I have the motivation, I may create a setup so you could fool
your friends (Kappa), but for now there isn't a setup.
嗯...这真的很可惜,如果能放出这个存盘应该满多人会想拿来玩玩看的。
目前还很难想像这样的SETUP实际上多难办到。
(3) 回到原PO提出来的讨论。
"推卡车到底是真是假?"
嗯,Short Answer: 推卡车是不会有梦幻的。那是谣言。 END.
"那这个影片是造假吗?"
......我很认真的想了一下这个问题。
Arbitary Code Execution 应该要看成是在造假吗?
我觉得这真的是个很难回答的问题啊。
我觉得ACE确实是"刻意的设法从游戏内的手段,塑造出原本不存在的东西";
如果从原作设计的手段来看,这应该可以算是在造假吧。而且是在追求造假。
是在追求"我们有一些真实的手段,这能够虚构出多少超乎想像的结果"。
而我觉得这个对虚构的追求非常的艺术。
至于这到底多真实──
很可惜我到现在还是没有办法看到这个SETUP的全貌,
无法判断这到底是不是真的能够全部用实机可行的手段办到;
说真的就算他把整个SETUP的过程重新整理干净放出来,
我觉得总长度可能也不是我真的能全部看完的。(真的好长阿。...)
同时,ACE的手段实在太多,我也是挑比较容易理解的几个方式试着介绍;
如果真的有把SETUP的过程放出来,大概也会有我没办法两天看懂的方法。
哎,想学会的东西太多了,实在是很难都花时间去看懂阿,
要真的都去尝试一次就更难了。ACE这样的长度我实在很难去尝试。
但是我觉得这没什么关系。
我还是很愿意去相信那些Setup是实机能够办到的,
或是即使现在这个版本并没有被实机作出来──大概也能找到办法办到。
反过来想,你看人家连Skype都可以打出来了,弄个梦幻真的很难吗...
┌──────┐
│ 后 记 │
└──────┘
(1) 2017年的Pokemon 黄版 TAS "Arbitary Code Execution"
https://youtu.be/Vjm8P8utT5g
是一个我觉得非常巧妙的利用ACE挑战Gameboy Color硬件极限的TAS
如果要挑一片TAS,来介绍现在能做到的事情──那大概就是这片了。
非常精采。不过如果对ACE的过程有兴趣,这东西的作者Comment也很精彩
http://tasvideos.org/5384S.html
里面为了更高速的即时写入程式码,自己写了三个新的触发阶段;
另外用按键即时输入18KHz的Still Alive,
然后还放了几秒的海绵宝宝。巧妙至极。
TASbot即时的表演效果更好,但是我觉得以静态作品来说,这片更是精彩。
(2) 其实我觉得 RiverT 提出的问题并没有这么应该被嘘。
我觉得GDQ这次的表演其实用了非常深刻的技术;
而我觉得会选择相信他们不会在现场造假,这其实满有道理的──
因为最懂这些游戏的人都正在看着,在现场或是在线上。
在这个场合恶意造假被揪出来,大概一辈子都别想在speedrun社群生存了。
相对的,自己尝试来否定一个谣言其实很困难,比证实他难很多;
这需要同时证明"自己的操作是完备的,已经尝试过所有可能性了。"
这很难啊。要怎么证明自己的操作已经完备了呢?
更何况,如果是从理解ACE的原理的角度看起来,
在ACE存在的情况下,什么叫做所有可能性...这真的很难说阿。
当然我理解谣言之所以讨厌,辟谣到觉得很麻烦的时候,谣言真的很讨厌。
如果谁跟我说"RMX4黑杰洛攻击力比较高一点点"我也会翻脸 ← 一秒惹火鸦片
但是这个世界真的很难想像他究竟能大到什么程度。哎。超难想像。
所以如果可能的话,我还是希望大家都可以开心的玩游戏,讨论游戏就好了。
毕竟游戏本来就是为了要让玩家开心,才会被设计出来的嘛。
┌───────┐
│ 给按End的人 │
└───────┘
(1) 这是一篇幻想文。我其实没有操作过,因为操作超长的。
(2) 8F法是ACE的众多方法中比较容易理解的一种。但是还是很难。
(3) GDQ这次的表演采用的方式是更改地图脚本指标。
(4) 但是如果按End看到这几行应该没办法看懂。
(5) 所以我觉得大家还是开心玩游戏吧。
(6) 上面两页有另一个精彩的黄版TAS,真的,看嘛看嘛,看嘛看嘛。
以上。
鸦片 (Append) 2018.06.06