逆向记录Assaultcube for Mac OS

3 篇文章 0 订阅

手潮了,长时间不做逆向水平就会下降。再次记录一次逆向手段。这次争取写的更全面一些。之前的CSGO只是在windows上的一次简单实践,只是完成了glow esp。

这次在Mac OS上进行实践。

目标:血量、子弹、弹夹数的修改。TODO:透视、auto aim
手段:找到血量、子弹等属性的内存地址,通过这些内存地址反向推理player对象或者结构体的base address和属性的offset。
知识:内存搜索、mach格式、lldb调试手段、AT&T指令集、ALSR(Address Space Layout Randomization)知识点请自行Google it!
工具:Bit-Slicer、lldb

步骤:
1. 打开游戏,建立游戏,通过Bit-Slicer找到子弹的地址 0x10200FF68
2. 找到游戏的pid: ps aux | grep -i assaultcube ·pid 为 40880·
3. 使用lldb调试器,attach pid:process attach --pid 40880
4. 通过Bit-Slicer找到血量地址 0x10200F710,可以用炸弹或者别人打你一枪,只要不爆头哈哈。设置观察点命令请看第4条

# 血量变成889
Watchpoint 1 hit:
old value: 889
new value: 889
Process 55018 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = watchpoint 1
    frame #0: 0x000000010002c100 assaultcube`___lldb_unnamed_symbol497$$assaultcube + 688
assaultcube`___lldb_unnamed_symbol497$$assaultcube:
->  0x10002c100 <+688>: subl   %esi, %r13d
    0x10002c103 <+691>: subl   %r13d, 0x110(%r12)
    0x10002c10b <+699>: cmpq   %r12, %r14
    0x10002c10e <+702>: jne    0x10002c1b8               ; <+872>
Target 0: (assaultcube) stopped.

(lldb) register read
General Purpose Registers:
       rax = 0x0000000000000000
       rbx = 0x0000000000000001
       rcx = 0x0000000000000003
       rdx = 0x0000000000000000
       rdi = 0x0000000000000000
       rsi = 0x0000000000000000
       rbp = 0x00007ffeefbff510
       rsp = 0x00007ffeefbff4c0
        r8 = 0x0000000000000000
        r9 = 0x000000000000002c
       r10 = 0x0000000000000003
       r11 = 0x0000000000000000
       r12 = 0x000000010200f600
       r13 = 0x000000000000002c
       r14 = 0x000000010200f600
       r15 = 0x0000000103bd0a00
       rip = 0x000000010002c100  assaultcube`___lldb_unnamed_symbol497$$assaultcube + 688
    rflags = 0x0000000000200246
        cs = 0x000000000000002b
        fs = 0x0000000000000000
        gs = 0x0000000000000000

通过AT&T指令集,不懂的同学自行学习,这里不展开说,只说结论:

0x10002c103 <+691>: subl   %r13d, 0x110(%r12)

这个指令集是 ($r12的地址 + 0x110)指向的值其实就是血量,而$r12其实就是player结构体的地址,通过读取寄存器可以找到 $r12 = 0x10200f600

你可以通过lldb确认一下刚才的指令

(lldb) p/x 0x000000010200f600 + 0x110
(long) $6 = 0x000000010200f710
(lldb) memory read 0x000000010200f710
0x10200f710: 79 03 00 00 00 00 00 00 06 00 00 00 06 00 00 00  y...............
0x10200f720: 06 00 00 00 00 00 00 00 01 00 00 00 46 00 00 00  ............F...
(lldb) p/d 0x379
(int) $12 = 889
# 这里可以看到确实是血量

接下来简单了,可以使用vmmap命令,或者lldb找到内存的region

$ vmmap 55018 | grep "assaultcube$"
Path:            /Applications/AssaultCube.app/Contents/gamedata/assaultcube.app/Contents/MacOS/assaultcube
__TEXT                      100000000-10018c000    [ 1584K  1584K     4K     0K] r-x/rwx SM=COW          /Applications/AssaultCube.app/Contents/gamedata/assaultcube.app/Contents/MacOS/assaultcube
__LINKEDIT                  1001d1000-1001d8000    [   28K    28K     0K     0K] r--/rwx SM=COW          /Applications/AssaultCube.app/Contents/gamedata/assaultcube.app/Contents/MacOS/assaultcube
__DATA                      10018c000-100193000    [   28K    28K    28K     0K] rw-/rwx SM=COW          /Applications/AssaultCube.app/Contents/gamedata/assaultcube.app/Contents/MacOS/assaultcube
__DATA                      100193000-1001d1000    [  248K   248K   244K     0K] rw-/rwx SM=PRV          /Applications/AssaultCube.app/Contents/gamedata/assaultcube.app/Contents/MacOS/assaultcube

__DATA段就是,另外一个方法:

(lldb) image dump sections assaultcube
Sections for '/Applications/AssaultCube.app/Contents/gamedata/assaultcube.app/Contents/MacOS/assaultcube' (x86_64):
  SectID     Type             Load Address                             Perm File Off.  File Size  Flags      Section Name
  ---------- ---------------- ---------------------------------------  ---- ---------- ---------- ---------- ----------------------------
  0x00000100 container        [0x0000000000000000-0x0000000100000000)* ---  0x00000000 0x00000000 0x00000000 assaultcube.__PAGEZERO
  0x00000200 container        [0x0000000100000000-0x000000010018c000)  r-x  0x00000000 0x0018c000 0x00000000 assaultcube.__TEXT
  0x00000001 code             [0x0000000100001640-0x000000010013780c)  r-x  0x00001640 0x001361cc 0x80000400 assaultcube.__TEXT.__text
  0x00000002 code             [0x000000010013780c-0x000000010013807c)  r-x  0x0013780c 0x00000870 0x80000408 assaultcube.__TEXT.__stubs
  0x00000003 code             [0x000000010013807c-0x0000000100138e9c)  r-x  0x0013807c 0x00000e20 0x80000400 assaultcube.__TEXT.__stub_helper
  0x00000004 regular          [0x0000000100138ea0-0x0000000100155ae4)  r-x  0x00138ea0 0x0001cc44 0x00000000 assaultcube.__TEXT.__const
  0x00000005 data-cstr        [0x0000000100155af0-0x0000000100165b12)  r-x  0x00155af0 0x00010022 0x00000002 assaultcube.__TEXT.__cstring
  0x00000006 regular          [0x0000000100165b14-0x000000010016a3bc)  r-x  0x00165b14 0x000048a8 0x00000000 assaultcube.__TEXT.__gcc_except_tab
  0x00000007 data-cstr        [0x000000010016a3bc-0x000000010016a644)  r-x  0x0016a3bc 0x00000288 0x00000002 assaultcube.__TEXT.__objc_methname
  0x00000008 data-cstr        [0x000000010016a644-0x000000010016a68c)  r-x  0x0016a644 0x00000048 0x00000002 assaultcube.__TEXT.__objc_classname
  0x00000009 data-cstr        [0x000000010016a68c-0x000000010016a6c2)  r-x  0x0016a68c 0x00000036 0x00000002 assaultcube.__TEXT.__objc_methtype
  0x0000000a compact-unwind   [0x000000010016a6c4-0x000000010016cd50)  r-x  0x0016a6c4 0x0000268c 0x00000000 assaultcube.__TEXT.__unwind_info
  0x0000000b eh-frame         [0x000000010016cd50-0x000000010018bff8)  r-x  0x0016cd50 0x0001f2a8 0x00000000 assaultcube.__TEXT.__eh_frame
  0x00000300 container        [0x000000010018c000-0x00000001001d1000)  rw-  0x0018c000 0x00007000 0x00000000 assaultcube.__DATA
  0x0000000c regular          [0x000000010018c000-0x000000010018c028)  rw-  0x0018c000 0x00000028 0x00000000 assaultcube.__DATA.__program_vars
  0x0000000d data-ptrs        [0x000000010018c028-0x000000010018c038)  rw-  0x0018c028 0x00000010 0x00000006 assaultcube.__DATA.__nl_symbol_ptr
  0x0000000e data-ptrs        [0x000000010018c038-0x000000010018c0d0)  rw-  0x0018c038 0x00000098 0x00000006 assaultcube.__DATA.__got
  0x0000000f data-ptrs        [0x000000010018c0d0-0x000000010018cc10)  rw-  0x0018c0d0 0x00000b40 0x00000007 assaultcube.__DATA.__la_symbol_ptr
  0x00000010 data-ptrs        [0x000000010018cc10-0x000000010018cd68)  rw-  0x0018cc10 0x00000158 0x00000009 assaultcube.__DATA.__mod_init_func
  0x00000011 regular          [0x000000010018cd70-0x000000010018e480)  rw-  0x0018cd70 0x00001710 0x00000000 assaultcube.__DATA.__const
  0x00000012 regular          [0x000000010018e480-0x000000010018e488)  rw-  0x0018e480 0x00000008 0x10000000 assaultcube.__DATA.__objc_nlclslist
  0x00000013 regular          [0x000000010018e488-0x000000010018e498)  rw-  0x0018e488 0x00000010 0x00000000 assaultcube.__DATA.__objc_protolist
  0x00000014 regular          [0x000000010018e498-0x000000010018e4a0)  rw-  0x0018e498 0x00000008 0x00000000 assaultcube.__DATA.__objc_imageinfo
  0x00000015 data-ptrs        [0x000000010018e4a0-0x000000010018e5e0)  rw-  0x0018e4a0 0x00000140 0x00000000 assaultcube.__DATA.__objc_const
  0x00000016 data-cstr-ptr    [0x000000010018e5e0-0x000000010018e708)  rw-  0x0018e5e0 0x00000128 0x10000005 assaultcube.__DATA.__objc_selrefs
  0x00000017 regular          [0x000000010018e708-0x000000010018e718)  rw-  0x0018e708 0x00000010 0x00000000 assaultcube.__DATA.__objc_protorefs
  0x00000018 data-ptrs        [0x000000010018e718-0x000000010018e728)  rw-  0x0018e718 0x00000010 0x10000000 assaultcube.__DATA.__objc_classrefs
  0x00000019 data-ptrs        [0x000000010018e728-0x000000010018e778)  rw-  0x0018e728 0x00000050 0x00000000 assaultcube.__DATA.__objc_data
  0x0000001a data             [0x000000010018e780-0x0000000100192d28)  rw-  0x0018e780 0x000045a8 0x00000000 assaultcube.__DATA.__data
  0x0000001b zero-fill        [0x0000000100192d30-0x00000001001bd142)  rw-  0x00000000 0x00000000 0x00000001 assaultcube.__DATA.__common
  0x0000001c zero-fill        [0x00000001001bd150-0x00000001001d0e71)  rw-  0x00000000 0x00000000 0x00000001 assaultcube.__DATA.__bss
  0x00000400 container        [0x00000001001d1000-0x00000001001d7adc)  r--  0x00193000 0x00006adc 0x00000000 assaultcube.__LINKEDIT
# 搜索刚才的基址0x10200f600,这个地址其实是alsr产生的运行实际地址
# 找到了固定的player的基址为0x1001abf08
# 那么血量的offset就是0x110
(lldb) memory find -e 0x10200f600 0x000000010018c000 0x00000001001d1000
data found at location: 0x1001abf08
0x1001abf08: 00 f6 00 02 01 00 00 00 f0 4d 2f 5d 01 00 00 00  .?......?M/]....
0x1001abf18: 10 00 00 00 04 00 00 00 d0 b8 04 00 d0 b8 04 00  ........и..и..

那么血量的offset就是0x110

4. 查找子弹的偏移量

(lldb) watchpoint set expression -- 0x10200FF68
Watchpoint created: Watchpoint 1: addr = 0x10200ff68 size = 8 state = enabled type = w
    new value: 998

998就是子弹数量
 

# 建立watchpoint观察点
(lldb) watchpoint modify -c '*(int*)0x10200FF68 < 998'
# continue
(lldb) c
Process 40880 resuming

开一枪会小于998,命中观察点

# 开一枪后断点卡住,可以看到子弹变成997
Watchpoint 1 hit:
old value: 998
new value: 997
Process 40880 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = watchpoint 1
    frame #0: 0x0000000100103f71 assaultcube`___lldb_unnamed_symbol2400$$assaultcube + 529
assaultcube`___lldb_unnamed_symbol2400$$assaultcube:
->  0x100103f71 <+529>: movq   0x10(%r13), %rax
    0x100103f75 <+533>: movb   $0x1, %r15b
    0x100103f78 <+536>: cmpq   (%rbx), %rax
    0x100103f7b <+539>: jne    0x10010401a               ; <+698>
Target 0: (assaultcube) stopped.

打印寄存器的列表
 

(lldb) register read
General Purpose Registers:
       rax = 0x000000010200ff68
       rbx = 0x00000001001abf08  # base address
       rcx = 0x000000010200ff90
       rdx = 0x0000000000000000
       rdi = 0x0000000000000001
       rsi = 0x00000000000000dc
       rbp = 0x00007ffeefbffad0
       rsp = 0x00007ffeefbffa60
        r8 = 0x14d2082090214802
        r9 = 0x0000000101900000
       r10 = 0x0000000000000002
       r11 = 0x00000000000000e5
       r12 = 0x00007ffeefbffa88
       r13 = 0x00000001018042b0
       r14 = 0x00000000000bd06c
       r15 = 0x00007ffeefbffa98
       rip = 0x0000000100103f71  assaultcube`___lldb_unnamed_symbol2400$$assaultcube + 529
    rflags = 0x0000000000200202
        cs = 0x000000000000002b
        fs = 0x0000000000000000
        gs = 0x0000000000000000
# 通过$r13 + 0x10计算出来指针0x101304df0,然后找到指向的地址是0x10200f600,这个地址是运行时player的基址
# 下面通过血量来验证一下player的基址
(lldb) p/x 0x0000000101304de0 + 0x10
(long) $4 = 0x0000000101304df0
(lldb) memory read 0x0000000101304df0
0x101304df0: 00 f6 00 02 01 00 00 00 e0 0c 19 00 01 00 00 00  .?......?.......
0x101304e00: 40 f7 00 02 01 00 00 00 68 f7 00 02 01 00 00 00  @?......h?......
# 因此可以知道子弹的偏移地址:
(lldb) p/x 0x10200f768 - 0x10200f600
(long) $7 = 0x0000000000000168

以此类推,找到其他属性需要的偏移量。我之前写的blog中提到的CE(cheat engine)也是一样的。

刚入职新公司,尝试一个新职业:安全开发岗,今年主要开发项目:数据隐写(Steganography),数据脱敏技术,移动端安全SDK,终端检测响应技术(EDR),有经验的朋友可以一起探讨一下。感谢🙏

实在是没时间了。以后继续完善 auto aim 自动瞄准和glowESP 人物区域。

游戏截图:

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值