├── .DS_Store ├── README.md ├── classdump.md ├── img ├── .DS_Store ├── reveal │ └── loader.png └── theos │ ├── files.png │ └── nictest.png ├── ipapatch.md ├── oc └── oc-basic.md ├── python.md ├── reveal.md ├── ssh.md └── theos.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartdone/IOS-Reverse-Engineering/3bfbc9ea3949bf5ad01fc46b839e26bb1e7678ff/.DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IOS-Reverse-Engineering 2 | ios逆向工程学习记录 3 | 4 | --- 5 | 6 | ## 逆向工程工具 7 | 8 | - 监测工具 [Reveal(UI监测工具)](/reveal.md) 9 | - 反汇编工具 Hopper,IDA 10 | - 调试工具 lldb 11 | - [class-dump](/classdump.md) 12 | - [Theos](/theos.md) 13 | - ​ 14 | 15 | ## 一些笔记 16 | 17 | - [Ios10.2越狱后ssh连接不上的问题](/ssh.md) 18 | - [ios10.2安装python2.7](/python.md) 19 | - [IPAPatch 使用](/ipapatch.md) 20 | 21 | ## OC基础 22 | 23 | 1. [基础语法](./oc/oc-basic.md) 24 | 2. ​ -------------------------------------------------------------------------------- /classdump.md: -------------------------------------------------------------------------------- 1 | # class-dump 2 | 3 | 下载地址 [http://stevenygard.com/projects/class-dump/](http://stevenygard.com/projects/class-dump/) 4 | 5 | class-dump是用来dump目标对象的class信息的工具,他利用objective-c语言的runtime特性,将存储在Mach-O文件中的头文件信息提取出来,并生成对应的.h文件。 6 | 7 | 下载dmg,然后将里面的class-dump复制出来,更改权限为可执行,并且加到环境变量。 8 | 9 | 导出头文件命令 10 | 11 | ``` 12 | class-dump -S -s -H 可执行文件 -o 输出目录 13 | ``` 14 | 15 | ## Usage 16 | 17 | ``` 18 | class-dump 3.5 (64 bit) 19 | Usage: class-dump [options] 20 | 21 | where options are: 22 | -a show instance variable offsets 23 | -A show implementation addresses 24 | --arch choose a specific architecture from a universal binary (ppc, ppc64, i386, x86_64, armv6, armv7, armv7s, arm64) 25 | -C only display classes matching regular expression 26 | -f find string in method name 27 | -H generate header files in current directory, or directory specified with -o 28 | -I sort classes, categories, and protocols by inheritance (overrides -s) 29 | -o output directory used for -H 30 | -r recursively expand frameworks and fixed VM shared libraries 31 | -s sort classes and categories by name 32 | -S sort methods by name 33 | -t suppress header in output, for testing 34 | --list-arches list the arches in the file, then exit 35 | --sdk-ios specify iOS SDK version (will look in /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk 36 | --sdk-mac specify Mac OS X version (will look in /Developer/SDKs/MacOSX.sdk 37 | --sdk-root specify the full SDK root path (or use --sdk-ios/--sdk-mac for a shortcut) 38 | ``` 39 | 40 | -------------------------------------------------------------------------------- /img/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartdone/IOS-Reverse-Engineering/3bfbc9ea3949bf5ad01fc46b839e26bb1e7678ff/img/.DS_Store -------------------------------------------------------------------------------- /img/reveal/loader.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartdone/IOS-Reverse-Engineering/3bfbc9ea3949bf5ad01fc46b839e26bb1e7678ff/img/reveal/loader.png -------------------------------------------------------------------------------- /img/theos/files.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartdone/IOS-Reverse-Engineering/3bfbc9ea3949bf5ad01fc46b839e26bb1e7678ff/img/theos/files.png -------------------------------------------------------------------------------- /img/theos/nictest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartdone/IOS-Reverse-Engineering/3bfbc9ea3949bf5ad01fc46b839e26bb1e7678ff/img/theos/nictest.png -------------------------------------------------------------------------------- /ipapatch.md: -------------------------------------------------------------------------------- 1 | # [IPAPatch](https://github.com/Naituw/IPAPatch) 2 | 3 | > IPAPatch是一个比较神奇的东西,有点类似于二次打包,他会把你写的patch编译成framework,然后解压原始ipa中的文件替换xcode生成的app里面的内容,并且通过optool将你代码生成的framework和外部的framework注入到二进制文件中,最后对这些二进制文件进行签名然后安装到手机上。 4 | 5 | ## 配置使用 6 | 7 | ### 第一步,下载工程 8 | 9 | 使用git克隆工程`git clone https://github.com/Naituw/IPAPatch.git` 10 | 11 | ### 第二步,准备一个砸了壳的ipa文件 12 | 13 | 载pp助手里面去下载没有课的ipa或者手动去吧ios应用商店下载的ipa的壳给砸开 14 | 15 | ### 第三步,替换掉工程里面的app.ipa文件 16 | 17 | 将上一步砸开壳之后的ipa文件重名名为app.ipa,然后放到I`PAPatch/Assets/app.ipa` 18 | 19 | ### 第四步,放置三方framework(可选) 20 | 21 | 放置三方framework到`IPAPatch/Assets/Frameworks`这里面,放在这里面会被自动链接 22 | 23 | ### 第五步,配置 24 | 25 | 打开 IPAPatch,在 IPAPatch-DummyApp 这个 Target 里,配置好 BundleID 和代码签名。Display Name 会作为前缀添加到原来的 App 上 26 | 27 | ### 第六步,编写你的patch 28 | 29 | 编写的入口在`IPAPatchEntry.m`文件的load方法,你可以在这里改变应用的行为,比如去掉https证书校验什么的,总之可以做你任何想做的时 30 | 31 | ### 第七步,编译运行 32 | 33 | 点击run按钮就可以了 34 | 35 | ### 第一次搞需要注意的问题 36 | 37 | 1. xcode需要登录你的apple id账号 38 | 2. 需要使用砸过壳的app,或者直接在pp助手下载越狱之后的应用 39 | 3. 在signing里面的team要选自己,然后identity里面的bundle identifier也需要修改成别人没有占用的 40 | 41 | -------------------------------------------------------------------------------- /oc/oc-basic.md: -------------------------------------------------------------------------------- 1 | # OC基础语法 2 | 3 | --- 4 | 5 | ```objective-c 6 | #import 7 | 8 | int main(int argc, const char * argv[]) { 9 | @autoreleasepool { 10 | // insert code here... 11 | NSLog(@"Hello, World!"); 12 | } 13 | return 0; 14 | } 15 | ``` 16 | 17 | - OC程序和入口 18 | > C程序的源文件后缀名为.c,OC程序源文件后缀名为.m,m就是message的意识。因为OC是完全兼容C的,所以在OC中入口仍然是mian函数 19 | - `#import`指令 20 | > 这是一个增强的`#include`指令,用户和`#include`指令相同,并且`#import`在包含文件的时候会先判断这个文件是否被包含,如果没有被包含,就包含进来,如果被包含就不会重复包含。 21 | - Foundation框架 22 | 23 | >提供了一些OC最基础的功能,`Foundation.h`这个文件中包含了所有的`Foundation`框架中的头文件,`#import`相当于包含了所有的Foundation框架的头文件 24 | 25 | - `@autoreleasepool` 26 | >他是一个自动释放池,管理内存的 27 | - NSLog函数 28 | 29 | > 是printf函数的增强版,作用也是向控制台输出信息。 30 | > 31 | > 1. NSLog输出完毕信息之后会默认加一个\n,如果我们手动加了一个\n,NSLog的自动换行就会失效。 32 | > 2. 在输出信息的同时还会输出一些与程序有关的其他信息(系统时间、程序名、进程ID、线程ID)。 33 | > 3. NSLog函数支持printf函数的全部格式控制符,其用法也相同。 34 | > 4. NSLog函数的字符串参数前面必须要加一个@符号,这是OC里的字符串格式。 35 | > 5. NSLog可以使用%@格式控制符输出对象,而printf不能输出对象。 36 | > 6. NSLog函数的第一个参数是NSString类型的指针,所以必须给一个OC字符串。 37 | 38 | ## OC中的字符串 39 | 40 | C语言使用字符数组和字符指针的方式来存储字符串,oc中专门设计了一个新的数据类型`NSString`来保存字符串。 41 | 42 | 1. OC字符串签名必须加一个前缀`@`。 43 | 2. OC的字符串常量使用NSString类型的指针变量来保存地址。 44 | 3. NSString类型的变量的指针变量只能保存OC字符串的地址。 45 | 4. 使用`%@`格式控制符输出NSSTring类型的字符串 46 | 47 | 48 | -------------------------------------------------------------------------------- /python.md: -------------------------------------------------------------------------------- 1 | # 安装python 2 | 3 | 1. 在cydia中搜索libffi安装 4 | 2. 下载[http://python.mila432.com/python_2.7.13-1_iphoneos-arm.deb](http://python.mila432.com/python_2.7.13-1_iphoneos-arm.deb)到设备上并且安装 5 | 3. 执行下列命令 6 | 7 | ```shell 8 | dpkg -i python_2.7.13-1_iphoneos-arm.deb 9 | ldid -S /usr/bin/python 10 | ldid -S /usr/lib/libpython2.7.dylib 11 | ldid -S /usr/lib/libssl.1.0.0.dylib 12 | ldid -S /usr/lib/libcrypto.1.0.0.dylib 13 | ``` 14 | 15 | -------------------------------------------------------------------------------- /reveal.md: -------------------------------------------------------------------------------- 1 | # Reveal 2 | 3 | ## 安装 4 | 5 | 在cydia搜索Receal,安装并且重启SpringBoard 6 | 7 | ![reveal loader](./img/reveal/loader.png) 8 | 9 | 导入libReveal.dylib 10 | 11 | 安装完Reveal loader之后,看/Library/RHRevealLoader这个文件夹是否存在,如果存在就不需要做这一步 -------------------------------------------------------------------------------- /ssh.md: -------------------------------------------------------------------------------- 1 | # ios10经过yalu越狱之后无法连接ssh 2 | 3 | 1. ios设备上安装mterminal,运行su,输入密码进入root查看进程dropbear是否存在 4 | ```shell 5 | ps aux | grep dropbear 6 | ``` 7 | 如果进程不存在,执行`/usr/local/bin/dropbear -F -R -p 22` 8 | 9 | 2. 如果进程存在,并且进程是这样的`/usr/local/bin/dropbear -F -R -p 127.0.0.1:22` 10 | 这种就说明只能通过数据线重定向连接ssh,如果想通过wifi可以访问,就通过文件管理修改`/private/var/containers/Bundle/Application/{UUID}/yalu102.app/dropbear.plist`这个文件,把里面的一个参数`127.0.0.1:22`改成`22`即可 11 | 12 | 3. 修复scp 13 | yalu102自带的ssh可能无法使用,原因缺少了scp,首先在cydia里面安装wget,然后执行下面的命令来获取scp 14 | ```shell 15 | wget mila432.com/scp 16 | ldid -S scp 17 | chmod 777 scp 18 | mv scp /usr/bin/scp 19 | killall SpringBoard 20 | ``` 21 | 22 | -------------------------------------------------------------------------------- /theos.md: -------------------------------------------------------------------------------- 1 | # Theos 2 | 3 | --- 4 | 5 | ## 安装Theos 6 | 7 | 1. 安装xcode,如果安装了多个xcode就用`sudo xcode-select -s /Applications/xcode.app/Contents/Developer`来选择默认的xcode 8 | 9 | 2. 下载theos 10 | 11 | 从github上面下载theos,操作如下: 12 | 13 | ```shell 14 | export THEOS=/opt/theos 15 | sudo git clone https://github.com/theos/theos.git 16 | ``` 17 | 18 | 3. 配置ldid 19 | 20 | ldid是专门用来签名ios可执行文件的工具,用以在越狱的ios中取代xcode自带的codesign,从[http://joedj.net/ldid](http://joedj.net/ldid)下载ldid,然后把它放到theos的bin目录下面,并且赋予可执行的权限 21 | 22 | 4. 配置dpkg 23 | 24 | 5. 配置环境变量 25 | 26 | 配置环境变量THEOS,将theos的bin加到PATH环境变量中 27 | ```shell 28 | export THEOS=theos的路径 29 | export PATH=$PATH:$THEOS/bin 30 | ``` 31 | 32 | 6. 测试是否装成功 33 | 34 | 在终端执行`nic.pl`如果出现如下图就表示安装成功了 35 | ![nic.pl](./img/theos/nictest.png) 36 | 37 | ## 创建工程 38 | 39 | 1. `nic.pl` 40 | 2. 输入11选择iPhone/tweak 41 | 3. `Project Name (required):`输入工程名 42 | 4. `Package Name [com.yourcompany.test]:`输入报名 43 | 5. `Author/Maintainer Name[xxxx]:`输入作者名字 44 | 6. `[iphone/tweak] MobileSubstrate Bundle filter [com.apple.springboard]:`输入作用的对象的bundle indentfier 45 | 7. 输入安装完之后需要重启的应用,以进程名称表示 46 | 47 | > 创建完成之后,目录结构如下图。Makefile,Tweak.xm,control,xxx.plist文件 48 | 49 | ![](./img/theos/files.png) 50 | 51 | ### Makefile 52 | 53 | Makefile文件指定工程用到的文件、框架、库等信息,将整个过程自动化,Makefile文件的内容如下: 54 | 55 | ```Makefile 56 | include $(THEOS)/makefiles/common.mk 57 | 58 | TWEAK_NAME = test 59 | test_FILES = Tweak.xm 60 | 61 | include $(THEOS_MAKE_PATH)/tweak.mk 62 | 63 | after-install:: 64 | install.exec "killall -9 SpringBoard" 65 | ``` 66 | 67 | `TWEAK_NAME = test`是tweak的名字,就是用nic.pl创建工程的时候指定的"Project Name",跟control文件中的“Name”对应,不要更改。 68 | 69 | `test_FILES = Tweak.xm`是指tweak包含的源文件"不包括头文件",多个文件用空格分隔 70 | 71 | `include $(THEOS_MAKE_PATH)/tweak.mk`根据不同的theos类型,通过include命令指定不同的mk文件 72 | 73 | `install.exec "killall -9 SpringBoard"`在安装之后杀掉SpringBoard好让cydiaSubstrate加载对应的dylib,和Android类似,我猜可能ios那些应用的进程可能都是SpringBoard给fork出来的,所以把它杀掉,重新打开的应用就会被注入dylib, 74 | 75 | ### Tweak.xm 76 | 77 | tweak.xm是tweak默认生成的源文件。xm中的x代表支持Logos语法,xm代表支持Logos语法和C/C++语法。默认生成的代码如下: 78 | 79 | ```obj 80 | /* How to Hook with Logos 81 | Hooks are written with syntax similar to that of an Objective-C @implementation. 82 | You don't need to #include , it will be done automatically, as will 83 | the generation of a class list and an automatic constructor. 84 | 85 | %hook ClassName 86 | 87 | // Hooking a class method 88 | + (id)sharedInstance { 89 | return %orig; 90 | } 91 | 92 | // Hooking an instance method with an argument. 93 | - (void)messageName:(int)argument { 94 | %log; // Write a message about this call, including its class, name and arguments, to the system log. 95 | 96 | %orig; // Call through to the original function with its original arguments. 97 | %orig(nil); // Call through to the original function with a custom argument. 98 | 99 | // If you use %orig(), you MUST supply all arguments (except for self and _cmd, the automatically generated ones.) 100 | } 101 | 102 | // Hooking an instance method with no arguments. 103 | - (id)noArguments { 104 | %log; 105 | id awesome = %orig; 106 | [awesome doSomethingElse]; 107 | 108 | return awesome; 109 | } 110 | 111 | // Always make sure you clean up after yourself; Not doing so could have grave consequences! 112 | %end 113 | */ 114 | ``` 115 | 116 | - %hook只需要hook的class,必须以%end结尾 117 | - %log指令在%hook内部使用,作用是讲函数的类名,参数等信息写入syslog 118 | - %orig该指令在%hook内部使用,作用是执行hook的函数的原始代码 119 | - %group用于对%hook分组,便于代码管理以及按条件初始化,必须以%end结束,一个%group可以包含多个%hook所有不属于某个自定义的group的%hook会被隐式的归类到%group_ungrouped中 120 | - %new在%hook内部使用,给一个现有的class添加新函数,功能与class_addMethod相同 121 | - %c该指令的作用等同于objc_getClass或者NSClassFromString,即动态获取一个类定义,在%hook或者%ctor中使用 122 | 123 | ### control 124 | 125 | control文件中记录了deb包管理系统所需基本信息,会被打进deb包里面。control文件的内容如下: 126 | 127 | ``` 128 | Package: com.test 129 | Name: test 130 | Depends: mobilesubstrate 131 | Version: 0.0.1 132 | Architecture: iphoneos-arm 133 | Description: An awesome MobileSubstrate tweak! 134 | Maintainer: smartdone 135 | Author: smartdone 136 | Section: Tweaks 137 | ``` 138 | 139 | Package字段用于描述这个deb包的名字,采用的命名方式同bundle identifier类似,均为反向DNS格式,可以按需更改; 140 | 141 | Name字段用于描述这个工程的名字,可以按需更改; 142 | 143 | Depends字段用于描述deb的依赖,依赖是指这个程序运行的基本条件,可以填写固件版本或者其他程序,如果当前ios不满足依赖中定义的条件,则无法正常运行; 144 | 145 | Version字段用来描述这个deb包的版本号,可以按需更改; 146 | 147 | Architecture字段用于描述这个deb包安装的目标设备架构,不要更改哦; 148 | 149 | Description字段用于描述deb包的维护人; 150 | 151 | Author用于描述tweak的作者; 152 | 153 | Section字段用于描述deb包所属的程序类别,不需要更改; 154 | 155 | ### plist 156 | 157 | plist文件的作用和App中的Info.plist文件的作用类似,它记录了一些配置信息,描述的tweak的作用范围。 158 | 159 | ## 编译打包安装 160 | 161 | ### 编译 162 | 163 | theos采用make来编译,运行命令mak,当前目录会多一个obj文件夹,里面有一个dylib文件,这个就是tweak的核心 164 | 165 | ### 打包 166 | 167 | 使用命令`make package`来打包,其实就是先执行`make`命令,然后再执行`dpkg-deb`命令,编译完成之后就会生成一个deb的文件,这个就是最终可以发布的版本 168 | 169 | ### 安装 170 | 171 | 把deb包复制到ios设备上面,然后用ssh连接上设备,使用`dpkg -i xxx.deb`命令来安装,或者就用iFile来安装。 --------------------------------------------------------------------------------