iOS逆向-day8:LLDB 动态调试

一、什么是动态调试?

答:将程序运行起来,通过打断点、打印等方式,查看参数,返回值,函数调用流程等

二、Xcode的动态调试原理
Xcode的动态调试原理
  • 2.1、Xcode的动态调试原理概述
    我们的手机新买回来的时候是没有安装 debugserver 的,它是安装在 Xcode的 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/De viceSupport/9.1/DeveloperDiskImage.dmg/usr/bin/debugserver 目录下的,Mac 电电脑中的Xcode通过 LLDB 调试器给 手机的 debugserver 监听器发送指令,debugserver再给对应的app发送指令,接到指令后再反馈给debugserver,debugserver 再把结果反馈给LLDB,这是一个完整的流程。

    拓展:

    • 1>、当 Xcode 识别到手机设备的时候,Xcode 会自动将 debugserver 安装到 iPhone 上,路径是:/Developer/usr/bin/debugserver
    • 2>、Xcode 调试的局限性:一般情况下,只能调试通过 Xcode 安装的App
  • 2.2、关于 GCC、LLVM、GDB、LLDB的介绍
    • Xcode 编译器的发展历程:GCC -> LLVM
    • Xcode 调试器的发展历程:GDB -> LLDB
三、动态调试任意APP
  • 3.1、debugserver 权限的问题

    • 默认情况下 /Developer/usr/bin/debugserver 缺少一定的权限,而且 /Developer下的文件是只读的,我们无法修改,只能调试通过 Xcode安装的 APP,无法调试其他的APP(比如我们从 APPStore 下载的APP)
    • 如果想要调试其他的APP,我们需要对 debugserver 进行重新签名,签上两个调试相关的权限
      • get-task-allow
      • task_for_pid-allow
  • 3.2、给 debugserver 签上权限
    上面我们已经说了 /Developer/usr/bin/debugserver 下的debugserver是只读权限,我们是无法直接对文件签名的,那么我们就把 debugserver 复制到 Mac 上进行签名,增加其权限


    我是把 debugserver 复制到桌面的文件夹下,导出其权限:ldid -e debugserver > debugserver.entitlements,按照上图修改后,重新回签给 debugserver:ldid -Sdebugserver.entitlements debugserver
    回签后的权限

    将增加好权限的 debugserver 我们放到 /usr/bin 目录下,目的是为了便于找到 debugserver 指令,并增加其可执行的权限

    chmod +x /usr/bin/debugserver
    
    • 提示:关于签名,也可以使用 codesign

    • 查看权限信息

      codesign -d --entitlements - debugserver
      
    • 签名权限

      codesign -f -s - --entitlements debugserver.entitlements debugserver
      
    • 或者简写为

      codesign -fs- --entitlements debugserver.entitlements debugserver
      
  • 3.3、端口映射
    我们之前是把手机的 22 与 Mac电脑的 10010 端口进行了映射,我们现在把手机的 10011 端口和 电脑的10011 端口也映射起来,我们直接修改之前的 usb.sh 文件即可,多端口映射


  • 3.4、让 debugserver 附加到某个 APP 的进程,这样手机端的debugserver配置就完成

    debugserver *:端口号 - a 进程
    
    附加到微信上面,并监听 10011端口

    提示:

    • *:端口号 : 使用 iPhone 的某个端口启动 debugserver 服务(只要不是保留端口号就行)
    • -a 进程:输入 APP 的进程信息(进程ID 或者 进程名称)
  • 3.5、Mac上启动 LLDB,远程链接 iphone 上的 debugserver 服务

    • 1>、启动 LLDB

      lldb
      
    • 2>、连接 debugserver 服务


      连接 debugserver 服务
      process connect connect://手机IP地址:debugserver服务的端口号
      

      比如下面的

      process connect connect://192.168.3.36:10011
      

      提示:连接成功后 APP 是暂停状态的

    • 3>、使用 LLDB 的 c 命令让程序继续执行

      c
      

      接下来就可以使用 LLDB 调试 APP

    • 4>、通过 debugserver启动 app

      debugserver -x auto *:端口号 APP的可执行文件路径
      
四、常用 LLDB 指令 (常用指令)
  • 4.1、LLDB调试器的基本介绍
    LLDB (Low Lever Debug): 默认内置于Xcode中的动态调试工具。标准的 LLDB 提供了一组广泛的命令,旨在与老版本的 GDB 命令兼容。 除了使用标准配置外,还可以很容易地自定义 LLDB 以满足实际需要。

  • 4.2、LLDB指令格式、help

    • 指令的格式是:<command> [<subcommand> [<subcommand>...]] <action> [-options [option�value]] [argument [argument...]]

      • <command>:命令名称
      • [<subcommand> [<subcommand>...]] :子命令
      • <action>:命令操作,用这个命令干什么
      • [-options [option�value]]:命令选项,如平时遇到的 -d、-l、-n 等等
      • [argument [argument...]] :命令参数

      比如给 test 函数设置断点:breakpoint set -n test

      • breakpoint:<command>
      • set:<action>
      • -n:<options>
      • test:<argements>
    • help:查看指令的用法
      比如:help breakpoinhelp breakpoint set

  • 4.3、expression ,动态执行某个代码,又不想让程序暂停掉
    执行一个表达式

    • : 命令选项

    • -- 命令选项结束符,表示所有的命令选项已经设置完毕,如果没有命令选项,-- 可以省略

    • : 需要执行的表达式

    • 如:我们断点之后给当前VC的view增加一个背景色,如下

      expression -- (void)[self.view setBackgroundColor:[UIColor greenColor]] 
      
    • expressionexpression -- 和指令 printpcall 的效果一样
    • expression -O -- 和指令 po 的效果一样,如我们打印 self,可以:expression -O -- self
    • expression可以简写为 ex

    推荐学习博客:使用 LLDB expression 命令调试动态更新 UI

  • 4.4、thread 相关的指令

    • 1>、thread backtrace
      一个 frame 代表一帧,一帧代表一个函数


      • 打印当前线程的堆栈信息
      • thread backtrace 和指令 bt 效果一样
    • 2>、thread return [<expr>]
      让函数直接返回某个值,不再执行断点后面的代码,如果有返回值,我们可以为其增加返回值


      thread return
    • 3>、frame variable
      打印当前栈帧的所有变量,也可以打印单独某一个

    • 4>、thread 的其他指令

      指令 和 Xcode 的对应关系
      • thread continue、continue、c : 程序继续运行
      • thread step-over 、next、n :单步运行,把子函数当做整体一步执行
      • thread step-in、step、s :单步运行,遇到子函数会进入子函数
      • thread step-out、finish :直接执行完当前函数的所有代码,返回到上一个函数
      • thread step-inst-over、nexti、ni
      • thread step-inst、stepi、si
      • si、ni 和 s、n 类似
        • s、n 都是源码级别,就是我们自己写的代码
        • si、ni 是汇编指令级别
      • 提示:thread step-over 和 thread step-in,只 遇到子函数才会有区别,thread step-over 会跳过函数,thread step-in 会进入函数
  • 4.5、breakpoint set 代码断点设置

    • breakpoint set -a 函数地址

    • breakpoint set -n 函数名字,如下函数名字

      breakpoint set -n test
      breakpoint set -n touchesBegan:withEvent:
      // 调用某个类的 touchesBegan:withEvent: 方法
      breakpoint set -n "-[类的名字 touchesBegan:withEvent:]"
      
    • breakpoint set -r 正则表达式,-r 后面我们可以跟一些模糊的函数名字,这样所有包含模糊函数名字的函数都会被打上断点

    • breakpoint set -s 动态库 -n 函数名

    • breakpoint list 列出所有的断点(每个断点都有自己的编号)

    • breakpoint disable 断点编号:禁用断点(空心)

    • breakpoint enable 断点编号:启用断点(实心)

    • breakpoint delete 断点编号:删除断点

    • breakpoint command add 断点编号 :给断点预先设置需要执行的命令,到触发断点时,就会按顺序执行

    • breakpoint command list 断点编号 : 查看某个断点设置的命令

    • breakpoint command delete 断点编号 : 删除某个断点设置的命令

  • 4.6、内存断点,在内存数据发生变化的时候触发

    • watchpoint set variable

      watchpoint set variable self->age
      
    • watchpoint set expression 地址

      watchpoint set expression &(self->_age)
      
    • watchpoint list

    • watchpoint disable 断点编号

    • watchpoint enable 断点编号

    • watchpoint delete 断点编号

    • watchpoint command add 断点编号

    • watchpoint command list 断点编号

    • watchpoint command delete 断点编号

  • 4.7、image lookup 模块查找,image 在底层里面可以认为是模块或者镜像

    • image lookup -t 类型: 查找某个类型的信息

      image lookup -t 类型: 查找某个类型的信息
    • Image lookup -a 地址:根据内存地址查找在模块中的位置


  • image lookup -n 符号或者函数名:查找某个符号或者函数的位置

    • image list 列出加载的模块信息
      • image list -o -f 打印出模块的偏移地址、全路径
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350