Submission Text Full Submission Page
  • Arbitrary Code Execution
  • Major skip glitch
  • Uses a game restart sequence
  • Corrupts save data
  • Abuses opposite D-Pad presses (U+D/L+R)
  • Minor luck manipulation
  • Genre: Strategy
I guess I've now made it a goal to achieve a save glitch win in as many Koei games as possible.
I use the same basic method in my L'Empereur TAS of a mid-frame reset to create a general pointing to controller input. However unlike L'Empereur, there is no single RAM address I can write to in order to trigger the ending. Instead, I perform rudimentary arbitrary code execution to jump to the ending by writing code to RAM.
  • Through testing I found Scenario 5 allowed for the fastest route to the save corruption. The game's initial RNG seed is determined when you first press start during the intro sequence (beginning w/ the Koei logo's appearance), so I tested multiple seeds to get to my turn the fastest.
  • Controller input is at 0x6E, and I already have a general (Fei Shi) w/ address 0x6B6E. So it's just a matter of saving the game, sending Fei Shi to another province & resetting mid-frame to create a general w/ address 0x006E.
  • Beforehand, I reassign soldiers to fix the checksum of the future corrupted save. Note that the game designates generals with no soldiers as 0xFF, so setting a general to exactly 0 soldiers actually INCREASES the checksum. Here I balanced it out exactly.
I went through trial and error of different methods of writing the code I need to the zero page but the method I came up with ended up being really simple. Like my last TAS, you instantiate entries in the general list by holding down the appropriate button combinations. Appointing a general as governor places them at the start of the linked general list. In order to write a specific value to the zero page, first you make a general w/ that value, appoint them General, then create a general representing the address and appoint them. This causes the previous general to be written to that address. There are some caveats:
  • The value you're writing needs to also represent a writable RAM address, otherwise the general list will get obliterated.
  • Sometimes when appointing a glitched general, the resulting text message will contain a name string so long that it overflows over crucial data, which can crash the game. (This didn't happen here)
  • Traversing some values when filling the general list will sometimes hit an infinite loop which can also crash the game.
By writing 0x6EA4 to 0x1F and 0x63DD to 0x22 I get the following code (in the Koei VM bytecode):
  • A4 6E 00 ; load PAD1/PAD2 input to left register
  • DD ; call pointer in left register
  • 63 (this value is irrelevant, I just picked the first byte that didn't crash)
Now in order to actually run this code I need to clear the program counter for the virtual machine (0x06) so that the game starts executing values in the zero page. To do so I simplify instantiate an officer @ 0x06 and then dismiss them, which causes zero to be written to it (removal from linked list). The game then starts executing the "code" starting at 0x00, and eventually comes to the code we've written. At this point, by holding down the button combo for the ending function (0xE037), it gets called.
NOTE: The game uses the name of the ruler of Province 1 as the winning ruler, since normally the game ending is only triggered when all provinces have a singular ruler. The name is glitched because Province 1 is unoccupied so it does a name lookup on an invalid ID.
Future improvements are possible, there might exist a way to have sufficient code in the zero page to leverage the ending skip using only a single memory write in combination with values that are already there.
In addition to this rudimentary ACE I've also written a full ACE bootstrap for a potential total-control TAS. The setup for it was around 10 minutes but using this new method I should be able to shave that down considerably. A simple demonstration of using it to draw custom graphics: https://www.youtube.com/watch?v=EKCj2jXPqIU


TASVideoAgent
They/Them
Moderator
Joined: 8/3/2004
Posts: 15585
Location: 127.0.0.1
CoolHandMike
He/Him
Editor, Judge, Experienced player (896)
Joined: 3/9/2019
Posts: 696
Very impressive work!
discord: CoolHandMike#0352
Alyosha
He/Him
Editor, Emulator Coder, Expert player (3822)
Joined: 11/30/2014
Posts: 2832
Location: US
Nice work once again, you sure are improving rapidly at this hash attack exploit stuff, I hope to see even crazier stuff in the future. Yes Vote.
EgixBacon
He/Him
Player (184)
Joined: 4/15/2013
Posts: 331
Location: In the attic
You thought you could escape from the glitchiness by moving from France to China? Think again >:D Voting yes. Side note: I'm kinda surprised they didn't remove hiragana characters when localising the game. I always thought that was the norm.
FanFiction|Youtube Still on Win7! Take that, Microsoft!
Jigwally
He/Him
Active player (427)
Joined: 3/11/2012
Posts: 119
Not only that, but all of the Generals' names were originally written in Kanji so CHR $1000-$7FFF still holds all of the tile graphics for those.
Jigwally
He/Him
Active player (427)
Joined: 3/11/2012
Posts: 119
g0goTBC
He/Him
Experienced player (752)
Joined: 6/11/2018
Posts: 110
That's very impressive. Nice job figuring that out! May I ask why the given time seems to be way longer than the run itself? Could it be because of blank inputs at the end of the movie file?
Banjo-Tooie runner, DTC 8, 9, 10, and 11 winner, but more importantly, "When's GR?" Current projects: Banjo-Kazooie: Grunty's Revenge - 100% (50 minutes) Mario Party 1 - All Boards (est: 4-6 hours) Mario Party 3 - All Minigames (est: 40-50 minutes, not sure) "Ooooh, I saved some more subpixels. Look at those sweet subpixels. You can't look at them, because they're subpixels, but they look so good." - The8bitbeast "It's as if I knew what was going to happen. It's as if I had the plan written in front of me and I was reading it. I mean, I do have it in front of me, but I'm not reading it." -garagedooropener
Jigwally
He/Him
Active player (427)
Joined: 3/11/2012
Posts: 119
My best guess is it's to do with SubNESHawk counting both controller polls as separate frames. My most recent revision doesn't seem to have that problem.
Jigwally
He/Him
Active player (427)
Joined: 3/11/2012
Posts: 119
I'm going to cancel and resubmit, I've optimized the route considerably which requires a rewrite of the submission text.
TASVideosGrue
They/Them
Joined: 10/1/2008
Posts: 2785
Location: The dark corners of the TASVideos server
om, nom, nom