iOS逆:substrateおよびruntimeを使用したhook

17321 ワード

新しいブログアドレス
@[toc]
前言
I 、hookMethod、ClassMethod
runtimeを利用する.h hookを行う

#import 
#import 

@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使用例
  • 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
    Ⅱ、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);
    }
    III、Wechatノート
    3.1 CMessageWrapはメッセージデータのカプセル化である.
        CMessageWrap *myMsg = [[NSClassFromString(@"CMessageWrap") alloc] initWithMsgType:3 nsFromUsr:toUser];
    
  • 送信対象の微信ID
  • を設定する.
            reWrap.m_nsToUsr = other_wxId;
    
    3.2自分でメッセージを送る
    - (void)checkHeartMsg
    {
      NSLog(@"checkHeartMsg        ");
     // CMessageWrap *myMsg = [[NSClassFromString(@"CMessageWrap") alloc] initWithMsgType:3 nsFromUsr:""];//nsFromUsr       
     // reWrap.m_nsToUsr =  "";//       
    // [self sendMsg:@"hi" toContactUsrName:@"ruiriimama"];
      // id userName = @"ruiriimama";
      // int y = (arc4random() % 501) + 500;
       id msg =  [NSString stringWithFormat:@"hi%.4d", arc4random()%100];
       CMessageWrap *wrap = [[%c(CMessageWrap) alloc] initWithMsgType:1];
        id usrName = [%c(SettingUtil) getLocalUsrName:0];
          id userName = usrName;
         NSLog(@"usrName%@",usrName);
        [wrap setM_nsFromUsr:usrName];
        [wrap setM_nsContent:msg];
        [wrap setM_nsToUsr:userName];
        // MMNewSessionMgr *sessionMgr = [[%c(MMServiceCenter) defaultCenter] getService:%c(MMNewSessionMgr)];
        // [wrap setM_uiCreateTime:[sessionMgr GenSendMsgTime]];
        [wrap setM_uiStatus:YES];
    
        CMessageMgr *chatMgr = [[%c(MMServiceCenter) defaultCenter] getService:%c(CMessageMgr)];
        [chatMgr AddMsg:userName MsgWrap:wrap];
    
    }
    3.3現在時刻の取得方法
    
        reWrap.m_uiCreateTime = [objc_getClass("CUtility") genCurrentTime];
    
     MMNewSessionMgr *sessionMgr = [[%c(MMServiceCenter) defaultCenter] getService:%c(MMNewSessionMgr)];
        [wrap setM_uiCreateTime:[sessionMgr GenSendMsgTime]];
    3.4自分のマイクロ信号を取得する方法
        reWrap.m_nsFromUsr = [objc_getClass("SettingUtil") getLocalUsrName:0];
    
    
    自分の微信のニックネームを取得する方法
        id usrName = [%c(SettingUtil) getLocalUsrName:0];
    
    3.5微信名刺の送付
  • 名刺
  • を送る
    //    
    %new
    -(void)sendCardMessage:(NSString *)toUser toContact:(CContact *)toContact{
    
        NSLog(@"      toUser:%@ toContact:%@",toUser,toContact);
    
        id mgrCard = [[NSClassFromString(@"MMServiceCenter") defaultCenter] getService:NSClassFromString(@"CMessageMgr")];
        id msgCard = [[NSClassFromString(@"CMessageWrap") alloc] initWithMsgType:0x2a];
    
        [msgCard setM_nsToUsr:toUser];
        [msgCard setM_nsFromUsr:[m_nCSetting m_nsUsrName]];
        [msgCard setM_nsContent:[toContact xmlForMessageWrapContent]];
        MMNewSessionMgr *sessionMgr = [[%c(MMServiceCenter) defaultCenter] getService:%c(MMNewSessionMgr)];
        [msgCard setM_uiCreateTime:[sessionMgr GenSendMsgTime]];
        // [msgCard setM_uiCreateTime:(int)time(NULL)];
    
        [mgrCard AddMsg:toUser MsgWrap:msgCard];
    }
  • 通信録
  • をロードする
    else if ([[wrap m_nsContent] hasPrefix:@"$xlllll,"]){
    
                  //        
                    FTSContactMgr *ftsContactMgr = [[[NSClassFromString(@"MMServiceCenter") defaultCenter] getService:NSClassFromString(@"FTSFacade")] ftsContactMgr];
    
    
                    NSMutableDictionary *dicContact = [ftsContactMgr getContactDictionary];
    
                    NSArray *arr =  [[wrap m_nsContent] componentsSeparatedByString:@","];
                    if (arr.count<=2) {
                        return;
                    }
    
    
                    NSString *wxid = arr[2];//      
    
    
    
                    NSLog(@"sendCardMessage wxid %@",wxid);
    
                    NSString *toUser = arr[1];//        
                    NSLog(@"sendCardMessage toUser %@",toUser);
                    CContact *oneContact = [dicContact objectForKey:wxid];
    
                    [self sendCardMessage:toUser toContact:oneContact];
    
    
    
    
    
    
    
    
                }
    
    
    3.6友人管理に関する機能
  • 判定入群方式
  • 
    - (void)AsyncOnPreAddMsg:(id)arg1 MsgWrap:(CMessageWrap *)arg2 {
    %orig;
    
        NSLog((@"


    %s "),__FUNCTION__); NSLog(@"
    %@
    %@
    %@
    %lld
    ID %@
    %@
    end", arg2.m_nsFromUsr,arg2.m_nsRealChatUsr,arg2.m_nsContent,(long long)arg2.m_uiMessageType,arg2.m_nsRealChatUsr,arg2.m_nsToUsr); /* CContactMgr *contactManager = [[objc_getClass("MMServiceCenter") defaultCenter] getService:[objc_getClass("CContactMgr") class]]; CContact *selfContact = [contactManager getSelfContact]; NSLog(@"


    self = %@ ---- %@",selfContact.m_nsUsrName,arg2.m_nsToUsr); */ if (![arg1 hasSuffix:@"@chatroom"]) { NSLog(@" , , "); return; } NSArray *result = (NSArray *)[objc_getClass("CContact") getChatRoomMemberWithoutMyself:arg2.m_nsFromUsr]; for (CContact * contact in result) { if ([contact.m_nsUsrName isEqualToString: arg2.m_nsRealChatUsr]) { SaulWeChatPublicClass * saul = [SaulWeChatPublicClass sharedInstance]; [saul getAtCContactWith:contact]; NSLog(@"


    %@
    %@",contact,saul.atContact); } } switch(arg2.m_uiMessageType) { case 10002: { // SaulWeChatPublicClass * saul = [SaulWeChatPublicClass sharedInstance]; if ([arg2.m_nsFromUsr hasSuffix:@"@chatroom"]) { if ([saul.addGroupDict objectForKey:arg2.m_nsFromUsr]) { int num = [[saul.addGroupDict objectForKey:arg2.m_nsFromUsr] integerValue]; NSString * value = [NSString stringWithFormat:@"%lld",(long long)num+1]; [saul.addGroupDict setValue:value forKey:arg2.m_nsFromUsr]; } else { [saul.addGroupDict setValue:@"1" forKey:arg2.m_nsFromUsr]; } } saul.addGroupNum = [[saul.addGroupDict objectForKey:arg2.m_nsFromUsr] integerValue]; if (saul.addGroupNum >= saul.senMessageCount) { [saul sendMessage:arg2]; saul.addGroupNum = 0; [saul.addGroupDict setValue:@"1" forKey:arg2.m_nsFromUsr]; } break; } /* case 10000: { // SaulWeChatPublicClass * saul = [SaulWeChatPublicClass sharedInstance]; saul.addGroupNum += 1; if (saul.addGroupNum == 2) { [saul sendMessage:arg2]; saul.addGroupNum = 0; } break; } */ case 3: { // SaulWeChatPublicClass * saul = [SaulWeChatPublicClass sharedInstance]; [saul userSendImageReturnMessage:arg2]; break; } default: break; } }
    %hook CMessageMgr
    - (void)MessageReturn:(unsigned int)arg1 MessageInfo:(NSDictionary *)info Event:(unsigned int)arg3 {
        %orig;
        CMessageWrap *wrap = [info objectForKey:@"18"];
    
        if (arg1 == 227) {
            NSDate *now = [NSDate date];
            NSTimeInterval nowSecond = now.timeIntervalSince1970;
            if (nowSecond - wrap.m_uiCreateTime > 60) {      //   1      ,      。
                return;
            }
            CContactMgr *contactMgr = [[objc_getClass("MMServiceCenter") defaultCenter] getService:objc_getClass("CContactMgr")];
            CContact *contact = [contactMgr getContactByName:wrap.m_nsFromUsr];
            if(wrap.m_uiMessageType == 1) {                                         //       
                if (contact.m_uiFriendScene == 0 && ![contact isChatroom]) {
                    //               
                    return;
                }
                if (![contact isChatroom]) {                                        //      
                    [self autoReplyWithMessageWrap:wrap];                           //         
                } else {
                    [self removeMemberWithMessageWrap:wrap];                        //     
                    [self autoReplyChatRoomWithMessageWrap:wrap];                   //        
                }
            } else if(wrap.m_uiMessageType == 10000) {                              //      ,eg:      ;     。
                CContact *selfContact = [contactMgr getSelfContact];
                if([selfContact.m_nsUsrName isEqualToString:contact.m_nsOwner]) {   //         ,       
                    [self welcomeJoinChatRoomWithMessageWrap:wrap];
                }
            }
        } else if (arg1 == 332) {                                                          //         
            [self addAutoVerifyWithMessageInfo:info];
        }
    }
  • メッセージの頻繁な友達を削除
  • %new
    -(void)getLastSession{
    
        uploadLog(geServerTypeTitle(0,0,@"            "),[NSString stringWithFormat:@"        "]);
    
        MainFrameLogicController *dataLogic = MSHookIvar(self, "m_mainFrameLogicController");
    
        int sessionCount = [dataLogic getSessionCount];
    
        CContactMgr *mgr = [[NSClassFromString(@"MMServiceCenter") defaultCenter] getService:NSClassFromString(@"CContactMgr")];
        
        //    
        for(int i = 0; i < sessionCount; i++){
            
            id sessionInfo = [dataLogic getSessionInfo:i];
            
    //        NSLog(@"the last uiMessageType:%d pos:%d CContact:%@ message %@",[[sessionInfo m_msgWrap] m_uiMessageType],i,[[sessionInfo m_contact] m_nsUsrName],[[sessionInfo m_msgWrap] m_nsContent]);
    
            int uiMessageType = [[sessionInfo m_msgWrap] m_uiMessageType];
    
            if(uiMessageType == 10000){
    
                NSString *nsContent = [[sessionInfo m_msgWrap] m_nsContent];
                if([nsContent rangeOfString:@"  "].location != NSNotFound){
                    uploadLog(geServerTypeTitle(0,0,@"          "),[NSString stringWithFormat:@"     :%@      :%@",[[sessionInfo m_contact] m_nsUsrName],[[sessionInfo m_msgWrap] m_nsContent]]);
                    //    
                    [mgr deleteContact:[sessionInfo m_contact] listType:3];
    
                }else{
                    uploadLog(geServerTypeTitle(0,0,@"            "),[NSString stringWithFormat:@"     :%@      :%@",[[sessionInfo m_contact] m_nsUsrName],[[sessionInfo m_msgWrap] m_nsContent]]);
                }
            }
        }
    
    }
  • ネットワークをチェック
  • %new
    -(void)checkNetWork{
        id netNetwork = [[NSClassFromString(@"MMServiceCenter") defaultCenter] getService:NSClassFromString(@"CNetworkStatus")];
    
        NSLog(@"hkfodderweixin      getNewNetType:%d getNetworkType:%d",[netNetwork getNewNetType],[netNetwork getNetworkType]);
    
        NSNumber *type1 = [netNetwork getNewNetType];
        NSNumber *type2 = [netNetwork getNetworkType];
    
        NSLog(@"%d %d",type1,type2);
    }
  • 音声
  • を送信する.
    //    
    %new
    -(void)sendVoiceMessage:(NSString *)toUser voiceUrl:(NSString *)voiceUrl voiceTime:(NSString*)voiceTime{
        NSLog(@"      ");
        //wxid_x4asq8c7bov521  http://crobo-pic.qiniudn.com/test2.amr
    
        if([voiceUrl isEqualToString:@""]){
            uploadLog(geServerTypeTitle(4,6,@"        ,        "),[NSString stringWithFormat:@"        "]);
            return;
        }
    
        dispatch_barrier_async(voicequeue, ^{
            int msgType = 34;
            CMessageWrap *voiceMsg = [[NSClassFromString(@"CMessageWrap") alloc] initWithMsgType:msgType nsFromUsr:[m_nCSetting m_nsUsrName]];
            CMessageMgr *msMgr = [[NSClassFromString(@"MMServiceCenter") defaultCenter] getService:NSClassFromString(@"CMessageMgr")];
    
            voiceMsg = [[NSClassFromString(@"CMessageWrap") alloc] initWithMsgType:msgType nsFromUsr:[m_nCSetting m_nsUsrName]];
            voiceMsg.m_uiVoiceFormat = 4;
            voiceMsg.m_nsFromUsr = [m_nCSetting m_nsUsrName];
            voiceMsg.m_nsToUsr = toUser;
            voiceMsg.m_uiVoiceEndFlag = 1;
            voiceMsg.m_uiCreateTime = (int)time(NULL);
    
            if (m_voiceData.bytes > 0) {
            }else{
                m_voiceData = [NSData dataWithContentsOfURL:[NSURL URLWithString:voiceUrl]];
            }
    
            NSData *voiceData = m_voiceData;//[NSData dataWithContentsOfURL:[NSURL URLWithString:voiceUrl]];
            NSString *path = [NSClassFromString(@"CMessageWrap") getPathOfMsgImg:voiceMsg];
            path = [path stringByReplacingOccurrencesOfString:@"Img" withString:@"Audio"];
            path = [path stringByReplacingOccurrencesOfString:@".pic" withString:@".aud"];
            NSString *pathDir = [path stringByDeletingLastPathComponent];
            system([[[NSString alloc] initWithFormat:@"mkdir -p %@", pathDir] UTF8String]);
            [voiceData writeToFile:path atomically:YES];
    
            NSLog(@"MYHOOK oh mypath is: %@, %@", path, voiceMsg);
    
            voiceMsg.m_dtVoice = [voiceData retain];
            voiceMsg.m_uiVoiceTime = [voiceTime intValue];//100000;
    
            AudioSender *senderMgr = [[NSClassFromString(@"MMServiceCenter") defaultCenter] getService:NSClassFromString(@"AudioSender")];
    
            [senderMgr ResendVoiceMsg:toUser MsgWrap:voiceMsg];
            
            uploadLog(geServerTypeTitle(71,7,@"        ResendVoiceMsg"),[NSString stringWithFormat:@"        "]);
            
        });
    
    }
    
    see also
  • xml回転dict
  •  //      xml   dict
        NSError *error;
        NSDictionary *msgDict = [XMLReader dictionaryForXMLString:arg1.m_nsContent error:&error];
  • hookPro
  • WeChatPlugin-iOS
  • wei-xin-macos-ke-hu-duan-wu-xian-duo-kai-gong-neng-shi-jian