iOS逆向工程介绍与实现
## 逆向工程的目的```undefined
1)分析竞品的最新研究或者产品原型(包括所用的技术,所使用的框架)
2)学术/学习目的。
3)破解应用的使用权限
4)识别竞品潜在的侵权行为
```
## 逆向工程的分析工具
进行iOS逆向工程的一个关键就是工具的使用,工欲善其事,必先利其器。
| 工具分类 | 工具名称 |
| :------------- | :-------------------------------: |
| 越狱工具 | 盘古越狱 |
| 查看文件工具 | PP助手, iExplorer, iFunbox, iTool |
| 砸壳工具 | dumpdecrypted, Clutch |
| 查看头文件工具 | class-dump |
| 反汇编工具 | Hopper, IDA Pro |
| 调试器 | Cycript, gdb |
| UI分析工具 | Reveal |
| 网络分析工具 | Charles |
## 第一部分 砸壳查看APP头文件
## 工具
一.`App Store`上的应用都使用了(https://link.jianshu.com/?t=https://en.wikipedia.org/wiki/FairPlay)数字版权加密保护技术。我们要对文件进行反汇编,而IPA都是加密的,哪怎么办呢?所以在逆向之前我们需要先对应用进行砸壳。这里我们使用的是 `dumpdecrypted`。(还可以使用(https://link.jianshu.com/?t=https://github.com/KJCracks/Clutch),这里我们就不讲`Clutch`了)
### dumpdecrypted [代码](https://link.jianshu.com/?t=https://github.com/stefanesser/dumpdecrypted)
```csharp
Dumps decrypted mach-o files from encrypted iPhone applications from memory to disk.
This tool is necessary for security researchers to be able to look under the hood of encryption.
```
二.`class-dump`是用于解析`Mach-O`文件中存储的OC运行时信息的。他能生成类的声明、分类、协议。和otool -ov类似,但是由于`class-dump`的结果是以OC代码展示的,所以有很强的可读性。
### class-dump [代码](https://link.jianshu.com/?t=http://stevenygard.com/projects/class-dump/)
```csharp
This is a command-line utility for examining the Objective-C runtime information stored in Mach-O files.
It generates declarations for the classes, categories and protocols. This is the same information provided by using ‘otool -ov’,
but presented as normal Objective-C declarations, so it is much more compact and readable.
```
三.一台越狱手机
iOS为了保证安全性,所有的应用都是在沙盒中运行。所以要想完成逆向操作,我们需要更高级的权限。没有越狱设备那就无法展开学习和研究工作。
## 步骤
一.安装好 `dumpdecrypted`和 `class-dump` 以后,在越狱机上Cydia上安装 `openSSH`,通过MAC终端控制手机,`openSSH`密码是`alpine`(手机和电脑需要在同一网段,然后点开设置查看当前手机分配的ip地址)
```ruby
Mac-mini-Damon:~ damon$ ssh [email protected]
[email protected]'s password:
iPhone4:~ root#
```
二.在越狱机上`Cydia`上安装 `Cycript`
```csharp
Cycript是一个理解Objective-C语法的javascript解释器,这意味着我们能够在一个命令中用Objective-C或者javascript,
甚至2者兼用。它能够挂钩正在运行的进程,能够在运行时修改应用的很多东西。使用Cycript有如下好处:
1.我们能够挂钩正在运行的进程,并且找出正被使用的类信息,例如view controllers,内部和第3方库,甚至程序的delegate的名称。
2.对于一个特定的类,例如View Controller, App delegate或者任何其他的类,我们能够得到所有被使用的方法名称。
3.我们能够得到所有实例变量的名称和在程序运行的任意时刻实例变量的值。
4.我们能够在运行时修改实例变量的值。
5.我们能够执行Method Swizzling,例如替换一个特定方法的实现。
6.我们可以在运行时调用任意方法,即使这个方法目前并不在应用的实际代码当中。
Mac-mini-Damon:dumpdecrypted-master damon$ cd /Users/damon/Desktop/dumpdecrypted-master
Mac-mini-Damon:dumpdecrypted-master damon$ make
`xcrun --sdk iphoneos --find gcc` -Os-Wimplicit -isysroot `xcrun --sdk iphoneos --show-sdk-path` -F`xcrun --sdk iphoneos --show-sdk-path`/System/Library/Frameworks -F`xcrun --sdk iphoneos --show-sdk-path`/System/Library/PrivateFrameworks -arch armv7 -arch armv7s -arch arm64 -c -o dumpdecrypted.o dumpdecrypted.c
Mac-mini-Damon:dumpdecrypted-master damon$ ls
Makefile dumpdecrypted.c dumpdecrypted.o
README dumpdecrypted.dylib
Mac-mini-Damon:dumpdecrypted-master damon$
```
三.找出要反编译APP的执行文件目录,为了避免干扰,最好杀掉其他进程,只打开反编译APP,使用`ps -e`命令得到路径
```objectivec
iPhone4:~ root# ps -e
PID TTY TIME CMD
1556 ?? 0:00.10 /usr/libexec/afc2d -S -L -d /
1564 ?? 0:03.07 /usr/libexec/deleted --idleExit
1566 ?? 0:00.15 /System/Library/PrivateFrameworks/GeoServices.framework/geod
1568 ?? 0:00.36 /usr/libexec/mobileassetd
1570 ?? 0:00.63 /System/Library/Frameworks/AssetsLibrary.framework/Support/assetsd
1612 ?? 0:00.37 sshd: root@ttys000
1622 ?? 0:06.20 /var/mobile/Applications/B1215D4A-24B7-480F-B91D-8F5386B0211A/QQ.app/QQ
1623 ?? 0:00.10 /System/Library/Frameworks/UIKit.framework/Support/pasteboardd
1613 ttys000 0:00.05 -sh
1628 ttys000 0:00.01 ps -e
iPhone4:~ root#
```
其中的 `/var/mobile/Applications/B1215D4A-24B7-480F-B91D-8F5386B0211A/QQ.app/QQ` 就是我们要找的
四.使用`Cycript`找出反编译APP的Documents目录路径
```objectivec
iPhone4:~ root# cycript -p QQ
cy# [ URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]
#"file:///var/mobile/Applications/B1215D4A-24B7-480F-B91D-8F5386B0211A/Documents/"
cy#
```
其中的 `/var/mobile/Applications/B1215D4A-24B7-480F-B91D-8F5386B0211A/Documents/` 就是我们要找的Documents目录路径
五.将`dumpdecrypted_7.dylib`拷贝到Documents目录下,此处是使用scp方式,也可以使用iFunBox或者PP助手进行文件操作(这里的dumpdecrypted_7.dylib是别人已经生成好的)[地址](https://link.jianshu.com/?t=http://git.oschina.net/hongyangyi/dumpdecrypted)
```ruby
Mac-mini-Damon:~ damon$ scp /Users/damon/Desktop/dumpde/dumpdecrypted_7.dylib [email protected]:/var/mobile/Applications/B1215D4A-24B7-480F-B91D-8F5386B0211A/Documents/
[email protected]'s password:
dumpdecrypted_7.dylib 100% 81KB81.0KB/s 00:00
Mac-mini-Damon:~ damon$
```
六.然后就是使用`dumpdecrypted`砸壳
```csharp
iPhone4:~ root# cd /var/mobile/Applications/B1215D4A-24B7-480F-B91D-8F5386B0211A/Documents/
iPhone4:/var/mobile/Applications/B1215D4A-24B7-480F-B91D-8F5386B0211A/Documents root# DYLD_INSERT_LIBRARIES=dumpdecrypted_7.dylib /var/mobile/Applications/B1215D4A-24B7-480F-B91D-8F5386B0211A/QQ.app/QQ
mach-o decryption dumper
DISCLAIMER: This tool is only meant for security research purposes, not for application crackers.
[+] detected 32bit ARM binary in memory.
[+] offset to cryptid found: @0x4a4c(from 0x4000) = a4c
[+] Found encrypted data at address 00004000 of length 46284800 bytes - type 1.
[+] Opening /private/var/mobile/Applications/B1215D4A-24B7-480F-B91D-8F5386B0211A/QQ.app/QQ for reading.
[+] Reading header
[+] Detecting header type
[+] Executable is a FAT image - searching for right architecture
[+] Correct arch is at offset 16384 in the file
[+] Opening QQ.decrypted for writing.
[+] Copying the not encrypted start of the file
[+] Dumping the decrypted data into the file
[+] Copying the not encrypted remainder of the file
[+] Setting the LC_ENCRYPTION_INFO->cryptid to 0 at offset 4a4c
[+] Closing original file
[+] Closing dump file
iPhone4:~ root# ls
(null)/ CustomFace/ Image/ Other/ QQAppSetting.plistTRctBundle/app.m dumpdecrypted_7.dylibwallet/
AVEngine.log Doc/ LuaPluginDir/QMusicSdk/ QQFlow.ini Theme/ client_wording.jsongiftInfo/ webappCache2/
Audio/ FileRecv/ MQZONEv1/ QQ.decryptedQQHeadThumb/ ThemeInfo/ content/ patchScripts/ wupseq.dat
ConfigStorage/FileTransferTemp/MyFolder/ QQ.ini QZoneImageThumb/ Video/ contents/ tbmg.data
root#
```
其中的 `QQ.decrypted` 就是我们要的破解文件
七.使用`class-dump`将文件解析
将`QQ.decrypted`拷贝到Mac桌面文件夹,使用`class-dump`进行解析
```ruby
Mac-mini-Damon:~ damon$ cd /Users/damon/Desktop/test
Mac-mini-Damon:test damon$ class-dump --arch armv7 QQ.decrypted > QQ.m
Mac-mini-Damon:test damon$
```
得到的QQ.m文件就是我们需要的头文件,`class-dump --arch armv7 QQ.decrypted > QQ.m`,因为我是用的手机是iPhone4做的(没办法,只能用公司不用的4进行越狱),所以使用 armv7,其他型号使用相对应的 `4(armv7),4s(armv7),5(armv7),5s(arm64),6(arm64),6s(arm64)`
### 1)分析从AppStore下载的IPA包
```css
class-dump --arch armv7 QQ.decrypted > QQ.m
```
### 2)分析从越狱平台下载的越狱IPA包
```ruby
class-dump -H MYXJ.app -o /Users/damon/Desktop/test/headMYXJ
```
## 第二部分 分析APP UI
### (https://link.jianshu.com/?t=http://revealapp.com/)简介
```undefined
Reveal能够在运行时调试和修改iOS应用程序。它能连接到应用程序,并允许开发者编辑各种用户界面参数,
这反过来会立即反应在程序的UI上。就像用FireBug调试HTML页面一样,在不需要重写代码、
重新构建和重新部署应用程序的情况下就能够调试和修改iOS用户界面。
```
Reveal查看任意app的高级技巧介绍了如何在越狱设备上查看任意app的技巧:
```bash
1)iOS设备需要越狱,iOS6以上
2)安装Reveal,越狱设备与安装Reveal的Mac在同一wifi内。
3)点击菜单Help / Show Reveal Library in Finder,获取libReveal.dylib
4)将libReveal.dylib上传到设备的/Library/MobileSubstrate/DynamicLibraries
5)编辑并上传一个libReveal.plist,格式和/Library/MobileSubstrate/DynamicLibraries下面的其他plist类似,其中的filter的bundle写要查看的iOS App的bundle Id。
格式如下:
{ Filter = { Bundles = ( "你要查看的app的bundle Id" ); }; }
6)重启iOS设备
```
## 第三部分 反编译
### 一:(https://link.jianshu.com/?t=http://www.hopperapp.com/)简介
```undefined
Hopper是一款运行在Mac、Windows和Linux下的调试(os x only)、反汇编和反编译的交互式工具。
可以对32、64位的MAC程序、Windows程序和IOS程序(arm)进行调试、反编译等。
```
### 功能
```objectivec
1)能够分析出函数的代码块、变量等
2)可以生成代码块的控制流图CFG
3)可以通过Python脚本来调用Hopper的其他一些功能,使用更加灵活
4)在MAC上还可以通过GDP动态调试分析
5)对Objective C的极佳的支持——能够解析出Selector、字符串和发送的消息
6)反编译,生成伪代码
7)分析快速,且占用资源少
```
### 二:(https://link.jianshu.com/?t=https://www.hex-rays.com/products/ida/)简介
IDA Pro是一个非常强大的反汇编和调试工具,支持Windows,Linux, Mac OS X平台
(https://link.jianshu.com/?t=https://book.douban.com/subject/10463039/)
## 第四部分 网络接口分析
### (https://link.jianshu.com/?t=http://www.charlesproxy.com/)简介
```undefined
Charles是Mac下常用的对网络流量进行分析的工具,类似于Windows下的Fiddler。
在开发iOS程序的时候,往往需要调试客户端和服务器的API接口,这个时候就可以用Charles,Charles能够拦截SSL请求、模拟慢速网络、
支持修改网络请求包并多次发送、能够篡改Request和Response等强大的功能。下面介绍安装和使用方法。
```
### 功能
```jsx
1)拦截SSL请求
2)模拟慢速网络
菜单Proxy中的Throttle Setting可以对此进行设置
3)支持修改网络请求包并多次发送
4)断点功能
Charles能够断到发送请求前(篡改Request)和请求后(篡改Response)
5)捕获记录控制 可以过滤出关注的请求。菜单Proxy中的Record Setting可以对此进行设置
```
## 第五部分 使用调试器hook
```undefined
gdb调试命令
已经集成在Xcode中去了用于调试App程序
但是直接在硬件设备上执行时,可以获得更多的功能
可以调试设备上所有的进程
快速分离和重新附着到某个进程上
没有桌面形式的操作系统上进行开发程序时的调试
攻击者可以修改gdb命令的脚本文件,来达到操作设备上任何程序的
运行、修改、监控设备上的所有的程序
```
(https://link.jianshu.com/?t=http://wufawei.com/2013/11/ios-application-security-22/)
(https://link.jianshu.com/?t=http://www.cnblogs.com/jailbreaker/p/4212997.html)
(https://link.jianshu.com/?t=http://xiongzenghuidegithub.github.io/blog/2015/03/24/iosni-xiang-gong-cheng-du-shu-bi-ji/)
## 第六部分 如何防止被反编译
代码混淆的必要性以及方法:
```undefined
1) 使用c语言实现关键的代码逻辑
2)使用宏替换
```
页:
[1]