shithub: zelda3

Download patch

ref: 5defa99a116211ad5e1ab12f6739d7bc40699756
parent: aaf43972b821ab06e955e5dca453412d55e6ef58
author: Snesrev <snesrev@protonmail.com>
date: Mon Mar 6 15:07:17 EST 2023

Fix OOB read in Link_APress_LiftCarryThrow (Fixes #174)

--- a/player.c
+++ b/player.c
@@ -3556,8 +3556,7 @@
   } else {
     static const uint8 kLiftTab0[10] = { 8, 24, 8, 24, 8, 32, 6, 8, 13, 13 };
     static const uint8 kLiftTab1[10] = { 0, 1, 0, 1, 0, 1, 0, 1, 2, 3 };
-    static const uint8 kLiftTab2[] = { 6, 7, 7, 5, 10, 0, 23, 0, 18, 0, 18, 0, 8, 0, 8, 0, 254, 255, 17, 0,
-      0x54, 0x52, 0x50, 0xFF, 0x51, 0x53, 0x55, 0x56, 0x57};
+    static const uint8 kLiftTab2[] = { 6, 7, 7, 5 };
 
     if (player_handler_timer != 0) {
       if (player_handler_timer + 1 != 9) {
@@ -3576,8 +3575,9 @@
         return;
       }
     } else {
-
-      // todo: This is an OOB read triggered when lifting for too long
+      // fix OOB read triggered when lifting for too long
+      if (some_animation_timer_steps >= 3)
+        return;
       some_animation_timer = kLiftTab2[++some_animation_timer_steps];
       assert(some_animation_timer_steps < arraysize(kLiftTab2));
       if (some_animation_timer_steps != 3)
--- a/snes/cpu.c
+++ b/snes/cpu.c
@@ -735,10 +735,16 @@
 void HookedFunctionRts(int is_long);
 
 static void cpu_doOpcode(Cpu* cpu, uint8_t opcode) {
+RESTART:
   switch(opcode) {
     case 0x00: { // brk imp
       uint32_t addr = (cpu->k << 16) | cpu->pc;
       switch (addr - 1) {
+      case 0x7B269:  // Link_APress_LiftCarryThrow reads OOB
+        if ((cpu->x & 0xff) >= 3)
+          cpu->pc = 0xB280; // RTS
+        opcode = 0xE8;
+        goto RESTART;
 
         // Uncle_AtHome case 3 will read random memory. 
       case 0x5DEC7:
--- a/zelda_cpu_infra.c
+++ b/zelda_cpu_infra.c
@@ -517,6 +517,8 @@
 
   PatchRomBP(rom, 0x1DCDEB); // y is destroyed earlier, restore it..
 
+  PatchRomBP(rom, 0x7B269);  // Link_APress_LiftCarryThrow oob
+
   // Smithy_Frog doesn't save X
   memmove(rom + 0x332b8, rom + 0x332b7, 4); rom[0x332b7] = 0xfa;