<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      IOS中如何Hook消息

      IOS中如何Hook消息

        

        年過完了,該收心了,該開始學習了。

        我們都知道在windows下可以通過API輕松的hook很多消息,IOS里面貌似還沒有現成的API(可能是我還沒發現吧),前段時間碰巧看到Objective-C運行時的一些東西,于是心想著是不是可以嘗試一下實現hook的功能。

        為什么要hook消息呢,因為有些時候我們可能無法直接去繼承一個類,卻又想先截獲某些消息做一些處理,然后再接著進行正常的處理流程。今天使用運行時的一些API實現了基本的hook功能。

        下面先直接上源碼:

       1 //
       2 //  TestHookObject.m
       3 //  TestHookMessage
       4 //
       5 //  Created by mapleCao on 13-2-28.
       6 //  Copyright (c) 2013年 mapleCao. All rights reserved.
       7 //
       8 
       9 #import "TestHookObject.h"
      10 #import <objc/objc.h>
      11 #import <objc/runtime.h>
      12 
      13 @implementation TestHookObject
      14 
      15 // this method will just excute once
      16 + (void)initialize
      17 {
      18     // 獲取到UIWindow中sendEvent對應的method
      19     Method sendEvent = class_getInstanceMethod([UIWindow class], @selector(sendEvent:));
      20     Method sendEventMySelf = class_getInstanceMethod([self class], @selector(sendEventHooked:));
      21     
      22     // 將目標函數的原實現綁定到sendEventOriginalImplemention方法上
      23     IMP sendEventImp = method_getImplementation(sendEvent);
      24     class_addMethod([UIWindow class], @selector(sendEventOriginal:), sendEventImp, method_getTypeEncoding(sendEvent));
      25     
      26     // 然后用我們自己的函數的實現,替換目標函數對應的實現
      27     IMP sendEventMySelfImp = method_getImplementation(sendEventMySelf);
      28     class_replaceMethod([UIWindow class], @selector(sendEvent:), sendEventMySelfImp, method_getTypeEncoding(sendEvent));
      29 }
      30 
      31 /*
      32  * 截獲到window的sendEvent
      33  * 我們可以先處理完以后,再繼續調用正常處理流程
      34  */
      35 - (void)sendEventHooked:(UIEvent *)event
      36 {
      37     // do something what ever you want
      38     NSLog(@"haha, this is my self sendEventMethod!!!!!!!");
      39     
      40     // invoke original implemention
      41     [self performSelector:@selector(sendEventOriginal:) withObject:event];
      42 }
      43 
      44 @end

        下面我們來逐行分析一下上面的代碼:

        首先我們來看19行,這一行主要目的是獲取到UIWindow原生的sendEvent的Method(一個結構體,用來對方法進行描述),接著第20行是獲取到我們自己定義的類中的sendEvent的Method(這兩個方法的簽名必須一樣,否則運行時報錯)。第23行我們通過UIWindow原生的sendEvent的Method獲取到對應的IMP(一個函數指針),第24行使用運行時API Class_addMethod給UIWindow類添加了一個叫sendEventOriginal的方法,該方法使用UIWindow原生的sendEvent的實現,并且有著相同的方法簽名(必須相同,否則運行時報錯)。27行是獲取我們自定義類中的sendEventMySelf的IMP,28行是關鍵的一行,這一行的主要目的是為UIWindow原生的sendEvent指定一個新的實現,我們看到我們將該實現指定到了我們自己定義的sendEventMySelf上。到了這兒我們就完成了偷梁換柱,大功告成。

        執行上面這些行以后,我們就成功的將UIWindow的sendEvent重定向到了我們自己的寫的sendEventMySelf的實現,然后將其原本的實現重定向到了我們給它新添加的方法sendEventOriginal中。而sendEventMySelf中,我們首先可以對這個消息進行我們想要的處理,然后再通過41行調用sendEventOriginal方法轉到正常的執行流程。

        這塊兒你可能有個困惑 “我們自定義類中明明是沒有sendEventOriginal方法的啊?” 

        為什么執行起來不報錯,而且還會正常執行?因為sendEventMySelf是UIWindow的sendEvent重定向過來的,所以在運行時該方法中的self代表的就是UIWindow的實例,而不再是TestHookObject的實例了。加上sendEventOriginal是我們通過運行時添加到UIWindow的實例方法,所以可以正常調用。當然如果直接通過下面這種方式調用也是可以的,只不過編譯器會提示警告(編譯器沒那么智能),因此我們采用了performSelector的調用方式。

      [self sendEventOriginal:event];

        以上就是Hook的實現,使用時我們只需要讓TestHookObject類執行一次初始話操作就可以了,執行完以后。UIWindow的sendEvent消息就會會hook到我們的sendEventMySelf中了。

        下面是調用代碼:

       

      Install Hook
      - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
      {
          self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
          // Override point for customization after application launch.
          self.viewController = [[[TestHookViewController alloc] initWithNibName:@"TestHookViewController" bundle:nil] autorelease];
          self.window.rootViewController = self.viewController;
          [self.window makeKeyAndVisible];
          
          
          //hook UIWindow‘s SendEvent method
          TestHookObject *hookSendEvent = [[TestHookObject alloc] init];
          [hookSendEvent release];
          
          UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
          btn.center = CGPointMake(160, 240);
          btn.backgroundColor = [UIColor redColor];
          [btn addTarget:self action:@selector(btnAction:) forControlEvents:UIControlEventAllEvents];
          [self.window addSubview:btn];
          [btn release];
          
          return YES;
      }

       

        代碼中我們還專門添加了一個button來驗證,hook完以后消息是否正常傳遞。經驗證消息流轉完全正常。

        2013年寫的第一篇博客,希望大家能喜歡!!!

       

      注:歡迎轉載,轉載請注明出處!

       

      參考資料:Objective-C運行時源代碼

           Objective-C Runtime Reference

      一片-楓葉

      2013年2月28日

        

       

       

      posted on 2013-02-28 22:42  一片-楓葉  閱讀(14434)  評論(22)    收藏  舉報

      主站蜘蛛池模板: 国产精品人成视频免费国产| 色综合色天天久久婷婷基地| 亚洲综合精品一区二区三区| 精人妻无码一区二区三区| 亚洲人精品午夜射精日韩| 欧洲美女黑人粗性暴交视频| 亚洲加勒比久久88色综合| 精品无码人妻一区二区三区| 麻豆精品一区二区综合av| 成人国产精品日本在线观看| 精品国产免费一区二区三区香蕉| 久久亚洲精品中文字幕馆| 日韩无码视频网站| 亚洲欧美日韩久久一区二区 | 国模无吗一区二区二区视频| 国产精品午夜无码AV天美传媒| 无码人妻一区二区三区精品视频| 边吃奶边添下面好爽| 国产成人午夜在线视频极速观看 | 亚洲高潮喷水无码AV电影| 麻豆成人精品国产免费| 丰满人妻一区二区三区高清精品| 天堂在线中文| 亚洲av成人一区二区三区| 国产av一区二区三区精品| 极品人妻少妇一区二区三区| 国产激情第一区二区三区| 亚洲伊人久久综合影院| 国产av寂寞骚妇| 一 级做人爱全视频在线看| 亚洲国产另类久久久精品| 韩国19禁无遮挡啪啪无码网站 | 国产精品欧美一区二区三区不卡| 国产高清无遮挡内容丰富| 巴南区| 97久久久精品综合88久久| 少妇午夜啪爽嗷嗷叫视频| 久久精品道一区二区三区| 亚洲国产在一区二区三区| 欧美在线人视频在线观看| 免费观看成人毛片a片|