如果你目前还做不了巨人,那么就去思考如何优雅的站在巨人肩膀上。
此笔记只是把自己常用的一些操作命令记录,当做为个人逆向手册吧。
一、LLDB常用命令
1. 模块操作:
image list -o -f | grep MiaoPai //显示 MiaoPai Image模块的信息
image lookup -r -n NUWebViewController //查询NUWebViewController类或者方法在哪个模块里面
2. 断点操作:
2.1 基本断点:
br s -a 0xA5446 //在固定地址0xA5446下断,此地址是绝对地址。
br s -a '0x0009a000 + 0xb446' //用ALSR+IDA偏移下断,ALSR的获取需要使用image list
br s -n "[UIAlertView initWithTitle:message:delegate:cancelButtonTitle:otherButtonTitles:]" //符号断点这样也行
br s -n "initWithTitle:message:delegate:cancelButtonTitle:otherButtonTitles:" //对所有含有initWithTitle方法的地方下断点。
br s -n alertControllerWithTitle:message:preferredStyle: //对所有含有alertControllerWithTitle方法的地方下断点。
po (void*)class_getMethodImplementation(NSClassFromString(@"UIAlertView"),NSSelectorFromString(@"initWithTitle:message:delegate:cancelButtonTitle:otherButtonTitles:")) //这个可以先打出[UIAlertView initWithTitle:message:delegate:cancelButtonTitle:otherButtonTitles:]的内存地址,然后使用br s -a addr下断点。
2.2 条件断点:
br s -a 0x03193730 -c '(BOOL)[(NSString *)$x0 isEqualToString:@"winsong"]'
2.2 断点命中行为:
br command add index // 给序号为index的断点增加命中后的行为
2.3 内存读写断点:
watchpoint set expression -w write -- addr //给addr地址处设置内存写入断点
watchpoint set expression -w read -- addr //给addr地址处设置内存读断点
2.4 禁用断点:
br dis index
2.5 删除断点:
br del index
2.6 查看断点:
br list //查看断点列表 原型:breakpoint list
3.寄存器操作:
re w r0 0 //把r0寄存器修改为0
re read //查看所有寄存器的值
4.内存操作(可以用x 命令代替):
4.1 内存读:
mem r -s4 -fx -c16 addr // 查看addr处的内存情况,这里主要解释一下上面这条命令每个-的作用,-s主要是控制显示的是以多少个字节显示,如-s1就是Byte的显示,如-s2就是以Word显示,如-s4就是以Dword显示。-f主要是控制显示的格式其后面有效数值:
mem r -s1 -fY -c0x20 0x38b0fe70
mem r -o/Users/winsong/Desktop/temp.bin -c0x8CA000 -b 0xbffff3c0 //dump指定地址 指定大小的内存以Hex格式dump到文件中
x -ff -c0xAC718 -o/Users/winsong/Desktop/temp.bin $x0--force //dump指定地址 指定大小的内存以浮点数格式dump到文件中
x -b -c0xAC718 -o/Users/winsong/Desktop/temp.bin $x0--force //dump指定地址 指定大小的内存以Hex格式dump到文件中
4.2 内存写:
memory write -s1 -fx 0x144dade11 0x38 //对0x144dade11内存地址写入一个字节为0x38
4.3 关于x命令的拓展
常规格式:
1).打印32位地址:
(lldb) x -fx -c8 -l4 $r0 //-f(格式控制)、-c(总个数控制)、-l(每一行的个数控制)
0x10004005: 0x7400001f 0x74000006 0x0f000006 0x74000067
0x10004015: 0x74000007 0x21000007 0x7400006b 0x74000009
2).打印字符串:
(lldb) x -fY -c0x30 -l0x10 $r0 //-f(格式控制)、-c(总个数控制)、-l(每一行的个数控制)
0x10004005: 1f 00 00 74 06 00 00 74 06 00 00 0f 67 00 00 74 ...t...t....g..t
反斜杠格式“x/
5. 线程操作:
th l //查看线程列表 原型:thread list
6. 通用操作:
continue // 原型:process continue
dis -s 908FF0 -c 50 -b //在指定地址处开始显示汇编代码 显示50行数 和显示Opcode
expr ((long long (*)())0x10258f910) //直接调用内存地址CALL:
po [[[UIWindow keyWindow] rootViewController] _printHierarchy] //针对8.0以上的系统
po [[UIWindow keyWindow] recursiveDescription]
expr (void)[CATransaction flush] //刷新UI
二、iOS调试技巧
1. LLDB+DebugServer远程调试
请参考:http://bbs.iosre.com/t/debugserver-lldb-gdb/65
1). debugserver localhost:1234 -a "SpringBoard" // attach方式调试(iOS端运行)
2). debugserver -x backboard *:1234 /var/mobile/Applications/BFC441A6-3F4B-4F18-BA15-3C5DF7148F40/testapp/test //启动方式调试(iOS端运行)
3).process connect connect://localhost:1234 //lldb连接 (MacOS端运行lldb连接debugserver)
4).process launch --stop-at-entry //
2. 使用USB来SSH:
请参考:http://bbs.iosre.com/t/usb-ssh-ios/193
小技巧
#! /bin/bash
$path/tcprelay.py -t 22:2222 &
$path/tcprelay.py -t 1234:1234 &
3. iOS越狱免登陆SSH
ssh-copy-id -i ~/.ssh/id_rsa.pub root@IP
三、关于chisel的使用记录:
1.pviews //参数:无 功能:在程序断下来的情直接输出当前UI的层次结构
2.presponder //参数:控件地址 功能:递归显示出这个控件之前的Responder
3.fa11y //参数:字符串 功能:通过给定字符串找出对应控件的地址
4.caflush //参数:无 功能:改变了UI的情况下刷新UI缓存
5.flicker //参数:控件地址 功能:快速闪速一下控件方便定位
6.paltrace //参数:View
7.pinternals //参数:控件地址 功能:查看控件详细内部结构
8.pvc //参数:viewController 功能:找出viewController和View的对应关系和地址
9.taplog //参数:无 功能:可以找对应的控件点击事件
10.show/hide、mask/unmask、border/unborder、
11.visualize //参数:控件地址或者图片的内存地址 功能:用mac上的preview显示出
12.binside //参数:地址 功能:下断,针对那种有ASLR的方便使用
四、其他技巧:
5.1 将NSData写到Docments目录:
expr (id)[$x0 writeToFile:(id)[NSString stringWithFormat:@"%@/123.bin",(NSString*)[NSSearchPathForDirectoriesInDomains( 9,1, YES) lastObject]] atomically:YES] //将寄存器X0指针里面buff写到沙盒Document目录下
5.2 对于iOS有弹窗(UIAlertView或者UIAlertController)的代码的快速定位
1).可以直接下个断br s -n initWithTitle:message:delegate:cancelButtonTitle:otherButtonTitles: 然后在App操作断下来之后通过栈回溯定位关键代码
2).或者可以: po (void*)class_getMethodImplementation(NSClassFromString(@"UIAlertView"),NSSelectorFromString(@"initWithTitle:message:delegate:cancelButtonTitle:otherButtonTitles:")); //这就能准确的找出对应类的函数。
5.3 查找按钮的Target点击事件
po [myButton 为按钮的内存地址
{(
)}
(lldb) po [$myButton actionsForTarget:(id)0x7fb58bd2e240 forControlEvent:0]
<__NSArrayM 0x7fb58bd2aa40> _handleTap:)
现在你或许想在它发生的时候加一个断点。在 -[MagicEventListener _handleTap:] 设置一个符号断点就可以了,在 Xcode 和 LLDB 中都可以,然后你就可以点击按钮并停在你所希望的地方了。
5.4 App瘦身和签名
利用lipo命令留下支持armv7s的header
1.lipo -thin armv7s
2.ldid -Sent.xml SrcFile(如果此方法不行就换下面第二种)//注意此处“-S”选项与“ent.xml”之间是没有空格的。
3.codesign -s - --entitlements ent.plist -f
5.5.文件的拷贝:(可以用PP助手代替)
scp -P 2222 root@localhost:/Developer/usr/bin/debugserver ~/debugserver //将手机上的debugserver 拷贝至MAC当前目录(已经端口转换了)
scp SrcFile [email protected]:/Users/zj-dt0094/desktop //将手机上的SrcFile 拷贝至Mac的desktop上(前提是已经ssh上手机了)
scp SrcFile [email protected]:/var/mobile/Downloads //将电脑上的SrcFile 拷贝至手机上
scp -rp /var/mobile/Applications/431430A4-6F89-45ED-BA3E-B257DFD0B99C/MiaoPai.app [email protected]:/Users/zj-dt0094/desktop //拷贝整个目录
5.6.砸壳
进入APP的Document目录后 执行以下命令:DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/mobile/Containers/Bundle/Application/BFED82A3-3238-4F41-B797-C1CB584CBE05/qqlive.app/qqlive
具体见: http://www.jianshu.com/p/a4373b5feca0
5.7.对于swift+OC混编的程序如何快速定位关键代码
1. 第一步还是和之前分析OC程序一样的通过View找到对应的ViewController,
2. 第二步就和之前OC(拿到ViewController之后就去对应的头文件找对应的事件)不一样,这里是到IDA的String Windows里面去找,假设找到的 是:
5.8 lldb 自动带入库
打开终端:(依次输入,什么都没提示,打开xcode项目,有Hook 1(expr --@import UIKit等提示,意味着成功))
touch ~/.lldbinit
echo display @import UIKit >> ~/.lldbinit
echo target stop-hook add -o \"target stop-hook disable\" >> ~/.lldbinit
5.9 App打包成IPA
mkdir Payload
mv test.app Payload
zip -ry test.ipa Payload
6.0 在iDA去除SVC
IDA 二进制byte搜索 “01 10 00 D4” 将其替换为 nop 1F 20 03 D5
六、砸壳技巧:
1、Clutch砸壳
2、dumpdecrypted.dylib
使用dumpdecrypted砸壳,出现killed:9 请参考此处 // https://iosre.com/t/ios-9-3-3-dumpdecrypted-killed-9/4489
3、CrackerXI (cyida插件方便)