08-25-2019, 04:56 PM
Of course. I was more thinking, if we were reversing the sequences, and we found a substantial bug in one of the code-heavy sequences, we should keep our eyes open for possible exploitation of it.
Perhaps this isn't the right place to bring this up, but I have been thinking about the relationship of music to ACE in another context for a while. Any successful ACE requires not only some sort of bug where execution goes somewhere it shouldn't (e.g. stack smash, jump table out of range, etc.) but also a relatively large area of memory which can be manipulated through in-game actions (e.g. Koopa shell X-coordinate table in SMW or inventory in Pokemon). Ideally, in-game actions would be able to set every byte of this memory uniquely to write whatever instructions you wanted, but it may be able to work even if there are constraints on what you can write there.
The second, "secret" scarecrow song in Ocarina of Time--the one you teach to Pierre, not the well-known one you teach to Bonooru which allows you to call Pierre--is not eight notes, but a seemingly unlimited arbitrary song that stores your pitch bends, vibrato, etc. This is the song that's played after the end credits in various different instruments (there actually may be a sequence for this--I'll have to take another look at something). Anyway, this song is stored in a unique format, different from the other scarecrow song. It starts at 0x0F60 in SRA and ends at 0x12b8 or 0x12c0, which is enough to store 108 8-byte-long events. The events are aligned to 0x2/0xA, and the format is:
struct event{
u8 note_number; // FF for rest, 00 is middle C, counts up for half steps; Z/R modifier affects this (possible range: FF, 01, 02, 03, 04, 05, 06, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F)
u8 flags; //Unknown; appears to be 00 if the event is slurred, c0 if it's rearticulated, 01 for the first event, also have seen 80
s8 pitch_bend; //Signed, with emulator set to 66% of control stick, gives 3C or c4, but probably could be set to larger range
u8 vibrato; //Unsigned, range 00 to 0F, same if you go L or R on the stick
u8 unknown_57 = 0x57; //Unknown, always 0x57
u16 timestamp; //Amount of time before this event, possibly continues into the next byte
u8 zero = 0; //Unknown, either always zero or a continuation of the timestamp
}
The decompile will definitely help with this!
Interpreting this as 216 4-byte words, you get alternating words of
[00-FF] (timestamp byte 2)
[00] or [00-FF] (zero, or timestamp byte 3)
[FF-0F] (note, excluding 00 and 07]
[??] (flags)
and
[C4-3F] (pitch bend)
[00-0F] (vibrato)
[57] (unknown)
[00-FF] (timestamp byte 1)
That is quite a decent amount of control, and 216 instructions is a LOT to have at your disposal to write a bootloader. And, the data here (within the bounds on each value) can be easily recorded via TAS, simply by going to the scarecrow and then making the correct changes to the controller state at the correct times. It even has the bonus that it's stored in the save file in the same format--this isn't some transient RAM state which will get changed when something else spawns in!
Perhaps this isn't the right place to bring this up, but I have been thinking about the relationship of music to ACE in another context for a while. Any successful ACE requires not only some sort of bug where execution goes somewhere it shouldn't (e.g. stack smash, jump table out of range, etc.) but also a relatively large area of memory which can be manipulated through in-game actions (e.g. Koopa shell X-coordinate table in SMW or inventory in Pokemon). Ideally, in-game actions would be able to set every byte of this memory uniquely to write whatever instructions you wanted, but it may be able to work even if there are constraints on what you can write there.
The second, "secret" scarecrow song in Ocarina of Time--the one you teach to Pierre, not the well-known one you teach to Bonooru which allows you to call Pierre--is not eight notes, but a seemingly unlimited arbitrary song that stores your pitch bends, vibrato, etc. This is the song that's played after the end credits in various different instruments (there actually may be a sequence for this--I'll have to take another look at something). Anyway, this song is stored in a unique format, different from the other scarecrow song. It starts at 0x0F60 in SRA and ends at 0x12b8 or 0x12c0, which is enough to store 108 8-byte-long events. The events are aligned to 0x2/0xA, and the format is:
struct event{
u8 note_number; // FF for rest, 00 is middle C, counts up for half steps; Z/R modifier affects this (possible range: FF, 01, 02, 03, 04, 05, 06, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F)
u8 flags; //Unknown; appears to be 00 if the event is slurred, c0 if it's rearticulated, 01 for the first event, also have seen 80
s8 pitch_bend; //Signed, with emulator set to 66% of control stick, gives 3C or c4, but probably could be set to larger range
u8 vibrato; //Unsigned, range 00 to 0F, same if you go L or R on the stick
u8 unknown_57 = 0x57; //Unknown, always 0x57
u16 timestamp; //Amount of time before this event, possibly continues into the next byte
u8 zero = 0; //Unknown, either always zero or a continuation of the timestamp
}
The decompile will definitely help with this!
Interpreting this as 216 4-byte words, you get alternating words of
[00-FF] (timestamp byte 2)
[00] or [00-FF] (zero, or timestamp byte 3)
[FF-0F] (note, excluding 00 and 07]
[??] (flags)
and
[C4-3F] (pitch bend)
[00-0F] (vibrato)
[57] (unknown)
[00-FF] (timestamp byte 1)
That is quite a decent amount of control, and 216 instructions is a LOT to have at your disposal to write a bootloader. And, the data here (within the bounds on each value) can be easily recorded via TAS, simply by going to the scarecrow and then making the correct changes to the controller state at the correct times. It even has the bonus that it's stored in the save file in the same format--this isn't some transient RAM state which will get changed when something else spawns in!
Sauraen#0047 / SEQ64 developer: https://github.com/sauraen/seq64