lldb+debugserver调试

1.安装和配置 lldb

xcode自带,进入的方式:

➜  ~ /Applications/Xcode.app/Contents/Developer/usr/bin/lldb

(lldb) process connect connect://localhost:1234

2.安装和配置debug server

配置debugserver, 这部分都在OSX中操作

  1. 需要把设备连接xcode, 在Window->Devices中添加此设备, debugserver就会被安装到 /Developer/usr/bin目录下。
  2. 默认的debugserver是不能调试别人的app的,所以需要做一些配置。
  3. 把未经处理的debugserver从iOS拷贝到OSX的 ~/ 目录
  4. 减肥,注意要根据设备来决定用哪个cpu类型,iphone5s以上都是arm64, 5和5c是armv7s
➜  ~ lipo -thin arm64 ~/debugserver -output ~/debugserver
  1. 下载http://iosre.com/ent.xml到~/目录
  2. 给debugserver添加task_for_pid权限
➜  ~ /opt/theos/bin/ldid -Sent.xml debugserver
  1. 把修改后到debugserver拷贝到ios设备的/usr/bin目录,因为这个目录下的文件都可以直接运行。

启动debugserver

1.启动server的监听

ce6Plus:~ root# debugserver -x backboard localhost:1234 /var/mobile/Containers/Bundle/Application/CA27858D-C4E3-4FD8-B1C6-77DAAF1CF601/MomoChat.app/MomoChat

3.iOS内存地址概念

1. lldb 中 image list -o -f 的返回数据意义

[ 0] 0x0000000000008000 /private/var/mobile/Containers/Bundle/Application/CA27858D-C4E3-4FD8-B1C6-77DAAF1CF601/MomoChat.app/MomoChat(0x0000000100008000)

第一列[0]是模块序号。
第二列0x0000000000008000是ASLR偏移量。

这就是我们需要从lldb中找到的关键地址,后面调试的断点地址都是基于这个ASLR偏移量来计算的。

第三列是模块的文件位置,后面的括号是便宜后的地址,不用管

目前只需要知道偏移了0x74000

刚开始调试时的输出:

(lldb) process connect connect://localhost:1234
Process 27894 stopped
* thread #1: tid = 0x1aef82, 0x0000000197950e0c libsystem_kernel.dylib`mach_msg_trap + 8, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
    frame #0: 0x0000000197950e0c libsystem_kernel.dylib`mach_msg_trap + 8
libsystem_kernel.dylib`mach_msg_trap:
->  0x197950e0c <+8>: ret

libsystem_kernel.dylib`mach_msg_overwrite_trap:
    0x197950e10 <+0>: movn   x16, #0x1f
    0x197950e14 <+4>: svc    #0x80
    0x197950e18 <+8>: ret

2.如何打断点

在得到模块便宜量后,在IDA或者Hopper中找到想打断点的方法,找到他们的基地址,
基地址 + lldb拿到的ASLR偏移地址 = 需要打断点的地址

用momo来测试:
找到[MDRegisterBaseViewController enableNextBtn:]: 这个方法的入口地址
偏移前: 00000001009bad58
偏移后 = 0x74000 + 00000001009bad58 = 0x100A2ED58

设置断点:

(lldb) br s -a 0x100A2ED58

成功在输入数据后触发断点

(lldb) br s -a 0x100A2ED58
Breakpoint 2: where = MomoChat`_mh_execute_header + 10179032, address = 0x0000000100a2ed58
Process 27894 stopped
* thread #1: tid = 0x1aef82, 0x0000000100a2ed58 MomoChat`_mh_execute_header + 10202456, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
    frame #0: 0x0000000100a2ed58 MomoChat`_mh_execute_header + 10202456
MomoChat`_mh_execute_header:
->  0x100a2ed58 <+10202456>: stp    x20, x19, [sp, #-32]!
    0x100a2ed5c <+10202460>: stp    x29, x30, [sp, #16]
    0x100a2ed60 <+10202464>: add    x29, sp, #16              ; =16
    0x100a2ed64 <+10202468>: mov    x19, x2

3.如何用快捷的方式直接找到方法调用的内存入口

  • (lldb) po [ClassName _shortMethodDescription]
(lldb) po [MDApiBase _shortMethodDescription]
<MDApiBase: 0x102f61ee0>:
in MDApiBase:
    Class Methods:
        + (void) postRequestWithUrl:(id)arg1 requestIdentifier:(id)arg2 param:(id)arg3 timeout:(unsigned long)arg4 userInfo:(id)arg5 target:(id)arg6 ok:(SEL)arg7 err:(SEL)arg8 fail:(SEL)arg9; (0x101851d1c)
        + (void) addExtraVerifyInfoToParaDictionary:(id)arg1; (0x1000a4c50)
        + (void) dataRequestWithUrl:(id)arg1 requestIdentifier:(id)arg2 param:(id)arg3 data:(id)arg4 timeout:(unsigned long)arg5 userInfo:(id)arg6 target:(id)arg7 ok:(SEL)arg8 err:(SEL)arg9 fail:(SEL)arg10; (0x10185311c)
        + (void) outRequestWithUrl:(id)arg1 requestIdentifier:(id)arg2 requestType:(id)arg3 param:(id)arg4 timeout:(unsigned long)arg5 userInfo:(id)arg6 target:(id)arg7 ok:(SEL)arg8 err:(SEL)arg9 fail:(SEL)arg10; (0x101853700)
        + (void) specialPostRequestWithUrl:(id)arg1 specifyCookie:(id)arg2 requestIdentifier:(id)arg3 param:(id)arg4 timeout:(unsigned long)arg5 userInfo:(id)arg6 target:(id)arg7 ok:(SEL)arg8 err:(SEL)arg9 fail:(SEL)arg10; (0x1018524ac)
        + (void) postRequestWithURLString:(id)arg1 requestType:(unsigned long)arg2 requestIdentifier:(id)arg3 para:(id)arg4 timeOut:(unsigned long)arg5 userInfo:(id)arg6 target:(id)arg7 ok:(SEL)arg8 err:(SEL)arg9 fail:(SEL)arg10; (0x103b0ec58)
        + (void) dataRequestWithUrl:(id)arg1 requestType:(unsigned long)arg2 requestIdentifier:(id)arg3 param:(id)arg4 data:(id)arg5 timeout:(unsigned long)arg6 userInfo:(id)arg7 target:(id)arg8 ok:(SEL)arg9 err:(SEL)arg10 fail:(SEL)arg11; (0x1018536c4)
        + (void) postRequestWithAPIPara:(id)arg1; (0x101853a60)
        + (void) backgroundPostWithUrl:(id)arg1 parameters:(id)arg2 target:(id)arg3 backgroundDelegate:(id)arg4 ok:(SEL)arg5 err:(SEL)arg6 fail:(SEL)arg7; (0x1018527c4)
        + (void) resumeWithTask:(id)arg1 apiParam:(id)arg2; (0x101853f64)
        + (void) realPostWithURLString:(id)arg1 requestType:(unsigned long)arg2 requestIdentifier:(id)arg3 para:(id)arg4 timeOut:(unsigned long)arg5 userInfo:(id)arg6 target:(id)arg7 ok:(SEL)arg8 err:(SEL)arg9 fail:(SEL)arg10 concurrentParseBlock:(^block)arg11; (0x101851dac)
        + (void) dataRequestWithUrl:(id)arg1 requestType:(unsigned long)arg2 requestIdentifier:(id)arg3 param:(id)arg4 data:(id)arg5 timeout:(unsigned long)arg6 userInfo:(id)arg7 target:(id)arg8 ok:(SEL)arg9 err:(SEL)arg10 fail:(SEL)arg11 concurrentParseBlock:(^block)arg12; (0x1018531b8)
        + (void) realBackgroundPostWithDelegate:(id)arg1; (0x101852a08)
        + (void) postRequestWithURLString:(id)arg1 requestType:(unsigned long)arg2 requestIdentifier:(id)arg3 para:(id)arg4 timeOut:(unsigned long)arg5 userInfo:(id)arg6 target:(id)arg7 ok:(SEL)arg8 err:(SEL)arg9 fail:(SEL)arg10 concurrentParseBlock:(^block)arg11; (0x101852244)
(NSObject ...)
  • 找到需要打断点的方法的内存地址,设置断点:
b 0x1018536c4
  • 进入断点后,就可以获取各个寄存器的内容了
po $x0    ; 这种是直接获取

p (char *)$x1    ; 如果是方法调用这个获取??

4.获取stack pointer中的入参

x/10 $sp

5.清除,禁用断点

br dis       ; 禁用所有断点
br dis 6     ; 禁用某个断点
br en        ; 启用所有断点
br en 6      ; 启用某个断点
br del       ; 删除所有断点
br del 8     ; 删除某个断点
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值