iOS逆向小技能:使用substrate及runtime进行hook(定时检测app是否开启)
前言
利用runtime API进行hook
method_exchangeImplementations
可以直接是一个函数地址,不管是OC还是C
所有的OC函数都是IMP类型。IMP就是个c函数指针。
使用
substrate.h
进行hook定时检测app是否处于前台运行状态
I 利用runtime API进行hook
利用runtime API 进行hook
#import <Foundation/Foundation.h> #import <objc/runtime.h> @interface KNHook : NSObject /** 替换对象方法 @param originalClass 原始类 @param originalSelector 原始类的方法 @param swizzledClass 替换类 @param swizzledSelector 替换类的方法 */ void kn_hookMethod(Class originalClass, SEL originalSelector, Class swizzledClass, SEL swizzledSelector); /** 替换类方法 @param originalClass 原始类 @param originalSelector 原始类的类方法 @param swizzledClass 替换类 @param swizzledSelector 替换类的类方法 */ void kn_hookClassMethod(Class originalClass, SEL originalSelector, Class swizzledClass, SEL swizzledSelector); 复制代码
1.1 替换对象方法
/** 替换对象方法 @param originalClass 原始类 @param originalSelector 原始类的方法 @param swizzledClass 替换类 @param swizzledSelector 替换类的方法 */ void kn_hookMethod(Class originalClass, SEL originalSelector, Class swizzledClass, SEL swizzledSelector){ Method originalMethod = class_getInstanceMethod(originalClass, originalSelector); Method swizzledMethod = class_getInstanceMethod(swizzledClass, swizzledSelector); if(originalMethod && swizzledMethod) { method_exchangeImplementations(originalMethod, swizzledMethod); } } 复制代码
1.2 替换类方法
/** 替换类方法 @param originalClass 原始类 @param originalSelector 原始类的类方法 @param swizzledClass 替换类 @param swizzledSelector 替换类的类方法 */ void kn_hookClassMethod(Class originalClass, SEL originalSelector, Class swizzledClass, SEL swizzledSelector){ Method originalMethod = class_getClassMethod(originalClass, originalSelector); Method swizzledMethod = class_getClassMethod(swizzledClass, swizzledSelector); if(originalMethod && swizzledMethod) { method_exchangeImplementations(originalMethod, swizzledMethod); } } 复制代码
1.3 runtime的使用例子
hook OnSyncBatchAddMsgs
static void __attribute__((constructor)) initialize(void) { MSHookMessageEx(objc_getClass("MessageService"), @selector(OnSyncBatchAddMsgs:isFirstSync:), (IMP)&new_MessageService_OnSyncBatchAddMsgs_isFirstSync, (IMP*)&origin_new_MessageService_OnSyncBatchAddMsgs_isFirstSync); [NSObject hookWeChat]; } 复制代码
hook CUtility
#import "NSObject+WeChatHook.h" @implementation NSObject (WeChatHook) + (void)hookWeChat { kn_hookClassMethod(objc_getClass("CUtility"), @selector(HasWechatInstance), [self class], @selector(hook_HasWechatInstance)); } #pragma mark - hook 方法 /** hook 是否已启动 */ + (BOOL)hook_HasWechatInstance { NSLog(@"kn hook_HasWechatInstance"); return NO; } @end 复制代码
1.4 定时检测app是否开启
应用场景:长期保证app一只处于运行中
NSTimer *timer ; %hook SpringBoard //applicationDidFinishLaunching -(void)applicationDidFinishLaunching: (id)application { %orig; timer = [NSTimer scheduledTimerWithTimeInterval:60*2 target:self selector:@selector(checkHeart) userInfo:nil repeats:YES]; } %new - (void)checkHeart { //定时检测微信是否开启 [[UIApplication sharedApplication] launchApplicationWithIdentifier:@"com.tencent.xin" suspended:0]; } %end //qutolock %hook SBLockScreenViewController -(void)activate{ %orig; [[%c(SBLockScreenManager) sharedInstance] unlockUIFromSource:0 withOptions:nil]; } %end 复制代码
II 使用substrate.h
进行hook
static void (*origin_new_MessageService_OnSyncBatchAddMsgs_isFirstSync)(MessageService*,SEL,NSArray *,BOOL); static void new_MessageService_OnSyncBatchAddMsgs_isFirstSync(MessageService* self,SEL _cmd,NSArray * msgs,BOOL isFirstSync){ origin_new_MessageService_OnSyncBatchAddMsgs_isFirstSync(self,_cmd,msgs,isFirstSync); } 复制代码
see also
更多内容请关注 #小程序:iOS逆向,只为你呈现有价值的信息,专注于移动端技术研究领域;更多服务和咨询请关注#公众号:iOS逆向。
作者:公众号iOS逆向
链接:https://juejin.cn/post/7054422474540187678