Logos語(yǔ)法
http://iphonedevwiki.net/index.php/Logos
- 1、新建Logos測(cè)試工程
- 2、用class-dump導(dǎo)出頭文件
$class-dump -H 001-LogosDemo -o /Users/yaoqi/Desktop/LogosHeaders
- 3、新建Monkey工程,將Logos測(cè)試工程重簽名
此時(shí)Monkey工程已經(jīng)將libsubstrate.dylib庫(kù)和RevealServer.framework庫(kù)注入進(jìn)去了,有了libsubstrate.dylib庫(kù)就能寫(xiě)Logos語(yǔ)法了。
- 4、在Monkey中的Logos文件夾的.xm文件寫(xiě)Logos語(yǔ)法
Logos語(yǔ)法 | 功能解釋 | 事例 |
---|---|---|
%hook | 需要hook哪個(gè)類(lèi) | %hook Classname |
%end | 代碼塊結(jié)束標(biāo)記 | |
%group | 分組 | %group Groupname |
%new | 添加新方法 | %new(signature) |
%ctor | 構(gòu)造函數(shù) | %ctor { … } |
%dtor | 析構(gòu)函數(shù) | %dtor { … } |
%log | 輸出打印 | %log; %log([(<type>)<expr>, …]); |
%orig | 保持原有方法 | %orig;%orig(arg1, …); |
_02_loginHookDemoDylib.xm
// See http://iphonedevwiki.net/index.php/Logos
#import <UIKit/UIKit.h>
@interface ViewController: UIViewController
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^ __nullable)(void))completion NS_AVAILABLE_IOS(5_0);
+ (void)CL_classMethod;
@end
%hook ViewController
- (void)loginBtnClicked:(id)arg1 {
%log;
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"Hook成功了!!!" message:nil preferredStyle:(UIAlertControllerStyleAlert)];
[alertVC addAction:[UIAlertAction actionWithTitle:@"確定" style:(UIAlertActionStyleCancel) handler:nil]];
[self presentViewController:alertVC animated:YES completion:nil];
}
%new
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
[self.class CL_classMethod];
}
%new
+ (void)CL_classMethod {
NSLog(@"這是一個(gè)類(lèi)方法!!!");
}
%end
這里在ViewController中定義了一個(gè)方法presentViewController:animated:completion:,只是為了能編譯通過(guò),騙過(guò)Xcode編譯器。
5、運(yùn)行成功后,Monkey工程就能Hook到001-LogosDemo工程里面的loginBtnClicked:
Monkey工程注入FLEX庫(kù)
https://github.com/Flipboard/FLEX
- 1、在Monkey的Dylib動(dòng)態(tài)庫(kù)中注入FLEX庫(kù)
在Monkey工程的根目錄添加Podfile文件,Target為Monkey工程動(dòng)態(tài)庫(kù)的Target
# Uncomment the next line to define a global platform for your project
platform :ios, '9.0'
target '002-loginHookDemoDylib' do
use_frameworks!
pod 'FLEX'
end
- 2、界面展示
FLEX能查看App的文件、數(shù)據(jù)庫(kù)、沙盒、界面層級(jí)。。。
Logos練習(xí)
需求:在微信首頁(yè)導(dǎo)航欄左邊添加一個(gè)?按鈕,點(diǎn)擊事件和右邊按鈕的點(diǎn)擊效果一樣。
1、新建Monkey工程,重簽名微信包,并將FLEX注入進(jìn)動(dòng)態(tài)庫(kù)中
2、Xcode界面調(diào)試,class-dump微信包,找到首頁(yè)界面NewMainFrameViewController控制器
3、Xcode界面調(diào)試,找到微信導(dǎo)航欄右邊按鈕的點(diǎn)擊的showRightTopMenuBtn方法
Target <NewMainFrameRightTopMenuBtn: 0x104dd99d0>
Action showRightTopMenuBtn
- 4、在內(nèi)存中查找導(dǎo)航欄右邊按鈕視圖層次
5、寫(xiě)代碼實(shí)現(xiàn)需求
#import <UIKit/UIKit.h>
@interface NewMainFrameViewController :UIViewController
@end
@interface NewMainFrameRightTopMenuBtn: UIView
- (void)showRightTopMenuBtn;
@end
@interface MMBarButtonItem: UIBarButtonItem
@property(nonatomic,weak)NewMainFrameRightTopMenuBtn *view;
@end
%hook NewMainFrameViewController
-(UINavigationItem *)navigationItem{
// NSLog(@"\n\n\n-------------navigationItem-----");
//方法交換! 調(diào)用自己!
return %orig;
}
- (void)viewDidAppear:(_Bool)arg1{
%orig;
UIButton * leftBtn = [UIButton buttonWithType:(UIButtonTypeContactAdd)];
[leftBtn addTarget:self action:@selector(CL_leftClick) forControlEvents:(UIControlEventTouchUpInside)];
[self.navigationItem setLeftBarButtonItem: [[UIBarButtonItem alloc] initWithCustomView:leftBtn]];
}
- (void)viewDidLoad{
%orig;
// NSLog(@"\n\n\n-----viewDidLoad-----------");
}
%new
-(void)CL_leftClick
{
/**
從內(nèi)存中能查到調(diào)用該方法:[self.navigationItem.rightBarButtonItem.view showRightTopMenuBtn]
self:代表NewMainFrameViewController控制器
*/
MMBarButtonItem *btn = self.navigationItem.rightBarButtonItem;
[btn.view showRightTopMenuBtn];
}
%end