0

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.

1 Answers1

0

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

GuidedHacking
  • 3,628
  • 1
  • 9
  • 59