dyld(the dynamic link editor)是蘋果的動態連接器,是蘋果操做系統一個重要組成部分,在系統讀取程序MachO文件的Header段信息,作好程序準備工做以後,交由dyld負責加載動態庫和靜態庫以及其餘工做(後面章節會詳細介紹)。linux
動態庫:連接時不復制,在程序啓動後用動態加載,而後再決議符號,因此理論上動態庫只用存在一份,好多個程序均可以動態連接到這個動態庫上面,達到了節省內存(不是磁盤是內存中只有一份動態庫),還有另一個好處,因爲動態庫並不綁定到可執行程序上,因此咱們想升級這個動態庫就很容易,windows和linux上面通常插件和模塊機制都是這樣實現的。git
靜態庫:連接時會被完整的複製到可執行文件中,因此若是兩個程序都用了某個靜態庫,那麼每一個二進制可執行文件裏面其實都含有這份靜態庫的代碼。github
通常修改原始的程序,是利用代碼注入的方式,注入代碼就會選擇利用FrameWork或者Dylib等三方庫的方式注入;windows
一、FrameWork 注入:bash
二、Dylib注入框架
經過Xcode新建Dylib庫(注意:Dylib屬於MacOS因此須要修改屬性)工具
添加Target依賴,讓Xcode將自定義Dylib文件打包進入APP包。post
利用yololib進行注入。學習
///添加方法
class_addMethod(<#Class _Nullable __unsafe_unretained cls#>, <#SEL _Nonnull name#>, <#IMP _Nonnull imp#>, <#const char * _Nullable types#>)
複製代碼
///獲取實例方法
class_getInstanceMethod(<#Class _Nullable __unsafe_unretained cls#>, <#SEL _Nonnull name#>)
///獲取類方法
class_getClassMethod(<#Class _Nullable __unsafe_unretained cls#>, <#SEL _Nonnull name#>)
///交換方法
method_exchangeImplementations(<#Method _Nonnull m1#>, <#Method _Nonnull m2#>)
複製代碼
/// 替換方法實現
class_replaceMethod(<#Class _Nullable __unsafe_unretained cls#>, <#SEL _Nonnull name#>, <#IMP _Nonnull imp#>, <#const char * _Nullable types#>)
複製代碼
/// 設置方法實現
method_setImplementation(<#Method _Nonnull m#>, <#IMP _Nonnull imp#>)
/// 獲取方法實現
method_getImplementation(<#Method _Nonnull m#>)
複製代碼
+ (void)load{
///一、方法交換 找不到方法報錯
Method oldMethod = class_getInstanceMethod(objc_getClass("JDNewLoginViewController"), @selector(loginAction:));
Method newMethod = class_getInstanceMethod(self, @selector(nasy_loginAction:));
method_exchangeImplementations(oldMethod, newMethod);
}
/// 一、方法交換
-(void)nasy_loginAction:(id)btn {
NSLog(@"\n\n\nusername == %@......\npassword == %@......\n\n\n\n",[[[self valueForKey:@"_inputView"] subviews][0] valueForKey:@"text"],[[[self valueForKey:@"_inputView"] subviews][2] valueForKey:@"text"]);
[self nasy_loginAction:nil];
}
複製代碼
///二、添加方法
+ (void)load{
Method oldMethod = class_getInstanceMethod(objc_getClass("JDNewLoginViewController"), @selector(loginAction:));
BOOL isAdd = class_addMethod(objc_getClass("JDNewLoginViewController"), @selector(nasy_loginAction:), new_loginAction, "v@:");
if (isAdd) {
Method newMethod = class_getInstanceMethod(objc_getClass("JDNewLoginViewController"), @selector(nasy_loginAction:));
method_exchangeImplementations(oldMethod, newMethod);
}
}
void new_loginAction(id self , SEL _cmd){
NSLog(@"\n\n\nusername == %@......\npassword == %@......\n\n\n\n",[[[self valueForKey:@"_inputView"] subviews][0] valueForKey:@"text"],[[[self valueForKey:@"_inputView"] subviews][2] valueForKey:@"text"]);
[self performSelector:@selector(nasy_loginAction:) withObject:nil];
}
複製代碼
/// 三、交換方法實現
+ (void)load{
oldIMP = class_getMethodImplementation(objc_getClass("JDNewLoginViewController"), @selector(loginAction:));
class_replaceMethod(objc_getClass("JDNewLoginViewController"), @selector(loginAction:), new_loginAction, "v@:");
}
IMP ( * oldIMP)(id self,SEL _cmd);
void new_loginAction(id self , SEL _cmd){
NSLog(@"\n\n\nusername == %@......\npassword == %@......\n\n\n\n",[[[self valueForKey:@"_inputView"] subviews][0] valueForKey:@"text"],[[[self valueForKey:@"_inputView"] subviews][2] valueForKey:@"text"]);
oldIMP(self,_cmd);
}
複製代碼
/// 四、set get IMP
+ (void)load{
oldIMP = class_getMethodImplementation(objc_getClass("JDNewLoginViewController"), @selector(loginAction:));
Method oldMethod = class_getInstanceMethod(objc_getClass("JDNewLoginViewController"), @selector(loginAction:));
method_setImplementation(oldMethod, new_loginAction);
}
IMP ( * oldIMP)(id self,SEL _cmd);
void new_loginAction(id self , SEL _cmd){
NSLog(@"\n\n\nusername == %@......\npassword == %@......\n\n\n\n",[[[self valueForKey:@"_inputView"] subviews][0] valueForKey:@"text"],[[[self valueForKey:@"_inputView"] subviews][2] valueForKey:@"text"]);
oldIMP(self,_cmd);
}
複製代碼