相信大家对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就退出了.