ios逆向工程-內部鉤子(Method Swizzling)

來源:互聯網
上載者:User

標籤:

Method Swizzling(方法調配)

怎麼說呢,先瞭解什麼是鉤子為什麼用鉤子,學過C++的朋友應該清楚,hook就是用來獲得(截斷/改變)底層調用的方法。這樣我們可以自由的修改或者讀取一些想要的東西。(個人理解)

下面是百度百科的解釋:鉤子(Hook),是Windows訊息處理機制的一個平台,應用程式可以在上面設定子程以監視指定視窗的某種訊息,而且所監視的視窗可以是其他進程所建立的。當訊息到達後,在目標視窗處理函數之前處理它。鉤子機制允許應用程式截獲處理window訊息或特定事件

那ios中我們就用Method Swizzling來實現,為什麼說是內部鉤子呢,因為需要在工程裡實現,我改天會分享外部的。

----------------------------------------------淩亂的分割線------------------------------------------

先瞭解一下SEL和IMP的概念,

SEL可以理解為函數名的意思,我們常用的@selector()就是通過字串獲得SEL

IMP可以理解成函數指標的意思,是能正確讀取到函數的內容

一般是這樣的:盜個圖

我們要做的就是把連結線解開,然後連到我們自訂的函數IMP上,如果有需要的話,我們再連回原來的IMP上

就是這樣的:

如果在執行完IMPn後還想繼續調用IMPc的話,只需要在IMPn中調用selectorN就行了。

---------------------------------------------淩亂的分割線----------------------------------------

具體怎麼做呢:

Method origMethod = class_getInstanceMethod(class, origSelector);  //擷取SEL的Method

Method是一個結構體,我們想要的IMP就在裡面,看看結構

 struct objc_method {    SEL method_name                                          OBJC2_UNAVAILABLE;    char *method_types                                       OBJC2_UNAVAILABLE;    IMP method_imp                                           OBJC2_UNAVAILABLE;}
IMP origIMP = method_getImplementation(origMethod);  //擷取Method中的IMP

ok,IMP擷取到了,串連SEL到別的IMP呢

BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types);  //先增加新方法名SEL+原來的IMPIMP method_setImplementation(Method m, IMP imp);                       //然後將原來的method(SEL)重新分配新的IMP
void method_exchangeImplementations(Method m1, Method m2) //或者可以使用method的交換方法


---------------------------------------------淩亂的分割線-------------------------------------

實戰,假設我們想知道app跳轉都傳送了什麼值(如應用調用QQ分享什麼的),那麼我們可以勾取UIApplication的OpenUrl方法

#import "KHookObjectWrapper.h"#import "UIKit/UIKit.h"#import <objc/objc.h>#import <objc/runtime.h>@implementation KHookObjectWrapper+ (void)setup{    //openURL    Method m = class_getInstanceMethod([UIApplication class], @selector(openURL:));    class_addMethod([UIApplication class], @selector(hook_openURL:), method_getImplementation(m), method_getTypeEncoding(m));    method_setImplementation(m, class_getMethodImplementation([self class], @selector(hook_openURL:)));}- (BOOL)hook_openURL:(NSURL *)url{    NSLog(@"hook_openURL:%@", [url absoluteString]);    return [self hook_openURL:url];}

使用method的交換方法實現:

#import "KHookObjectWrapper.h"#import "UIKit/UIKit.h"#import <objc/objc.h>#import <objc/runtime.h>@implementation KHookObjectWrapper+ (void)setup{    //openURL    Method m = class_getInstanceMethod([UIApplication class], @selector(openURL:));    Method m2 = class_getInstanceMethod([self class], @selector(hook_openURL:));        class_addMethod([UIApplication class], @selector(hook_openURL:), method_getImplementation(m), method_getTypeEncoding(m)); //為什麼要有這句的,因為UIApplication沒有hook_openURL方法會奔潰,大家覺得可以講self的hook_openURL改名成openURL,大家可以試試,也是不行的        method_exchangeImplementations(m, m2);}- (BOOL)hook_openURL:(NSURL *)url{    NSLog(@"hook_openURL:%@", [url absoluteString]);    return [self hook_openURL:url];}@end


--------------------------------------------------------------------

另外再加一點,假如你只是想重寫類的某些方法,分類也是不錯的選擇,分類一旦加入工程,不需要包含標頭檔有會生效,所以請謹慎使用

@implementation UIApplication (test)- (BOOL)openURL:(NSURL*)url {    NSLog(@"!!!!!%@", [url absoluteString]);    return YES;}@end

當然你沒辦法重新在掉回原來的IMP了!

ios逆向工程-內部鉤子(Method Swizzling)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.