Hello fellow stack overflowers,
I'm up to create a program that plays the home teams goalhymn when it actually scored a goal in the football simulator FIFA 19.
I know there is no open API for the game itself. The only method I see to use is to actually poll the result from the memory. I do not know if this does comply with the end user license agreement of the game, but I have not in mind to actually cheat in any way.
For research I found and looked up the Cheat Engine Table from https://github.com/xAranaktu/FIFA-19---Career-Mode-Cheat-Table. It gives the ability to read or write the match score via Cheat Engine.
Sadly, I'm having trouble to reverse engineer the table. I've found the bit of code that reads the value from memory. But I'm having a hard time figuring out what each line does.
[ENABLE]
aobscanmodule(INJECT_matchScore,FIFA19.exe,48 8B 41 20 48 89 42 20 8B 41 28 89 42 28 41 8B 54) // should be unique
alloc(matchscore_cave,$1000,"FIFA19.exe"+2578D85)
alloc(ptrHomeTeamScore, 8)
registersymbol(ptrHomeTeamScore)
ptrHomeTeamScore:
dq 00
alloc(ptrAwayTeamScore, 8)
registersymbol(ptrAwayTeamScore)
ptrAwayTeamScore:
dq 00
label(code_matchscore)
label(home_matchscore)
label(away_matchscore)
label(return_matchscore)
matchscore_cave:
pushf
cmp rdx, 00
je home_matchscore
cmp rdx, 01
je away_matchscore
jmp code_matchscore
home_matchscore:
mov [ptrHomeTeamScore], rcx
jmp code_matchscore
away_matchscore:
mov [ptrAwayTeamScore], rcx
jmp code_matchscore
code_matchscore:
mov r8d,[rcx+0000011C]
popf
jmp return_matchscore
INJECT_matchScore+5B:
jmp matchscore_cave
nop
nop
return_matchscore:
registersymbol(INJECT_matchScore)
I have basic knowledge of what a pointer, a stack is and what assembler does. But I cannot understand the things going on here. Maybe you can give me a line by line description of what's going on.
Thank you in advance.
Essentially this is a hook which directs the code flow into your injected shellcode using the Cheat Engine scripting capability. I'm going to break down each line into it's basic purpose to help explain it. Learn more about it in the Cheat Engine Wiki
aobscanmodule(INJECT_matchScore,FIFA19.exe,48 8B 41 20 48 89 42 20 8B 41 28 89 42 28 41 8B 54) // should be unique
Scans the process for that specific pattern, stores the location of the matching pattern in INJECT_matchScore
alloc(matchscore_cave,$1000,"FIFA19.exe"+2578D85)
Allocates memory near "FIFA19.exe"+2578D85 that is 1000 bytes in size and stores the address of this memory inmatchscore_cave. This is where your shellcode will be placed
alloc(ptrHomeTeamScore, 8)
registersymbol(ptrHomeTeamScore)
ptrHomeTeamScore:
dq 00
allocated 8 bytes to store a 64bit pointer, registers the variable symbol name and assigns it QWORD value of 0x0
alloc(ptrAwayTeamScore, 8)
registersymbol(ptrAwayTeamScore)
ptrAwayTeamScore:
dq 00
same as above
label(code_matchscore)
label(home_matchscore)
label(away_matchscore)
label(return_matchscore)
creatse some labels for assembly blocks that you can jmp to, defined below
matchscore_cave:
pushf
cmp rdx, 00
je home_matchscore
cmp rdx, 01
je away_matchscore
jmp code_matchscore
push flags if rdx == 0, jmp to home_matchscore else if rdx == 1, jmp to away_matchscore else jmp code_matchscore
home_matchscore:
mov [ptrHomeTeamScore], rcx
jmp code_matchscore
away_matchscore:
mov [ptrAwayTeamScore], rcx
jmp code_matchscore
grab the pointer stored in rcx and store it in ptrHomeTeamScore
code_matchscore:
mov r8d,[rcx+0000011C]
popf
jmp return_matchscore
At offset 0x11C from RCX, grab the value and store it in register r8d pop flags, restoring them to what they were before the initial hook jmp
INJECT_matchScore+5B:
jmp matchscore_cave
nop
nop
overwrite the original assembly and jmp to your injected code, directing flow from the game code into your own code