IDA + LLDB 查找数据的位移

工具:

– IDA Program/Hopper
– Jailbroken iOS
– iGameGod/iMemEditor 数据修改器.
– LLDB 动态调试器

LLDB

我们修改的游戏 家族旅店
修改的内容是无限钻石

打开程序,看到程序的应用名字

devxp:~ root# ps aux | grep containers | grep .app
mobile 1438 79.9 10.2 409247952 296864 ?? Rs 6:20PM 0:06.01 /var/containers/Bundle/Application/33F5CD68-CE1E-4B7B-8D4D-112D97A4A423/china.app/china

这里我们使用内存搜索对应的数据,确认我们的断点分析位置
使用iMemEditor搜对应的数据, 这个就是数据变化的点,通过它反向找到对应的IDA中的位移

这个数据存在于2个位置,一般情况下,一个是后台数据,一个是前台数据,这个记住,并且不要退出程序,否则需要重新查找

手机上运行debugserver挂载程序,运行了以后程序会停止运行

devxp:~ root# debugserver 172.16.4.70:12345 -a china
debugserver-@(#)PROGRAM:LLDB  PROJECT:lldb-1200.2.12
 for arm64.
Attaching to process china...
Listening to port 12345 for a connection from 172.16.4.70...

MAC上链接至服务器进行调试

zeno@zeno-mbp data % lldb
(lldb) process connect connect://172.16.4.197:12345
Process 921 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
    frame #0: 0x00000001055c3790 UnityFramework`___lldb_unnamed_symbol20063
UnityFramework`___lldb_unnamed_symbol20063:
->  0x1055c3790 <+0>:  sub    sp, sp, #0xa0
    0x1055c3794 <+4>:  stp    d9, d8, [sp, #0x30]
    0x1055c3798 <+8>:  stp    x28, x27, [sp, #0x40]
    0x1055c379c <+12>: stp    x26, x25, [sp, #0x50]
Target 0: (china) stopped.

业务逻辑模块查看下基址

(lldb) image list UnityFramework
[  0] 8089E3F9-E036-35A2-B3C2-6F425491FF78 0x00000001055b8000 /private/var/containers/Bundle/Application/33F5CD68-CE1E-4B7B-8D4D-112D97A4A423/china.app/Frameworks/UnityFramework.framework/UnityFramework (0x00000001055b8000)

记住最后的几位数字: 55b8000

然后在对应的数据上创建断点

(lldb) w s e -- 0x122679944
Watchpoint created: Watchpoint 1: addr = 0x122679944 size = 8 state = enabled type = w
    new value: 1975684956320
(lldb) w s e -- 0x122679944
Watchpoint created: Watchpoint 1: addr = 0x122679944 size = 8 state = enabled type = w
    new value: 1975684956320
(lldb) c
Process 921 resuming

继续玩一下游戏,到了断点会停止

Watchpoint 1 hit:
old value: 1975684956320
new value: 1975684956376
Process 921 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = watchpoint 1
    frame #0: 0x00000001079a1f2c UnityFramework`___lldb_unnamed_symbol229760 + 40
UnityFramework`___lldb_unnamed_symbol229760:
->  0x1079a1f2c <+40>: cmp    w19, #0x1
    0x1079a1f30 <+44>: b.lt   0x1079a1f48               ; <+68>
    0x1079a1f34 <+48>: ldp    w8, w9, [x0, #0x18]
    0x1079a1f38 <+52>: add    w8, w8, w19
Target 0: (china) stopped.

frame #0 = 这个就是我们在IDA中位移 (忽略1之前的000)

最后计算出二进制文件中对应的位移

0x79a1f2c – 0x55b8000 = 0x23E9F2C

导出寄存器中的信息,稍后会使用到

(lldb) register read
General Purpose Registers:
        x0 = 0x0000000122679930
        x1 = 0x000000014b6df698
        x2 = 0x0000000107b98350  UnityFramework`___lldb_unnamed_symbol239758
        x3 = 0x000000014b6df1f8
        x4 = 0x0000000000000004
        x5 = 0x0000000000000000
        x6 = 0x0000000136560f20
        x7 = 0x0000000000000000
        x8 = 0x00000000000000d8
        x9 = 0x0000000000000018
       x10 = 0x000000014b6df550
       x11 = 0x000000014b6d2ed8
       x12 = 0x0000000000000001
       x13 = 0x0000000091800810
       x14 = 0x0000000091a01000
       x15 = 0x0000000000000002
       x16 = 0x00000001d38a25f0  libsystem_platform.dylib`_platform_memmove
       x17 = 0x0000000011a00000
       x18 = 0x0000000000000000
       x19 = 0x0000000000000038
       x20 = 0x0000000000000038
       x21 = 0x0000000122be4cc0
       x22 = 0x000000010a2762d0  UnityFramework`baseUrlType + 133728
       x23 = 0x000000010a273700  UnityFramework`baseUrlType + 122512
       x24 = 0x0000000000000000
       x25 = 0x000000014f3f8540
       x26 = 0x0000000105ea4aa8  UnityFramework`___lldb_unnamed_symbol86773
       x27 = 0x000000010a270008  UnityFramework`baseUrlType + 108440
       x28 = 0x0000000109e95000  
        fp = 0x000000016b004ee0
        lr = 0x00000001079a1f18  UnityFramework`___lldb_unnamed_symbol229760 + 20
        sp = 0x000000016b004ed0
        pc = 0x00000001079a1f2c  UnityFramework`___lldb_unnamed_symbol229760 + 40
      cpsr = 0x80000000

继续运行

(lldb) c
Process 921 resuming

然后继续卡住在第二个断点

Process 921 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=258, subcode=0x122679940)
    frame #0: 0x00000001079a1f40 UnityFramework`___lldb_unnamed_symbol229760 + 60
UnityFramework`___lldb_unnamed_symbol229760:
->  0x1079a1f40 <+60>: stp    w8, w9, [x0, #0x18]
    0x1079a1f44 <+64>: b      0x1079a1f58               ; <+84>
    0x1079a1f48 <+68>: ldr    w8, [x0, #0x20]
    0x1079a1f4c <+72>: sub    w8, w8, w19
Target 0: (china) stopped.

最后计算出二进制文件中对应的位移

0x79a1f40 – 0x55b8000 = 0x23E9F40

导出寄存器中的信息,稍后会使用到

(lldb) register read
General Purpose Registers:
x0 = 0x0000000122679930
x1 = 0x000000014b6df698
x2 = 0x0000000107b98350 UnityFramework___lldb_unnamed_symbol239758 x3 = 0x000000014b6df1f8 x4 = 0x0000000000000004 x5 = 0x0000000000000000 x6 = 0x0000000136560f20 x7 = 0x0000000000000000 x8 = 0x0000000000000204 x9 = 0x0000000000000008 x10 = 0x000000014b6df550 x11 = 0x000000014b6d2ed8 x12 = 0x0000000000000001 x13 = 0x0000000091800810 x14 = 0x0000000091a01000 x15 = 0x0000000000000002 x16 = 0x00000001d38a25f0 libsystem_platform.dylib_platform_memmove
x17 = 0x0000000011a00000
x18 = 0x0000000000000000
x19 = 0x0000000000000038
x20 = 0x0000000000000038
x21 = 0x0000000122be4cc0
x22 = 0x000000010a2762d0 UnityFrameworkbaseUrlType + 133728 x23 = 0x000000010a273700 UnityFrameworkbaseUrlType + 122512
x24 = 0x0000000000000000
x25 = 0x000000014f3f8540
x26 = 0x0000000105ea4aa8 UnityFramework___lldb_unnamed_symbol86773 x27 = 0x000000010a270008 UnityFrameworkbaseUrlType + 108440
x28 = 0x0000000109e95000
fp = 0x000000016b004ee0
lr = 0x00000001079a1f18 UnityFramework___lldb_unnamed_symbol229760 + 20 sp = 0x000000016b004ed0 pc = 0x00000001079a1f40 UnityFramework___lldb_unnamed_symbol229760 + 60
cpsr = 0x20000000

上面已经把数据采集差不多了

查看对应偏移的汇编指令

当时我们的金币数量是: 160, 使用下面的网址转换成实际的数据,结果为A0

https://www.binaryhexconverter.com/decimal-to-hex-converter

W8 = 金币数量, X & W 基本相同

                     sub_23e9f04:
00000000023e9f04         stp        x20, x19, [sp, #-0x20]!                     ; CODE XREF=sub_23e8464+3016, sub_23e8464+3260
00000000023e9f08         stp        fp, lr, [sp, #0x10]
00000000023e9f0c         add        fp, sp, #0x10
00000000023e9f10         mov        x19, x2
00000000023e9f14         bl         sub_23e8464+300
00000000023e9f18         cbz        x0, loc_23e9f64

00000000023e9f1c         cbz        w19, loc_23e9f58

00000000023e9f20         ldr        w8, [x0, #0x14]
00000000023e9f24         add        w8, w8, w19
00000000023e9f28         str        w8, [x0, #0x14]
00000000023e9f2c         cmp        w19, #0x1
00000000023e9f30         b.lt       loc_23e9f48

00000000023e9f34         ldp        w8, w9, [x0, #0x18]
00000000023e9f38         add        w8, w8, w19
00000000023e9f3c         add        w9, w9, #0x1
00000000023e9f40         stp        w8, w9, [x0, #0x18]
00000000023e9f44         b          loc_23e9f58

类似: X19+0x40 = 
X19 = 内存地址, 0x40 保存的变量. 
组合起来就是指向保存的地址

修改方法很多种

LDR             W8, [x0, #0x14]
- 修改成: MOV W8, #0xfffff --> 直接设置成最大的值到W8
- 修改成: LDR W8, [X20]    --> X20 是一个带有更大数据的寄存器.

STR             W8, [x0, #0x14]
- 修改W8成W20              --> 把一个较大数值存入x0, #0x14
- 修改成NOP                --> 这样就不执行指令,一般用于不减少.

也可以使用外挂

1.改成大值

    if(GetPrefBool(@"key1")) {
      vm_writeData(0x123456, 0x123456); //The first value should be the offset & the second value the hackedHex
    }

2.修改成不减少

    if(GetPrefBool(@"key1")) {
      vm_writeData(0x10092DEE8, 0x1F2003D5); // 
    }

关于Zeno Chen

本人涉及的领域较多,杂而不精 程序设计语言: Perl, Java, PHP, Python; 数据库系统: MySQL,Oracle; 偶尔做做电路板的开发,主攻STM32单片机
此条目发表在Objective-C, 默认分类分类目录。将固定链接加入收藏夹。