0

你好,堆栈溢出者,

我准备创建一个程序,当它在足球模拟器 FIFA 19 中实际进球时播放主队的进球。

我知道游戏本身没有开放的 API。我看到使用的唯一方法是从内存中实际轮询结果。我不知道这是否符合游戏的最终用户许可协议,但我不打算以任何方式实际作弊。

对于研究,我从https://github.com/xAranaktu/FIFA-19---Career-Mode-Cheat-Table找到并查找了作弊引擎表。它提供了通过作弊引擎读取或写入比赛分数的能力。

可悲的是,我无法对表格进行逆向工程。我找到了从内存中读取值的代码。但是我很难弄清楚每条线的作用。

[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)

我对指针、堆栈是什么以及汇编程序的作用有基本的了解。但我无法理解这里发生的事情。也许你可以给我逐行描述正在发生的事情。

先感谢您。

4

1 回答 1

0

本质上,这是一个使用 Cheat Engine 脚本功能将代码流引导到注入的 shellcode 的钩子。我将把每一行分解成它的基本目的来帮助解释它。在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

扫描该特定模式的进程,将匹配模式的位置存储在 INJECT_matchScore

alloc(matchscore_cave,$1000,"FIFA19.exe"+2578D85)

在大小为 1000 字节的“FIFA19.exe”+2578D85 附近分配内存,并将此内存的地址存储在matchscore_cave 中。这是放置你的 shellcode 的地方

alloc(ptrHomeTeamScore, 8)
registersymbol(ptrHomeTeamScore)
ptrHomeTeamScore:
dq 00

分配 8 个字节来存储 64 位指针,注册变量符号名称并为其分配 QWORD 值 0x0

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

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

获取存储在 rcx 中的指针并将其存储在 ptrHomeTeamScore

code_matchscore:
  mov r8d,[rcx+0000011C]
  popf
  jmp return_matchscore

在 RCX 的偏移量 0x11C 处,获取该值并将其存储在寄存器 r8d 弹出标志中,将它们恢复到初始挂钩 jmp 之前的状态

INJECT_matchScore+5B:
  jmp matchscore_cave
  nop
  nop

将原始程序集和 jmp 覆盖到您注入的代码中,将流程从游戏代码引导到您自己的代码中

于 2019-07-23T03:26:36.583 回答