方法一:在 gdb 设置断点分析
ARM CPU 有个特性便是一些加减计算要传送到CPU寄存器(register) 进行,因此你会经常看到这些要找的数据会先从内存用LDR 指令载入到寄存器, 经过一些计算(加或减)后及防溢位判断后便用STR 指令存储这寄存器回内存地址。
另外由于这些程式大多是用 Objective C 或 C++ 语言写成,这些程序员会用一些描述性的函数名,例如带有 Money, Price, Gold, Exp, Item, Life, Level 字段等。
利用这两点便可以将程序锁定在某些函数上,再利用 gdb 调试工具暂停在某些点一步一步地单步执行及查看一些寄存器,印证是否与你要找的数据是否有关。
在FinalFantasy2 的这实例中, 是用这方法找到修改点
用 less 工具去找寻 Money
putty / Terminal 打
- less FinalFantasy2.original.txt
在 less 工具內打
- /Money
去开始找寻(按 N 键去继续找寻),便会找到这段代码像是要存储金钱数据(SetMoney), 0007b218是进入这段代码的开始地址
- __ZN14cFF2GlobalWork19sysGAMEPrm_SetMoneyEj:
- 0007b218 e59f300c ldr r3, [pc, #12] ; 0x7b22c
- 0007b21c e580120c str r1, [r0, #524]
- 0007b220 e1510003 cmp r1, r3
- 0007b224 8580320c strhi r3, [r0, #524]
- 0007b228 e12fff1e bx lr
首先在iPhone或iPod Touch 开始Final Fantasy 2 直至游戏已 Resume及进入游戏。
① 在PuTTY / Terminal 找FinalFantasy2 的运行中的进程编号(process id)
PuTTY / Terminal 打
- ps ax
得到
- 1115 ?? Ss 1:30.86 /var/mobile/Applications/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/FinalFantasy2.app/FinalFantasy2
找到FinalFantasy2 游戏现时运行中的进程编号是 1115
② 用gdb 进入调试运行中的进程编号 1115
PuTTY / Terminal 打
- gdb -p 1115
此时游戏会暂停,音乐也暂停
③ 用gdb 设定断点breakpoint在十六进制地址 0x7b218
PuTTY / Terminal 打
- break *0x7b218
④ 继续 continue 游戏
PuTTY / Terminal 打
- c
⑤ 将Final Fantasy 2 游戏进入战斗,战胜后游戏会在十六进制地址0x7b218处停止
⑥ 暂停后,离开这分支__ZN14cFF2GlobalWork19sysGAMEPrm_SetMoneyEj
PuTTY / Terminal 打
- finish
⑦ 反汇编现时地址上面的代码
- disassem $pc-28 $pc
得到
- 0x0003baac <_ZN10FF2cBattle12SENRIHIN_CHKEP12thBATMonsterP6X86REG 180>: bl 0x78e30 <_ZN14cFF2GlobalWork8InstanceEv>
- 0x0003bab0 <_ZN10FF2cBattle12SENRIHIN_CHKEP12thBATMonsterP6X86REG 184>: mov r4, r0
- 0x0003bab4 <_ZN10FF2cBattle12SENRIHIN_CHKEP12thBATMonsterP6X86REG 188>: bl 0x78e30 <_ZN14cFF2GlobalWork8InstanceEv>
- 0x0003bab8 <_ZN10FF2cBattle12SENRIHIN_CHKEP12thBATMonsterP6X86REG 192>: bl 0x7b230 <_ZN14cFF2GlobalWork19sysGAMEPrm_GetMoneyEv>
- 0x0003babc <_ZN10FF2cBattle12SENRIHIN_CHKEP12thBATMonsterP6X86REG 196>: add r1, r0, r5
- 0x0003bac0 <_ZN10FF2cBattle12SENRIHIN_CHKEP12thBATMonsterP6X86REG 200>: mov r0, r4
- 0x0003bac4 <_ZN10FF2cBattle12SENRIHIN_CHKEP12thBATMonsterP6X86REG 204>: bl 0x7b218 <_ZN14cFF2GlobalWork19sysGAMEPrm_SetMoneyEj>
这时会发现在_ZN14cFF2GlobalWork19sysGAMEPrm_ GetMoneyEv
及_ZN14cFF2GlobalWork19sysGAMEPrm_ SetMoneyEj
中间 0x0003babc 地址的代码add r1, r0, r5 是最可疑的
⑧ 取消断点1及设定新断点breakpoint在十六进制地址 0x0003babc 及重新继续continue 游戏
PuTTY / Terminal 打
- disable 1
- break *0x3babc
- c
在iPhone或iPod Touch查看现时游戏的金钱例如是4888,将Final Fantasy 2 游戏进入战斗,战胜后游戏会新断点2地址0x3babc处停止
⑨ 当游戏在新断点2暂停时查看寄存器就发现 r0 是当时的金钱余额及 r5 是战胜后得到的金钱
PuTTY / Terminal 打
- i r $r0 $r1 $r5 $pc
⑩ 假设已找到应修改的地址是 0003babc,便可继续下面第(8)步