iOS逆向小技能:使用substrate及runtime进行hook(定时检测app是否开启)

「这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战」。

前言

  1. 利用runtime API进行hook

method_exchangeImplementations 可以直接是一个函数地址,不管是OC还是C

所有的OC函数都是IMP类型。IMP就是个c函数指针。

  1. 使用substrate.h 进行hook
  2. 定时检测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逆向。

猜你喜欢

转载自juejin.im/post/7054422474540187678