一、启动IOS上的server和Mac上的client
IOS
debugserver 172.16.4.70:12345 -a ProductName
Mac
zeno@zeno-macbook ~ % lldb
(lldb) process connect connect://172.16.4.75:12345
(lldb)
error: Process 1036 is currently being debugged, kill the process before connecting.
Process 1036 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
Process 2994 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
frame #0: 0x00000001b88672d0 libsystem_kernel.dylib`mach_msg_trap + 8
libsystem_kernel.dylib`mach_msg_trap:
-> 0x1b88672d0 <+8>: ret
libsystem_kernel.dylib`mach_msg_overwrite_trap:
0x1b88672d4 <+0>: mov x16, #-0x20
0x1b88672d8 <+4>: svc #0x80
0x1b88672dc <+8>: ret
Target 0: (ProductName) stopped.
二、计算应用的 page0偏移量大小
(lldb) image list -o -f | grep ProductName
[ 0] 0x0000000000ce0000 /private/var/containers/Bundle/Application/C2FFA931-CA3D-4BE9-BCEC-8CF086F57AF4/ProductName.app/ProductName(0x0000000100ce0000)
(lldb) c
Process 2994 resuming
得到ProductName的page0段落大小是:0x0000000000ce0000
三、使用hopper给要调试函数找到函数地址

四、lldb设置断点
用上面的app偏移量+函数地址,就是函数运行在内存中的地址,注意,加号两边不要有空格,并且数字前面加上0x表示16进制,hopper的地址没有自动加上0x
(lldb) br set -a 0x0000000000ce0000+0x0000000100007d20
Breakpoint 1: where = ProductName`___lldb_unnamed_symbol1$$ProductName + 164, address = 0x0000000100ce7d20
设置完断点以后,例如现在下断点的函数是点击屏幕以后出发的,那么点击屏幕后会停在这个断点处
通过lldb 可以读取寄存器的值
例如输入re read查看寄存器的值
(lldb) re read
General Purpose Registers:
x0 = 0x000000011b276800
x1 = 0x0000000112e2f360 “touchesBegan_TableView:withEvent:”
x2 = 0x0000000280301560
x3 = 0x0000000283202b80
x4 = 0x000000016bbdc5c8
…
因为普通的oc方法会编译成c++方法,例如下面的test1::会改成objc_msgSend,
[vc test1:arg1 :arg2];
objc_msgSend(vc,@selector(test1::),arg1,arg2)
objc_msgSend的参数:
- 参数1是调用的控制器
- 参数2是方法名
- 参数3是test1函数参数1
- 参数4是test1函数参数2
参数1.2.3.4分别存在寄存器x0,x1,x2,x3里
所以在lldb调试方法的时候,寄存器内容如下:
po $x0. //打印是调用的控制器
x/s $x1 //打印方法名
po $x2 //打印参数1
po $x3 //打印参数2..
x0寄存器是调用这个方法的对象
(lldb) re read x0
x0 = 0x000000011b276800
(lldb) po $x0
<BaseMsgContentViewController: 0x11b276800>
x1寄存器是方法名
(lldb) re read x1
x1 = 0x0000000112e2f360 "touchesBegan_TableView:withEvent:"
(lldb) x/s 0x0000000112e2f360
0x112e2f360: "touchesBegan_TableView:withEvent:"
x2 是参数1
(lldb) re read x2
x2 = 0x0000000280301560
(lldb) po $x2
{(
phase: Began tap count: 1 force: 0.133 window: ; layer = > view: > location in window: {237, 189.5} previous location in window: {237, 189.5} location in view: {177, 40.5} previous location in view: {177, 40.5}
)}
x3是参数2
(lldb) re read x3
x3 = 0x0000000283202b80
(lldb) po $x3
timestamp: 465.034 touches: {(
phase: Began tap count: 1 force: 0.133 window: ; layer = > view: > location in window: {237, 189.5} previous location in window: {237, 189.5} location in view: {177, 40.5} previous location in view: {177, 40.5}
)}
通过lr寄存器查看调用函数的地址
(lldb) re read lr
lr = 0x000000011e12e3b0 tweek_wechat.dylib`___lldb_unnamed_symbol381$$tweek_wechat.dylib + 104
通过bt指令查看函数调用栈
下面frame #1刚好就是上面 lr的地址,就是调用本函数的函数地址
(lldb) bt
* frame #0: 0x00000001076ece18 WeChat`___lldb_unnamed_symbol242619$$WeChat
frame #1: 0x000000011e12e3b0 tweek_wechat.dylib`___lldb_unnamed_symbol381$$tweek_wechat.dylib + 104
frame #2: 0x0000000110590b2c WeChat`___lldb_unnamed_symbol1610700$$WeChat + 244
frame #3: 0x00000001ad369420 UIKitCore`forwardTouchMethod + 316
frame #4: 0x00000001ad3692d0 UIKitCore`-[UIResponder touchesBegan:withEvent:] + 60
frame #5: 0x00000001ad4cd0cc UIKitCore`-[UITableViewCell touchesBegan:withEvent:] + 136
frame #6: 0x00000001ad369420 UIKitCore`forwardTouchMethod + 316
frame #7: 0x00000001ad3692d0 UIKitCore`-[UIResponder touchesBegan:withEvent:] + 60
frame #8: 0x00000001ad369420 UIKitCore`forwardTouchMethod + 316
frame #9: 0x00000001ad3692d0 UIKitCore`-[UIResponder touchesBegan:withEvent:] + 60
frame #10: 0x0000000107acb060 WeChat`___lldb_unnamed_symbol259286$$WeChat + 96
计算函数调用栈里面函数的地址
tweek_wechat.dylib 的函数是自己用tweek里面添加的hook方法的打印函数参数的方法
第1个函数 0x00000001076ece18 地址,就是咱们下断点的函数地址.
第2个函数 0x000000011e12e3b0 不是代码段的函数
第3个函数0x0000000110590b2c 是代码段的函数
frame #10: 0x0000000107acb060 WeChat`___lldb_unnamed_symbol259286$$WeChat + 96
这里计算frame #10的地址
是带偏移量的,减去app偏移量,用计算器算:
0x0000000107acb060-0x0000000004220000=0x1038AB060
在hopper中找到地址对应的函数
快捷键g,把地址输入进去,跳转到汇编指令
也可以点击 上面Navigate->Go To Address or Symbol…

00000001038ab05c bl sub_107bfedbc+21112
00000001038ab060 adrp x8, #0x111753000 ; 0x111753314@PAGE
00000001038ab064 ldrsw x8, [x8, #0x314] ; 0x111753314@PAGEOFF, objc_ivar_offset_BaseMessageCellView_m_bDisableAllOperation

删掉自己写的tweek打印方法可以在bt的时候可以直接查看原始的函数调用栈
app从启动开始就用lldb调试
debugserver -x auto localhost:20001 app包地址