Monday, October 9, 2017

Fixing an almost-working patch

Last time, I attempted to translate the "don't check whether Keen actually has the pogo before pogoing" patch from Keen 1 to Keen 2. It almost worked - Keen could always pogo starting from the ground, but not the air. My start was this:

%patch $6958 $EB $05
%patch $6BD0 $EB $0C

First I needed to find which of the two lines affected which check. When I commented out the first, ground-based pogoing stopped working, so that one was fine; the second line was the problem. Since I can't read most machine code, I fired up IDA and jumped to 0x6BD0. Bizarrely, I found that it wasn't actually near a comparison with the pogo variable - it was right on the stack-pointer-incrementing tail of some other function. Down a little bit was a pogo check (which I identified by having the variable named in IDA based on the correct half of the patch).

Having found the actual jump instruction at $6BF3, I tried patching the jump condition to be unconditional ($EB). That did something in that the pogo never worked in the air, even after acquiring it with C+T+Space. I don't know if there's a jump condition that never jumps, but since it was a check for equality ($74), I replaced the previous byte - the number the variable is compared to - with something ($FE) that the pogo variable never gets set to. The fixed second line is this:

%patch $6BF2 $FE

So, why didn't the patch at $6BD0 work, even though I found the right sequence of bytes? Turns out I had transcribed the location from XVI32's left column, which shows the address at the start of the line, not the address of the selected byte, for which I should have looked at the bottom left in the status bar. Oops - turns out patching right before sleeping might not be the greatest idea.

No comments:

Post a Comment