I'm trying to make a simple "one hit kill" script for a game called Terranigma for the SNES just for fun, but I'm having lots of trouble with it due to a bunch of different reasons:
1 - Values are 2 Bytes and 2 Bytes Big Endian
2 - The instruction writing to my value actually writes to pretty much EVERYTHING (more than 800 different things at once)
3 - "Find out what addresses this instruction accesses" makes the emulator SUPER slow (1-2 FPS) due to how many different addresses it accesses at the same time, all the time
Despite my efforts, I couldn't make the script work. As soon as I activate it, the emulator crashes completely. I am positive that I'm missing something dumb.
Code: Select all
// ORIGINAL CODE - INJECTION POINT: snes9x_libretro.dll+21355
snes9x_libretro.dll+21324: 75 77 - jne snes9x_libretro.dll+2139D
snes9x_libretro.dll+21326: 41 8D 8C 24 00 C0 FF FF - lea ecx,[r12-00004000]
snes9x_libretro.dll+2132E: 80 E5 7E - and ch,7E
snes9x_libretro.dll+21331: 48 8B 0D F8 D2 26 00 - mov rcx,[snes9x_libretro.dll+28E630]
snes9x_libretro.dll+21338: 0F 85 12 01 00 00 - jne snes9x_libretro.dll+21450
snes9x_libretro.dll+2133E: 8B A9 48 04 00 00 - mov ebp,[rcx+00000448]
snes9x_libretro.dll+21344: 48 8B 1D E5 CF 26 00 - mov rbx,[snes9x_libretro.dll+28E330]
snes9x_libretro.dll+2134B: 48 83 F8 12 - cmp rax,12
snes9x_libretro.dll+2134F: 76 66 - jna snes9x_libretro.dll+213B7
snes9x_libretro.dll+21351: 45 0F B7 E4 - movzx r12d,r12w
// ---------- INJECTING HERE ----------
snes9x_libretro.dll+21355: 66 42 89 34 20 - mov [rax+r12],si
// ---------- DONE INJECTING ----------
snes9x_libretro.dll+2135A: 80 7B 32 00 - cmp byte ptr [rbx+32],00
snes9x_libretro.dll+2135E: 75 1D - jne snes9x_libretro.dll+2137D
snes9x_libretro.dll+21360: 8B 43 04 - mov eax,[rbx+04]
snes9x_libretro.dll+21363: 8D 04 68 - lea eax,[rax+rbp*2]
snes9x_libretro.dll+21366: 89 43 04 - mov [rbx+04],eax
snes9x_libretro.dll+21369: 3B 43 40 - cmp eax,[rbx+40]
snes9x_libretro.dll+2136C: 7C 0F - jl snes9x_libretro.dll+2137D
snes9x_libretro.dll+2136E: 66 90 - nop 2
snes9x_libretro.dll+21370: E8 9B 58 FF FF - call snes9x_libretro.dll+16C10
snes9x_libretro.dll+21375: 8B 43 40 - mov eax,[rbx+40]
}
So mov [rax+r12],si is the instruction accessing everything.
I tried a bunch of different approaches to isolate the differences with the HP values (right now I don't mind if everything in the game dies with a single hit, I just want the script not to crash my game), such as:
Comiss with XMN3
Cmp values
Cmp int
Just make a blank script that only cmp (sometimes crashed the game as well)
So far, nothing really worked.
My theory is that there is something I must do with "si", since it is not "rsi" and can't be compared properly, or I'm using the cmp wrong.
I also think I'm doing something wrong with the cmp and mov commands since I'm dealing with 2 byte values and 2 byte big endian for the first time.
I already know how to make the One Hit Kill script (and some other basic scripts) for non-emulated games without a problem. But I can't seem to make this work for SNES games, sadly (I checked another game called "ARCANA" and the instruction that writes to everything is the exact same one, so it IS an emulator thing.
Oh, I also found the static addresses and the proper array of bytes that never change, too.
Could anyone please point me into the right direction? I'm at a loss at the moment.
Here are a few scripts that I tried:
Code: Select all
[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
alloc(newmem,2048,"snes9x_libretro.dll"+21355)
alloc(number,4)
label(returnhere)
label(originalcode)
label(exit)
number:
dw 7C
newmem: //this is allocated memory, you have read,write,execute access
//place your code here
comiss xmm3,[number]
jbe originalcode
jmp exit
originalcode:
mov [rax+r12],si
jmp exit
exit:
jmp returnhere
"snes9x_libretro.dll"+21355:
jmp newmem
returnhere:
[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(newmem)
"snes9x_libretro.dll"+21355:
db 66 42 89 34 20
//mov [rax+r12],si
Code: Select all
[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
alloc(newmem,2048,"snes9x_libretro.dll"+21355)
alloc(number,8)
label(returnhere)
label(originalcode)
label(exit)
number:
dw BC
newmem: //this is allocated memory, you have read,write,execute access
//place your code here
comiss xmm3,[number]
jbe originalcode
movss xmm3,[number]
jmp exit
originalcode:
mov [rax+r12],si
jmp exit
exit:
jmp returnhere
"snes9x_libretro.dll"+21355:
jmp newmem
returnhere:
[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(newmem)
"snes9x_libretro.dll"+21355:
db 66 42 89 34 20
//mov [rax+r12],si
Code: Select all
[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
alloc(newmem,2048,"snes9x_libretro.dll"+21355)
label(returnhere)
label(originalcode)
label(exit)
newmem: //this is allocated memory, you have read,write,execute access
//place your code here
push eax
movd eax,xmm3
cmp eax,000000BC
je originalcode
jmp exit
originalcode:
mov [rax+r12],si
exit:
pop eax
jmp returnhere
"snes9x_libretro.dll"+21355:
jmp newmem
returnhere:
[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(newmem)
"snes9x_libretro.dll"+21355:
db 66 42 89 34 20
//mov [rax+r12],si
Code: Select all
{ Game : retroarch.exe
Version:
Date : 2023-08-04
Author : Zvezda
This script does blah blah blah
}
[ENABLE]
aobscanmodule(INJECT,snes9x_libretro.dll,66 42 89 34 20 80 7B 32 00 75) // should be unique
alloc(newmem,$1000,INJECT)
label(code)
label(return)
newmem:
cmp [rsi+FC],(int)0
je code
jne return
code:
mov [rax+r12],si
jmp return
INJECT:
jmp newmem
return:
registersymbol(INJECT)
[DISABLE]
INJECT:
db 66 42 89 34 20
unregistersymbol(INJECT)
dealloc(newmem)
{
// ORIGINAL CODE - INJECTION POINT: snes9x_libretro.dll+21355
snes9x_libretro.dll+21324: 75 77 - jne snes9x_libretro.dll+2139D
snes9x_libretro.dll+21326: 41 8D 8C 24 00 C0 FF FF - lea ecx,[r12-00004000]
snes9x_libretro.dll+2132E: 80 E5 7E - and ch,7E
snes9x_libretro.dll+21331: 48 8B 0D F8 D2 26 00 - mov rcx,[snes9x_libretro.dll+28E630]
snes9x_libretro.dll+21338: 0F 85 12 01 00 00 - jne snes9x_libretro.dll+21450
snes9x_libretro.dll+2133E: 8B A9 48 04 00 00 - mov ebp,[rcx+00000448]
snes9x_libretro.dll+21344: 48 8B 1D E5 CF 26 00 - mov rbx,[snes9x_libretro.dll+28E330]
snes9x_libretro.dll+2134B: 48 83 F8 12 - cmp rax,12
snes9x_libretro.dll+2134F: 76 66 - jna snes9x_libretro.dll+213B7
snes9x_libretro.dll+21351: 45 0F B7 E4 - movzx r12d,r12w
// ---------- INJECTING HERE ----------
snes9x_libretro.dll+21355: 66 42 89 34 20 - mov [rax+r12],si
// ---------- DONE INJECTING ----------
snes9x_libretro.dll+2135A: 80 7B 32 00 - cmp byte ptr [rbx+32],00
snes9x_libretro.dll+2135E: 75 1D - jne snes9x_libretro.dll+2137D
snes9x_libretro.dll+21360: 8B 43 04 - mov eax,[rbx+04]
snes9x_libretro.dll+21363: 8D 04 68 - lea eax,[rax+rbp*2]
snes9x_libretro.dll+21366: 89 43 04 - mov [rbx+04],eax
snes9x_libretro.dll+21369: 3B 43 40 - cmp eax,[rbx+40]
snes9x_libretro.dll+2136C: 7C 0F - jl snes9x_libretro.dll+2137D
snes9x_libretro.dll+2136E: 66 90 - nop 2
snes9x_libretro.dll+21370: E8 9B 58 FF FF - call snes9x_libretro.dll+16C10
snes9x_libretro.dll+21375: 8B 43 40 - mov eax,[rbx+40]
}