對(duì)iOS的注入铃将,已經(jīng)有一定了解了兴溜。對(duì)于Mac app的注入侦厚,如何下手呢耻陕?
來寫個(gè)簡(jiǎn)單的小例子吧。
目標(biāo)app是自己寫的一個(gè)Mac app刨沦,要求hook按鈕的點(diǎn)擊事件诗宣,在處理事件之前,打印一下“hooked”表面hook成功想诅。
1.第一步召庞,先class_dump出文件頭,找到目標(biāo)函數(shù)来破。我們先明確一下目標(biāo):
類名:AppKitView
函數(shù):
- (void)btnAction:(id)arg1;
2.在xcode中新建一個(gè)framework項(xiàng)目,取名hook篮灼。
3.在新建的項(xiàng)目中,引入hook的框架徘禁。也就是2個(gè)文件诅诱,如圖:
在github的地址:
https://github.com/rentzsch/jrswizzle
在hook.h中,引入框架送朱,編輯宏定義
//
// hook.h
// hook
//
#import <Cocoa/Cocoa.h>
#import "JRSwizzle.h"
//! Project version number for hook.
FOUNDATION_EXPORT double hookVersionNumber;
//! Project version string for hook.
FOUNDATION_EXPORT const unsigned char hookVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <hook/PublicHeader.h>
#define CBGetClass(classname) objc_getClass(#classname)
#define CBRegisterClass(superclassname, subclassname) { Class class = objc_allocateClassPair(CBGetClass(superclassname), #subclassname, 0);objc_registerClassPair(class); }
#define CBHookInstanceMethod(classname, ori_sel, new_sel) { NSError *error; [CBGetClass(classname) jr_swizzleMethod:ori_sel withMethod:new_sel error:&error]; if(error) NSLog(@"%@", error); }
#define CBHookClassMethod(classname, ori_sel, new_sel) { NSError *error; [CBGetClass(classname) jr_swizzleClassMethod:ori_sel withClassMethod:new_sel error:&error]; if(error) NSLog(@"%@", error); }
#define CBGetInstanceValue(obj, valuename) object_getIvar(obj, class_getInstanceVariable([obj class], #valuename))
#define CBSetInstanceValue(obj, valuename, value) object_setIvar(obj, class_getInstanceVariable([obj class], #valuename), value)
3.項(xiàng)目中引入目標(biāo)頭文件
4.新建Main.h 和Main.mm娘荡,內(nèi)容如下
Main.h
//
// Main.h
// hook
//
#import <objc/runtime.h>
#import "hook.h"
Main.mm
//
// Main.m
// hook
//
#import "Main.h"
#import "AppKitView.h"
@implementation NSObject (hook)
#pragma mark - AppKitView
- (void)cb_btnAction:(id)arg1 {
[self cb_btnAction:arg1];
NSLog(@"cb_btnAction --- hooked");
}
@end
static void __attribute__((constructor)) initialize(void) {
NSLog(@"++++++++ loaded ++++++++");
// CBHookClassMethod();
CBHookInstanceMethod(AppKitView, @selector(btnAction:), @selector(cb_btnAction:));
}
上述代碼中,cb_btnAction 是我們定義的新函數(shù)驶沼,函數(shù)內(nèi)部調(diào)用自己就等于是調(diào)用被hook前的原函數(shù)(因?yàn)榉椒ū唤粨Q了)炮沐。
交換方法的代碼就是通過以下代碼實(shí)現(xiàn)的。
CBHookInstanceMethod(AppKitView, @selector(btnAction:), @selector(cb_btnAction:));
5.編寫腳本商乎,用于自動(dòng)注入
在xcode的targets->BuildPhases里添加一個(gè)腳本央拖。
腳本內(nèi)容:
#!/bin/bash
app_name="ColorPicker"
framework_name="hook"
app_bundle_path="/Applications/${app_name}.app/Contents/MacOS"
app_executable_path="${app_bundle_path}/${app_name}"
app_executable_backup_path="${app_executable_path}_"
framework_path="${app_bundle_path}/${framework_name}.framework"
# 備份原始可執(zhí)行文件
if [ ! -f "$app_executable_backup_path" ]
then
cp "$app_executable_path" "$app_executable_backup_path"
fi
cp -r "${BUILT_PRODUCTS_DIR}/${framework_name}.framework" ${app_bundle_path}
/opt/iOSOpenDev/bin/insert_dylib --all-yes "${framework_path}/${framework_name}" "$app_executable_backup_path" "$app_executable_path"
主要內(nèi)容就是,定義好目標(biāo)app的路徑鹉戚,備份好原有二進(jìn)制文件鲜戒。將編譯好的framework文件拷貝到目標(biāo)app目錄,用insert_dylib這個(gè)工具進(jìn)行注入抹凳。
insert_dylib這個(gè)工具是需要自己去編譯下載的遏餐。
github地址:
https://github.com/Tyilo/insert_dylib
到這里,我們做的工作大概有這些:
根據(jù)我們的代碼赢底,編譯生成一個(gè)framework失都。編譯完成后執(zhí)行xcode里面配置的腳本,將我們的framework復(fù)制到目標(biāo)app目錄幸冻,然后用insert_dylib工具將framework注入到app里粹庞。最后一步,就是要打開這個(gè)app洽损。編輯schema的excutable庞溜,選擇目標(biāo)app
好,再次編譯一下項(xiàng)目碑定。你就會(huì)發(fā)現(xiàn)流码,自動(dòng)編譯又官、注入、打開了app漫试。我們點(diǎn)擊一下按鈕事件六敬,看下控制臺(tái),注入成功了驾荣!
2017-03-15 15:58:56.418731 ColorPicker[18284:7540684] cb_btnAction --- hooked
2017-03-15 15:59:08.467269 ColorPicker[18284:7540684] cb_btnAction --- hooked
2017-03-15 15:59:08.771605 ColorPicker[18284:7540684] cb_btnAction --- hooked
2017-03-15 15:59:09.099117 ColorPicker[18284:7540684] cb_btnAction --- hooked
2017-03-15 15:59:09.419099 ColorPicker[18284:7540684] cb_btnAction --- hooked
2017-03-15 15:59:09.731221 ColorPicker[18284:7540684] cb_btnAction --- hooked