一、ipa了解
是个压缩包,解压后
二、逆向app思路;
-
界面分析
- Cycript:通过命令行查看界面的组成情况,子控制器的结构,子view的结构,控制器拥有的所有方法、成员变量;
- reveal:看到所有UI控件
-
代码分析
- 对Mach-O文件的静态分析(不运行,只看文本)
- MachOView、class-dump、Hopper Disassembler、ida等
通过代码分析可以大概知道他的代码是怎么写的了,接下来动态调试。
-
动态调试(这样才能知道他的每一行代码真正是干什么的)
- 对运行中的APP进行代码调试
- debugserver、LLDB
-
代码编写
- 注入代码到APP中
- 必要时还可能需要重新签名、打包ipa
三、class-dump
- 顾名思义,它的作用就是把Mach-O文件的class信息给dump出来(把类信息给导出来),它只能生成对应的.h头文件。
- 官方地址:http://stevenygard.com/projects/class-dump/。
- 下载完工具包后将class-dump指令文件复制到Mac的/usr/local/bin目录,这样在终端就能识别class-dump命令了。
tips:Mac终端的原理:
当我们在Mac终端敲指令的时候,它是去/usr/bin
和/usr/local/bin
文件夹下找,那里有非常多的指令,我们敲的指令都是从这个文件夹下找。但是貌似从Mac10.11开始
/usr/bin
目录就算有管理员权限也不能写,所以只能把class-dump放到/usr/local/bin
目录下,放完后,在命令行敲class-dump的命令就有反应了。
四、实战:使用dump-class指令导出ipa的.h头文件信息
1、得到一个ipa文件;
如何得到一个ipa:1、iTunes 12.6之前的版本;2、手机越狱;3、有源码直接用XCode编译打包;4、(可用)Mac端PP助手下载;5、(可用、推荐)Mac安装iMazing,只要是通过iMazing更新或下载的,就可以导出ipa,iMazing还可以从AppStore上添加app。
2、解压ipa,显示app包内容找到Mach-O文件,复制出来。
3、导出头文件内容
3.1 dump Mach-O文件(我尝试了dump那个.app也可以,无需在包内容中找Mach-O文件):
class-dump /Users/kyo/Desktop/腾讯课堂/pmes
所有头文件内容都显示在终端中,不方便看。
3.2 把头文件内容出到文件夹
class-dump -H Mach-O文件路径 -o 头文件存放目录
把『pmes头文件』文件夹拖拽到sublime中,即可如下图查看各个.h文件,command + p 筛选文件名:
《踩坑》 疑问:网易云音乐的app到处的头文件只有一个CDStructures.h,而且里面没什么内容??很奇怪。。。
网络解答:
class-dump不能直接将AppStore上的app的头文件导出来,你只会导出CDStructures.h这个头文件,而这里边基本是没有信息的。相当于Apple在app上加了一层壳(加密了),需要把这层壳砸破。(Dumpdecrypted破壳)
所以,想要直接用class-dump把头文件导出来,必须是未经加密的,比如XCode刚编译打包过的,上面的头文件是别人发给我的一个XCode编译打包好的ipa,并未上传到AppStore。
五、代码的编译过程
六、Hopper01——简单使用
Hopper Disassmbler能够将Mach-O文件的机器语言代码反编译成汇编代码、OC伪代码或者Swift伪代码。
把Mach-O文件拖拽至Hopper Disassembler。(这里的Mach-O是自己的项目用XCode编译好的Mach-O文件,没有上传到AppStore)
利用Hopper可以知道每个文件,每个方法,大概在干什么。
七、Hopper02-UIKit伪代码分析
比如我们想知道,
UIView的一些方法的内部实现,或者UIViewController一些方法的内部实现;或者验证以前的一些想法。
那么UIKit在哪里呢?
寻找一:
显示XCode包内容看看/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/UIKit.framework
Frameworks文件夹下有很多框架,UIKit也在其中,但是UIKit框架中并没有.m文件或者二进制的Mach-O实现文件。
把UIKit.tbd拖拽到sublime中查看:
是在手机中的/System/Library/Frameworks/UIKit.framework/UIKit
位置,连上越狱iPhone,用iFunBox位置。
然而并没有UIKit的Mach-O文件
寻找二:借助Cycript工具
寻找三:
UIKit其实是放在动态库共享缓存中(dyld shared cache)
动态库在手机的这个地方/System/Library/Caches/com.apple.dyId/
,复制到Mac。
就在dyld_shared_cache_arm64中
到此为止,就找到UIKit的Mach-O了。
说说 动态库共享缓存(dyld shared cache)
为什么寻找二的路径中没有呢,因为在Mac\iOS中,是使用了/usr/lib/dyld程序来加载动态库
当我们去链接寻找二的路径的时候,该路径会传给/usr/lib/dyld程序,dyld就会去动态库共享缓存中
,如果没找到就会去其他地方找。
dyld有两种说法:
1 . dynamic link editor,动态链接编辑器
2 . dynamic loader,动态加载器
dyld源码
https://opensource.apple.com/tarballs/dyld/
如何把dyld_shared_cache_arm64分解呢?网上有很多工具,但都不推荐,推荐用苹果官方的,在dyld源码的dsc_extractor.cpp中抽取。
dsc:即dyld shared cache,动态分享库;
extractor:提取、抽取;
dsc_ extractor:动态分享库抽取。
接下来把extractor.cpp编译成可执行文件,再用命令行形式调用里面的功能。
1 . 拷贝extractor.cpp到新建文件夹下,对extractor.cpp稍作处理:将#if 0上面的代码删除(包括#if 0),把最后面的#endif也删掉;(因为if 0 表示永远不会执行)
2 . 进入到extractor.cpp文件夹下,执行clang++ -o dsc_extractor dsc_extractor.cpp
,把launch-cache/dsc_extractor.cpp
编译成可执行文件:参考自己的文章把C文件编译成可执行文件
3 . 如何使用dsc_extractor抽取动态库呢?在dsc_extractor.cpp的main函数中已经告诉我们该怎么使用命令:usage: dsc_extractor <path-to-cache-file> <path-to-device-dir>\n
,因为dsc_extractor不在/local/bin/中,所以可执行文件的路径要写清楚。
dsc_extractor路径 动态库共享缓存文件的路径 用于存放抽取结果的文件夹路径
直接把这三部分拖拽进终端,回车即可。
这就是借助dyld源码dsc_extractor这个工具从共享缓存中抽取出所有的动态库。网上也有其他的工具,但不好使,比如jtool,抽取出来的动态库的文件会比官方工具抽取出来的偏大。
注意,上面抽取的是armv7s,如果是arm64,按上面的方法则不行:
开始看UIKit的实现源码
拖拽到Hopper,选择UIKit:
点下一步,等右下角的working消失后就可以操作了:
分析下loadView这个方法在什么时机调用了:
八、遗留问题:
问题1:
有的同学敲 sh usb.sh
(即tcprelay.py文件),发现Python文件不好使,端口映射不成功,可换成使用itnl
文件
由于itnl文件不是在/usr/local/bin
目录中,所以,要指定itnl的文件路径:
itnl文件路径 --iport 22 --lport 10011
:
iport:i-iPhone,port-端口;
lport:l-local本机Mac,port-端口;
所以,如果在使用Python脚本的时候出现了usb的问题,可以使用这个itnl工具来连接。
问题2:
用Cycript导入某个框架
比如:MJLoadFramework("Photos")