教你如何动态调试 iOS App(反编译App)

教你如何动态调试 iOS App(反编译App)开篇

通过本文你能了解 iOS 逆向的基本知识,对 iOS App 的安全有一定了解。然后能举一反三,在⾃自家 App 找到危险漏洞加以预防,保证⽤户数据安全。 

在安全领域,攻与防永远存在。哪怕是 iPhone 有着强大的安全防护机制,也挡不住那些极客们一次⼜一次的好奇,开发了很多强⼤且便利的⼯工具。本文就是在这些极客们提供的工具的基础上完成的!

准备工具

Mac 电脑和越狱 iPhone ⼿机 

查看手机系统目录工具: iFunbox 或 iTools

网络分析工具:Charles

反编译⼯具:Hopper, IDA Pro

查看头文件工具:class-dump

砸壳工具:dumpdecrypted, Clutch

调试器器:lldb 或 gdb

调试工具:Cycript

HTTP(S) 抓包

HTTP 抓包

第一步:获取 MAC IP

按下Option键,同时点击 Mac 菜单栏上的⽆无线⽹网 Icon,能看到当前电脑的 IP 地址。 或在终端输入 ifconfig en0 也可查看。

第⼆步:设置代理

保证⼿机和电脑在同一 WIFI 下,在手机上,点击“设置->⽆无线局域⽹网->连接的WiFi”,设置HTTP代理理: 

服务器器:为 Mac 电脑 IP 地址(如192.168.1.122)

端口:8888

第三步:抓包

在电脑端,打开 Charles。使⼿机发⽣生⽹网络请求,Charles 会弹出一个询问的对话框

点击“Allow”允许,Charles 会出现手机的 HTTP 请求记录列表。

HTTPS 抓包

第一步: 获取证书安装地址

安装 SSL 证书到⼿机设备。点击 Help -> SSL Proxying -> Install Charles Root Certificate on a Mobile Device

出现弹窗得到地址 chls.pro/ssl

第二步:iPhone 安装证书

在⼿机 Safari 浏览器输⼊地址 chls.pro/ssl,出现证书安装页面,点击安装,⼿机设置有密码的输入密码进行安装

第三步:配置代理理 host

Charles 设置 Proxy。选择 Proxy -> SSL Proxying Settings...

勾选 Enable SSL Proxying,点击 Add

Host 设置要抓取的 HTTPS 接⼝,Port 填写 443。

让手机重新发送 

HTTPS 请求,可看到抓包。

注意:不抓包请关闭手机 HTTP 代理理,否则断开与电脑连接后会连不上网!

拿到 .h 头文件

从 AppStore 直接下载的 ipa, 苹果公司对其做了 FairPlay DRM 技术进⾏行行加密保护,⽆法直接使⽤ class-dump 工具获取头文件。但是如果是通过 development 打包出来的话的 App 的话,是可以直接使用 class-dump 查看所有头⽂件的,此部分介绍就是通过此情况来说明如何获取 .h ⽂件的。 此处不再介绍 class-dump 工具的安装过程,具体步骤请直接百度。

进⼊到 appName.ipa 所在⽬录,修改扩展名为 .zip,然后解压文件,得到 appName.app。

然后执行:

class-dump -H appName.app -o ./headers/

命令执行完成后,会在当前⽬录下的 headers 目录⾥里里看到 app 所有头⽂件。 如果添加参数 -A -S 会在头文件⾥里里标记处类⽅法和属性的 IMP 地址(模块偏移前基地址)。

class-dump -H -A -S appName.app -o ./headers/

SSH 访问手机⽂件⽬录

在你的越狱手机上使用 Cydia 应用市场安装 OpenSSH,并保证 Mac 和 iPhone 处于同⼀个WIFI下,在 MAC 终端输入:ssh root@IP ,IP 替换为 iPhone 的 IP 地址

输⼊默认密码:alpine即可进⼊ iPhone 终端。

使用 Clutch 反编译 App

第一步:重新签名 debugserver

取得 debugserver 有两种⽅式。

第一种是在 Mac 电脑中拿到

进入路路径 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/8.3/DeveloperDiskImage.dmg (其中路路径⾥里里8.3,代表 iOS 系统版本,需与准备的越狱⼿机系统版本保持一致)。双击 DeveloperDiskImage.dmg,将目录里的 usr/bin/debugserver 复制到指定文件夹中。

第二种是在越狱手机里拿到

如果手机连接过手机并通过 XCode 调试过 app,会在⼿机⾥里里的 /Developer/usr/bin/ 目录下⽣生成一个 debugserver 文件。通过 iFunbox 导出⾄至 Mac 桌面。或使⽤ scp 命令 cpoy 出 来。

第二步:重签名 debugserver

即给 debugserver 添加 task_for_pid 权限 创建 entitlements.plist,添加如下四个 key:

com.apple.springboard.debugapplications 

get-task-allow

task_for_pid-allow

run-unsigned-code

key 对应的 value 都设为设为 ture

将 entitlements.plist 和 debugserver 放在同⼀个目录下,执⾏行行以下命令:

codesign -s - --entitlements entitlements.plist -f debugserver

此命令会重新签名 debugserver,将签名后的 debugserver 拷⻉⾄手机系统的 /usr/bin/ 目录下。注意:不要将 debugserver 拷贝至 /Developer/usr/bin/ 路径下

第三步: 通过 Clutch 拿到反编译后的 App 可执行文件

将下载好的 Clutch 放⼊手机的 /usr/bin/ 路径下。然后,给 Clutch 赋予权限,通过 SSH 登录到手机,进⼊ /usr/bin/ 执行 chmod a+x ./Clutch 。 通过命令 Clutch -i ,列出所有的可被 Clutch 的应用。

对指定序号的应用进行脱壳,如企业微信,序号是1,命令是 Clutch -d 1 。执行完成后,会得到脱壳后的 ipa。

第四步:使用 class-dump 拿到 .h 头文件

使用上文 【拿到.h头⽂件】 介绍的方法拿到脱壳后的 App 头文件和并记下要打断点的方法的 IMP 地址。

动态调试 App

本⽂动态调试⽤到的调试器器是 lldb。

第⼀步:使 iPhone 进⼊等待挂载状态

SSH 登录到手机,执行 ps -e 命令得到 App PID 或项目名称。

进入 /usr/bin/ 执行 ./debugserver IP:port -a PID|appProjectName 。 其中第一个参数 IP 可以替换为 Mac 电脑 IP地址,或者使用 * 通配符,允许所有 IP 调试;第二个 参数 port 随便写一个就行。第四个参数 可以指定要调试 App 的 PID 或项目名称。⽐如要调试的 PID 为 6019 的搜狗输⼊法项目名称为SogouInput,则命令即为:

./debugserver *:1234 -a 6019 或 ./debugserver *:1234 -a ‘SogouInput’

此命令执行完成后,app会进⼊等到挂载状态,app会被卡住点击无反应。正常现象!

如果此命令报错,如出现 Segmentation fault: 11 等情况,说明 App 做了反动态调试保护。遇到此种情况,需先确定 App 采⽤了哪种保护⽅案,然后进一步找到对应措施,干掉它的反动态调试保护。

第二步:监听进程,进⼊挂载状态

重新打开一个 Mac 终端执行 lldb 进入 lldb 调试状态。然后输⼊

process connect connect://iPhoneIP:port

iPhoneIP 替换为 iPhone 的 IP 地址;port 改为刚才指定的端口,即 1234。 待命令执行完成后,App 即进⼊挂载状态。

第三步:获取 App 的 ASLR 偏​​移量

ASLR偏移量其实就是虚拟内存的地址相对于模块基地址的偏移量。有两个概念需要熟悉一下:

模块在内存中的起始地址 ---- 模块基地址

ASLR偏移 ---- 虚拟内存起始地址与模块基地址的偏移量

在 lldb 调试器器模式下,执⾏行行 imge list -o -f

模块偏移后的基地址 = ASLR 偏移量 + 模块偏移前基地址(⽅法的 IMP 地址)

上⾯面这个公式是尤为重要的,因为 Class-dump 中显示的都是“模块偏移前基地址”,⽽而 lldb 要操作的都是“模块偏移后的基地址”。所以从 Class-dump 到 lldb 要做一个地址偏移量的转换。

⾄此,已得到了App 的 ASLR 偏移量和⽅法的 IMP 地址。

第四步:打断点,调试

在 lldb 模式下执⾏行行, br s -a 'ASLR 偏移量+ IMP' ,然后执⾏行行 c ,使 App 跑起来,触发一个⽅法调用,就会进入断点模式。输入 po $arg1 打印第⼀个参数。 然后,配合着抓包工具 Charles(⽐比如分析网络请求加密逻辑) 和 Class-dump(⽐比如修改某个类的方法返回值)等⼯具,你就可以随意动态调试 App 了,就像在 XCode ⾥里里调试一样!

 br 命令说明

br dis 1 -- 禁⽤(disable)编号为1的断点

 br en 1 -- 启用(enable)编号为1的断点

 br dis -- 禁用所有断点

br en -- 启用所有断点

br del 1 -- 删除(delete)编号为1的断点 

br del -- 删除所有断点

br list -- 列出所有断点

使用 dumpdecrypted 破壳 App

dumpdecrypted 脱壳工具的原理理是:将应用程序运行起来(iOS 系统会先解密程序再启动),然后将内存中的解密结果 dump 写⼊入文件中,得到一个新的可执行程序。

第一步:⽣生成 .dylib 文件

在终端进⼊到下载后的目录中, cd dumpdecrypted-master ,然后执行 make ,即可生成 dumpdecrypted.dylib

第⼆步:找到 App 的 Documents 文件夹路路径

通过 SSH 登录到 iPhone,然后执行 ps -e 查看进程,获取要破壳的进程 PID。然后执行 cycript -p PID 附加到 PID 进程上。最后执

[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask][0] 得到 Documents 文件夹路路径。

 第三步:开始破壳

将第一步生成的 dumpdecrypted.dylib 拷⻉贝到第二步得到的 .../Documents/ 路路径下,命令如下:

scp ~/dumpdecrypted.dylib root@IP:/var/mobile/Containers/Data/Application/2B4C6281-C015-4FF3-A8EC-5E5C7554D447/Documents (将路径⾥里里的UDID 替换为你的要破壳的 App 的 UDID)

进⼊入 Documents 目录下,执⾏

 DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/mobile/Containers/Bundle/ Application/BFED82A3-3238-4F41-B797-C1CB584CBE05/appProjectNa (路径里的 UDID 替换为你的要破壳的 App 的 UDID;将 appProjectName 替换为要破壳 App 的项⽬名称)

待命令执行完,会在当前目录⽣生成⼀一个名为 appProject.decrypted 的文件,这个就是破壳后的 App 可执⾏文件,要的就是它!使用 Class-dump 即可得到头文件。或使⽤ Hopper 或 IDA Pro 进⾏反编译。

给你的 App 添加反动态调试机制

 ptrace

为了⽅便便应用软件的开发和调试,从Unix的早期版本开始就提供了一种对运行中的进程进行跟踪和控制的手段,那就是系统调用 ptrace()。 通过 ptrace 可以对另⼀个进程实现调试跟 踪,同时 ptrace 还提供了一个⾮常有⽤的参数那就是 PTDENYATTACH,这个参数用来告诉系统,阻止调试器器依附。

所以最常用的反调试方案就是通过调用ptrace来实现反调试。 

sysctl

当⼀个进程被调试的时候,该进程会有一个标记来标记⾃己正在被调试,所以可以通过 sysctl 去查看当前进程的信息,看有没有这个标记位即可检查当前调试状态。 检测到调试器就退出,或者制造崩溃,或者隐藏工程,当然也可以定时去查看有没有这个标记。

syscall

为从实现从用户态切换到内核态,系统提供了一个系统调⽤函数 syscall,上⾯面讲到的 ptrace 也是通过系统调用去实现的。 在Kernel Syscalls27 这⾥里里可以找到 ptrace 对应的编号。

26. ptrace 801e812c T

所以如下的调⽤等同于调用 ptrace:syscall(26,31,0,0,0);

arm

syscall 是通过软中断来实现从用户态到内核态,也可以通过汇编 svc 调用来实现。 

觉得不错的话,欢迎关注我的公众号哦!



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

推荐阅读更多精彩内容

  • 前言 本文是自己对iOS逆向工程领域所学的一个总结,文中所用的例子仅为学习研究使用。 1. 逆向工程是什么? 从i...
    JimmyCJJ阅读 5,446评论 3 14
  • 教你如何反编译app,拿到加密方式 大家知道app 有安卓和ios 安卓是apk 现在基本上apk都是经过加密的 ...
    叫我老村长阅读 3,581评论 0 10
  • layout: wikititle: iOS逆向分析笔记categories: Reverse_Engineeri...
    超哥__阅读 10,741评论 3 16
  • 应用场景 在了解iOS逆向工程之前,我们有必要了解它究竟能做什么,在开发中能够获得哪些帮助?个人觉得有以下四点 促...
    郡王丶千夜阅读 649评论 0 1
  • 为了表示我对简书『饱醉豚』事件的不满,简书不再更新,后续有文章只更新 个人博客和 掘金 欢迎移步 个人博客或者 掘...
    eagleyz阅读 7,227评论 0 4