在我们通过将代码重新签名(如果对第三方app重签名不太熟悉的,请参考iOS逆向安全之代码重签名)能够让我们在本地通过Xcode进行代码调试后,我们一般会进行我们想要进行的操作,比如对对方APP包进行动态分析,或者进行篡改.这个时候我们如果要对第三方app进行我们自己的修改,我们就会考虑将代码注入到第三方app中.此时我们就要进行代码注入了.
代码注入:
在iOS中一般通行的注入手段是通过Framework注入或者dylib注入.
Framework注入:
1.添加framework.
首先我们在已经重签名的项目中添加一个我们用于注入的framework.并在该framework中添加我们的注入类.
2.编写注入代码.
在能够确保执行的接口中编写我们需要注入的代码进行自己想要的操作.一般为了保证我们注入的代码能够执行,我们通常是在load方法中编写.该方法会在我们的注入类被加载的时候调起.
3.将framework注入到MachO.
此时进行运行,framework会被我们的Xcode进行打包到App的framework文件夹中,但是依旧不会被加载运行,因为决定一个framework是否被加载,是dyld根据MachO文件load_commands下的LC_load_dylib字段中是否包含这个framework而定.所以我们需要将这个framework注册到第三方app的MachO文件里.
3.1 我们通过yololib(这个工具可以修改MachO文件)进行framework的注入操作.先将yololib放到/user/local/bin路径下.然后解压咱们需要注入的app包.(注意一定要确保app是原始的app包!否则会被每次运行时候的重签名操作给覆盖!)
3.2 在终端中通过命令yololib(空格)MachO文件路径(空格)库路径 来将MachO文件里添加我们的framework.
此时我们就会在MachO中发现LC_LOAD_DYLIB中多出了我们的framework.具体可以自行用MachOView查看.
3.3 重新打包已经更改后的app成ipa包.
4.用新的ipa包进行运行调试,确定是否注入成功.
此时我们就可以用新的ipa包进行重签名并运行查看注入效果了.
跳坑感受:
才开始做注入时候,一直在签名那里报错,最典型的一个坑是签名失效的错误,卡了我几天,错误样式如下:
我曾经一度以为是我在签名时候的Shell脚本写错了,或者是我的证书过期,或者是我用于签名的权限文件没有给app包打上.在一系列的排查,甚至去手动配置项目的framework上面的签名信息(一般是直接勾选签名自动管理automaticlly manage signing).结果还是没用.后来最终才发现,原来是framework在引入到我们的项目时候,它的开发版本是最新的,但是我们的设备版本却一般比较低,一般开发人员只会在target那里设置低开发版本,framework不会在引入的时候自动匹配你的target版本.(实在是郁闷...),这也是导致签名失效的原因.所以我们千万不要忘了将framework在引入的时候手动将其调整到与target保持一致(低于设备的系统版本)
DyLib注入:
1.添加一个Dylib.
1.1修改它的环境属性.
由于dylib是mac环境下的,所以无法用于在iOS环境下,需要修改lib的BaseSDK.将其由macOS改为iOS.
再将其的签名识别修改为iOSDeveloper.
2.为dylib设置依赖
由于dylib是Xcode在早期时候引入的,旧版本的Xcode在将文件打包迁移时需要设置依赖,dylib也是如此.需要我们手动设置依赖,以确保,我们的dylib为打包进app包的framework文件夹中
2.1配置依赖
3.在dylib中编写我们的注入代码.
4.使用yololib将dylib注册进MatchO中.
值得注意的是,dylib直接就是一个文件,并非一个文件夹,所以路径到dylib包为止并不需要再指向它内部的可执行文件中.
下面的步骤跟上面的Framework一致,最终运行查看结果即可.
跳坑感受:
最初在做dylib进行注入时候,总是报image refrence from的错误,dyld在加载时候在路径下找不到我们的dylib,通过查看app路径下的framework中确实这个dylib没有被打包进framework文件夹中.我反复检查了我的步骤似乎没有什么问题,不知道是否是因为我的项目framework和dylib同时都引进去的原因互相影响还是什么关系,说一下我的解决方案:我当时是直接舍弃Xcode打包操作.将文件的引用关系给干掉
这样Xcode就不会将我们的包给打进Framework里,然后在编译路径下,运行编译后的lib和framework给直接拷贝进我们目标App的framework中.
然后我们再重新将这个app打包成ipa,按照正常的编译,yololib进行注入MatchO,直接运行,这样编译器就不会找不到我们的lib以及framework的路径了.
但是这个解决方案有个致命的弊端就是虽然能够解决这个问题,但是每次我们修改了我们的注入库代码,要重新运行的时候又得重新拷贝编译结果,重新打包运行.所以很麻烦,当然逆向的工程本来就坑点重重,不管如何解决,只要能解决就成,哈哈哈.
MonkeyDev工具注入:
其实,最好用的注入方式还是使用MonkeyDev工具.将可以省却从签名,到配置注入前期的所有事情,MokeyDev的安装请参考官方文档:MonkeyDev-WiKi
按照好MonkeyDev后,我们只需要创建一个MonkeyApp就可以了,如果在创建工程时候没有显示图中最后一行的代表MonkeyDev插件没有安装成功.
通过MonkeyDev创建工具进行重签非常简单,只需要在项目工程目录里的TargetApp中放入需要重签的ipa或者app包(当然所有这些ipa包和app包都需要已经砸壳过的)然后直接运行项目就可以了.
MonkeyApp集成了很多Hook的工具类例如常用的fishHook,Cydia substract等.也支持用Logos语法.使用者可以直接用它所提供的已经注入的dylib进行注入.具体使用方法直接参考上面提供的官方文档就可以了.