美文网首页
iOS逆向实操笔记8-动态调试lldb+debugserver

iOS逆向实操笔记8-动态调试lldb+debugserver

作者: 水煮杰尼龟 | 来源:发表于2020-12-27 10:20 被阅读0次

      平常我们都是通过Xcode跑项目,加断点,动态调试,但是别人app,我们是没有源码的。
    这一篇就来实操动态调试别人的app,通过lldb+debugserver 来完成动态调试

    debugserver
    • Xcode识别设备后,会将debugserver安装到手机里,所以我们从手机里把debugserver拿出来。
      截屏2020-12-22 下午9.18.36.png
    • 原来的debugserver 权限是不够的,我们需要增加2个权限
    • ldid -e debugserver > debugserver.entitlements 导出默认的权限
    • 打开权限文件,增加2个权限
    task_for_pid-allow  yes
    get-task-allow  yes
    
    截屏2020-12-22 下午9.23.13.png
    • ldid -Sdebugserver.entitlements debugserver 重新签名一下,或者codesign签名也行
    • 签名好的权限的debugserver放到手机的/usr/bin 路径


      截屏2020-12-22 下午9.26.57.png
    • debugserver *:端口号 -a 进程 debugserver附加到某个app进程
    • 我这边通过usb手机10086端口mac的10086端口给映射一下,
      image.png
    • usb.sh内容如下
      image.png
    • 登录上手机之后,将debugserver附加到某个app


      image.png
    • 然后新开一个窗口,mac上进入lldb
      image.png
    • 通过process connect connect://ip地址:端口 连接某个进程
      image.png
    • 上图后面敲一下c,是让app继续运行,连上之后,默认进程是断住的,现在即已经对app进行调试了。

    动态调试还需要掌握的知识

    lldb指令
    breakpoint set -n 函数名   // 设置断点
    breakpoint set -n "-[xxx xxx]",断某个地方的某个方法
    breakpoint set -r xxx  函数名里包含xxx都会打断点
    breakpoint set -s 库名称(xxx.dylib) -n xxxx  断动态库里某个函数
    breakpoint list  打的断点list
    breakpoint disable 断点编号: 禁用断点
    breakpoint enable 断点编号: 启用断点
    breakpoint delete 断点编号: 删除断点
    breakpoint command add 断点编号: 给断点预先设置需要执行的命令,到触发断点时。就会按顺序执行
    breakpoint command list 断点编号: 查看某个断点设置的命令
    breakpoint command delete 断点编号: 删除某个断点设置的命令
    敲DONE 结束command指令设置
    
    help breakpoint //提示帮助
    help breakpoint set  // 进一步提示帮助
    
    expression 表达式
    p 表达式
    bt 打印堆栈 
    thread return  不执行断点后的代码
    frame variable 名称可不加 查看变量值
    thread continue , continue , c  程序继续运行
    thread step-over , next ,n  单步运行,把子函数当作一步
    thread step-in ,step , s  单步运行,有子函数进入子函数
    thread step-out ,finish  执行完当前函数所有代码,回到函数调用的地方
    si , ni和s ,n 类似
    s,n是源码级
    si,ni是汇编指令级
    
    /// 内存断点
    watchpoint set variable 变量(self->_age) 
    watchpoint set expression 地址
    watchpoint list 
    disable,enable等 同breakpoint 指令
    
    
    ##image lookup   (image:模块(动态库等等))
    image lookup -t 类型  // 查看某个类型的信息
    image lookup -a 地址  //根据内存地址查找在模块中的位置
    image lookup -n 符号或函数名 //查找某个符号或函数的位置
    image list  列出所加载的模块信息
    image list -o -f 
    
    正式的app通过方法打断点不行,需要使用地址打断点
    
    detach 退出debugserver
    
    Mach-O相关
    size -l -m -x xxxx 查看mach-o 内存分布
    
    ASLR 让mach-o载入内存时内存开始位置 发生变化,ASLR 随机产生偏移
    
    image list -o -f 打印模块 ,查看真实内存开始地址
    breakpoint set -a hopper上地址+偏移
    
    _PAGEZERO
    arm64 0x100000000
    非arm64 0x4000
    
    代码段开始位置 = ASLR offset + _PAGEZERO
    函数的内存地址(VM Address) = ASLR Offset + _PAGEZERO Size + File Offset
    hopper,ida中的地址都是未使用ASLR的 VM Address
    
    上面只是列出了一些常用的,实操过程会用到,可以自己去网上学习,包括一些简单的汇编知识,寄存器也需要了解一点。

    调试实践

    比如上一篇我们把pp虾 我的界面头部的banner 去掉了,是把cellHeightWithBanner:方法hook了,return 0。那么我们动态调试来看看这个参数是什么东西。

    • 将可执行文件拖入hopper中,搜索cellHeightWithBanner,找到它的地址
      截屏2020-12-22 下午10.01.27.png
    • image list -o -f | grep Super,找到地址偏移。
      image.png
    • breakpoint set -a hopper里的方法地址+地址偏移, 即在指定方法设置了断点
      image.png
    • 这时候来到我的界面,发现app进断点了。


      image.png
    • register read 查看一下寄存器的信息。
      image.png
    • 这里需要了解一些这方面的知识。
    • 方法的参数 放在x0-x7, 根据调用方法实质是objc_msgSend(xx,@selector,x) ,那么x2或其后才是参数,我们po一下看看
      image.png
    • 可以看出消息的接收者是BDSUserHomeBannerCell, 参数是BDSBannerEntity
    • 这样我们就可以去class-dump导出的头文件里具体看看BDSBannerEntity
      image.png
    • 那么我们换一种方式,hook 这个ModelinitWithModel 方法,也可以去除banner
      image.png
      image.png
    当然这里只是简单举个例子,来实践动态调试。学会动态调试,也会方便很多了。

    具体怎么调试,还是要看自己了,多了解一些lldb指令,也可以通过断点调试,查到的地址,去hopper里看是干了什么,调用了什么方法。

    • debugserver从0启动一个app(可以一步步看app从0开始做了什么)
    首先知道app可执行文件位置,可以通过MJ的工具,也可以`ps -A
    `debugserver -x auto *:10086 app可执行文件位置(app包中)
    然后mac `lldb` 连接debugserver ,调试
    

    end

    相关文章

      网友评论

          本文标题:iOS逆向实操笔记8-动态调试lldb+debugserver

          本文链接:https://www.haomeiwen.com/subject/ejhenktx.html