如果在我们的项目中hook了Method Swizzle,那么别人还能hook我们的项目吗??
//专门HOOK
+(void)load{
//内部用到的交换代码
Method old = class_getInstanceMethod(objc_getClass("ViewController"), @selector(btnClick1:));
Method new = class_getInstanceMethod(self, @selector(click1Hook:));
method_exchangeImplementations(old, new);
//在交换代码之前,把所有的runtime代码写完
//基本防护
struct rebinding bd;
bd.name = "method_exchangeImplementations";
bd.replacement=myExchang;
bd.replaced=(void *)&exchangeP;
struct rebinding rebindings[]={bd};
rebind_symbols(rebindings, 1);
}
//保留原来的交换函数
void (* exchangeP)(Method _Nonnull m1, Method _Nonnull m2);
//新的函数
void myExchang(Method _Nonnull m1, Method _Nonnull m2){
NSLog(@"检测到了hook");
}
-(void)click1Hook:(id)sender{
NSLog(@"原来APP的hook保留");
}
说明: * 在做防护之前,先把自己内部需要runtime交换的代码写完,比如开放btnClick1给自己内部去hook,其他的hook则禁止 * 使用fishhook hook method_exchangeImplementations方法,这样当外部使用method_exchangeImplementations方法时,让它失效
zip -ry Hook.ipa Payload
代码注入参考:iOS逆向之代码注入(framework)
前面在hookMgr中已经做了防护,不能交换btnClick2方法,那么我们写下hook btnClick2的代码来测试一下:
+(void)load
{
Method old = class_getInstanceMethod(objc_getClass("ViewController"), @selector(btnClick2:));
Method new = class_getInstanceMethod(self, @selector(click2Hook:));
method_exchangeImplementations(old, new);
}
-(void)click2Hook:(id)sender{
NSLog(@"btnClick2交换成功");
}
运行,分别点击按钮1,按钮2,发现btnClick2交换成功,防护失败了
NSLog(@"hookMgr--Load");
NSLog(@"ViewController--Load");
+(void)load{
NSLog(@"AppDelegate--Load");
}
zip -ry Hook.ipa Payload
NSLog(@"WJHook---load");
然后运行 修改前
修改后
zip -ry Hook.ipa Payload
* 发现我们的防护hookMgr先执行,并且 检测到了hook
* 至此外部就不能通过hook “Method Swizzle”来交换btnClick2方法
因为在内部是没有办法再进行hook了,所以有些三方库如果用了Method Swizzle,那么你要做的修改就比较多,需要将工程里用到的全部method_exchangeImplementations换成exchangeP
如果用Cydia Substrate或者MonkeyDev来hook,依然能hook成功
* %hook ViewController 表示hook ViewController这个类
* -(void)btnClick2:(id) org 表示hook btnClick2这个方法
Cydia Substrate主要由3部分组成:
* 1.MobileHooker
MobileHooker顾名思义用于HOOK。它定义一系列的宏和函数,底层调用objc的runtime和fishhook来替换系统或者目标应用的函数.
其中有两个函数:
* MSHookMessageEx 主要作用于Objective-C方法
void MSHookMessageEx(Class class, SEL selector, IMP replacement, IMP result)
* MSHookFunction 主要作用于C和C++函数
void MSHookFunction(voidfunction,void* replacement,void** p_original)
2.MobileLoader
MobileLoader用于加载第三方dylib在运行的应用程序中。启动时MobileLoader会根据规则把指定目录的第三方的动态库加载进去,第三方的动态库也就是我们写的破解程序.
3.safe mode
因为APP程序质量参差不齐崩溃再所难免,破解程序本质是dylib,寄生在别人进程里。 系统进程一旦出错,可能导致整个进程崩溃,崩溃后就会造成iOS瘫痪。所以CydiaSubstrate引入了安全模式,在安全模 式下所有基于CydiaSubstratede 的三方dylib都会被禁用,便于查错与修复。
在我们的防护代码中,只防护了method_exchangeImplementations方法,然而method_setImplementation和method_getImplementation并没有做防护,因此猜想Cydia Substrate就是通过这两个方法来hook的。
在基本防护2的工程中,增加对method_setImplementation和method_getImplementation的防护
编译生成基本防护.app,再次打包成Hook.ipa
如图,做到了防护MonkeyDev的hook,在检测到hook,强制退出APP
- 那么,上面的防护真的就无法破解了吗?
答案当然是否定的,提供一个思路:
通过修改MachO文件,在防护动态库之前调用hook的动态库,就能实现hook,因为你是在我hook成功之后才做的防护。- 不过新手一般就破解不了上面的防护了。进攻和防护还需要不断学习!