iOS逆向, 基础工具之LLDB和debugserver

相信大家对LLDB都不陌生, 平时在开发中会多少用到, 没用过也肯定见过~

而debugserver就是服务端, 实际执行LLDB传来的命令, iOS默认没有安装, 设备连接过一次xcode, 并在devices中添加此设备后, debugserver会被安装到iOS的/Developer/usr/bin目录下

因为缺少task_for_pid权限, 通过xocdedebugserver只能调试自己的app

配置debugserver

从iOS拷贝下来debugserver

$scp root@192.168.6.52:/Developer/usr/bin/debugserver ~/CommonFiles/ReverseEngineering 
root@192.168.6.52's password: 

然后帮它减肥

$lipo -thin armv7s debugserver -output ./debugserver

注意armv7s, 换成所使用设备对应的ARM

给debugserver添加task_for_pid权限

创建一个ent.xml文件

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>com.apple.springboard.debugapplications</key>
        <true/>
        <key>get-task-allow</key>
        <true/>
        <key>task_for_pid-allow</key>
        <true/>
        <key>run-unsigned-code</key>
        <true/>
</dict>
</plist>

先安装依赖ldid

$brew install ldid

然后执行

$ ldid -Sent.xml debugserver 
最后把经过处理的debugserver拷贝回iOS
$scp debugserver root@192.168.6.52:/usr/bin/debugserver
root@192.168.6.52's password: 

原版debugserver不可写, 无法覆盖

而且加入到/usr/bin下, 无需输入路径就可以执行

启动debugserver或附加进程

启动命令

debugserver -x backboard IP:port /path/to/executable

启动并附加进程

debugserver IP:port -a "ProcessName"

实例

$debugserver -x backboard *:1234 /Applications/iBooks.app/iBooks     
debugserver-@(#)PROGRAM:debugserver  PROJECT:debugserver-360.0.26.3
 for armv7.
Listening to port 1234 for a connection from *...

手机也会跟随启动相应的APP
附加进程

$debugserver *:1234 -a "SpringBoard"
debugserver-@(#)PROGRAM:debugserver  PROJECT:debugserver-360.0.26.3
 for armv7.
Attaching to process SpringBoard...
Listening to port 1234 for a connection from *..

然后再Mac上客户端连接

$lldb
(lldb) process connect connect://192.168.6.52:1234

耐心等待连接成功即可!

Process 2440 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
    frame #0: 0x1c754900 libsystem_kernel.dylib`mach_msg_trap + 20
libsystem_kernel.dylib`mach_msg_trap:
->  0x1c754900 <+20>: pop    {r4, r5, r6, r8}
    0x1c754904 <+24>: bx     lr

libsystem_kernel.dylib`mach_msg_overwrite_trap:
    0x1c754908 <+0>:  mov    r12, sp
    0x1c75490c <+4>:  push   {r4, r5, r6, r8}
Target 0: (SpringBoard) stopped.
(lldb)  

输入c让程序继续执行

(lldb) c
Process 2440 resuming
利用LLDB断点进行类HOOK的操作

下面简单介绍下ASLR偏移和断点功能, 实现类似HOOK的功能, 其它具体的LLDB功能, 本文不做赘述, 这里主要是介绍工具和如何配置. 以后整理后可能会专门写一篇关于LLDB的文章.
首先进行image list列出所有的image的信息, 这一步主要是确定ASLR偏移了多少

(lldb) image list -o -f
[  0] 0x0002c000 /System/Library/CoreServices/SpringBoard.app/SpringBoard(0x0000000000030000)
[  1] 0x00963000 /Users/wangyu/Library/Developer/Xcode/iOS DeviceSupport/10.3.3 (14G60)/Symbols/usr/lib/dyld
[  2] 0x00888000 /Library/MobileSubstrate/MobileSubstrate.dylib(0x0000000000888000)
[  3] 0x0218c000 /Users/wangyu/Library/Developer/Xcode/iOS DeviceSupport/10.3.3 (14G60)/Symbols/System/Library/PrivateFrameworks/StoreServices.framework/StoreServices

第一个地址就是偏移量, 记住这个地址0x0002c000

然后把对应的执行文件, 我这里就是用的SpringBoard, 在本地拖入IDA进行分析, 分析完成后, 选择一个你感兴趣的函数

-[SBDashBoardViewController noteMenuButtonDown] __text  0019B9F0    0000001E            R   .   .   .   .   T   .

这是home键按下的函数, 其地址在IDA中静态地址显示为0x0019B9F0

我们需要断点 = 静态基地址 + 偏移量

0x1C79F0 = 0x0019B9F0 + 0x0002c000

现在将这个地址加入断点

(lldb) br s -a 0x1C79F0
Breakpoint 1: where = SpringBoard`_mh_execute_header + 1643184, address = 0x001c79f0 address = 0x0019b9f0

之后我们在手机上进行按下home键的操作.

Breakpoint 2: where = SpringBoard`_mh_execute_header + 1643184, address = 0x001c79f0
Process 2440 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
    frame #0: 0x001c79f0 SpringBoard`_mh_execute_header + 1669616
SpringBoard`_mh_execute_header:
->  0x1c79f0 <+1669616>: .long  0x01f8f647                ; unknown opcode
    0x1c79f4 <+1669620>: smulbteq r3, r0, r2
    0x1c79f8 <+1669624>: .long  0xf2434479                ; unknown opcode
    0x1c79fc <+1669628>: vrshr.s64 q10, q7, #0x40
Target 0: (SpringBoard) stopped.
(lldb)  

程序成功的停住了, 现在我们可以跟踪一些基本信息, 甚至动态调试, 输入c让程序继续执行

(lldb) p (char *)$r1
(char *) $0 = 0x005d0ddb "noteMenuButtonDown"
(lldb) c
Process 2440 resuming

详细关于LLDB打印信息, 动态调试, 或者断点前执行脚本的内容, 大家可以自行查阅, 有很多其它资料可供参考.

输入exit, 会提示LLDB会杀了这个进程, 是否愿意, 愿意输入y就退出了.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容