代码注入(11)
2021-04-21 本文已影响0人
为了自由的白菜
代码注入(11)
framework注入
假工程里写代码不会走,是因为APP(MachO)文件整个都被替换了
- 通过Xcode新建Framwork,将库安装进入APP包
- 通过yololib注入Framwork库路径。命令:$yololib(空格)MachO文件路径(空格)库路径
- 所有的Framwork加载都是由DYLD加载进入内存被执行的
- 注入成功的库路径会写入到MachO文件的LC_LOAD_DYLIB字段中
Tips
- 注意: MachView(烂苹果) -> 拖拽打不开,右键打开文件可解决
- MachOView
流程
- 可执行文件 -> dyld加载 -> Load Commands -> LC_MAIN -> LC_LOAD_DYLIB加载动态库 (通过路径加载) -> 将自己的代码, 包装在一个动态库里面, 再让IPA加载 (以动态库的形式注入)
- framework里面的代码也要加载, framework里面也是可执行文件
yololib使用
需要修改MachO -> ./yololib WeChat framework路径
dylib也可以
- 通过Xcode新建Dylib库(注意:Dylib属于MacOS所以需要修改属性)
- 添加Target依赖,让Xcode将自定义Dylib文件打包进入APP包。
- 利用yololib进行注入。
添加lib -> 更改配置
用脚本yololib
yololib
shell脚本
./yololib "$TARGET_APP_PATH/$APP_BINARY" "framework路径"
Method Swizzle
framework注入
破坏微信, 窃取密码 -> 界面事件相应链,慢慢找
静态分析!!! -> class-dump (获取类,方法列表)
./class-dump -H WeChat -o ./headers/
class-dump
Sublime Text -> onNext没有参数(self, _cmd)
第一种Hook
Method Swizzle 方法交互修正
//第一种
/**
+(void)load{
//原始的Method
Method onNext = class_getInstanceMethod(objc_getClass("WCAccountMainLoginViewController"), @selector(onNext));
//添加新方法!
class_addMethod(objc_getClass("WCAccountMainLoginViewController"), @selector(new_onNext), new_onNext, "v@:");
//交换
method_exchangeImplementations(onNext, class_getInstanceMethod(objc_getClass("WCAccountMainLoginViewController"), @selector(new_onNext)));
}
//新的IMP
void new_onNext(id self,SEL _cmd){
UITextField * pwd = (UITextField *)[[self valueForKey:@"_textFieldUserPwdItem"] valueForKey:@"m_textField"];
NSLog(@"密码是:%@",pwd.text);
//调用回原来的逻辑!!
//调用原来的方法!
[self performSelector:@selector(new_onNext)];
}
隐患: 回不去了!!!(没法调用原来的实现!, 因为不是在该类的分类去交换的)
第二种
class_replaceMethod
/*
+(void)load{
//原始的Method
Method onNext = class_getInstanceMethod(objc_getClass("WCAccountMainLoginViewController"), @selector(onNext));
old_onNext = class_replaceMethod(objc_getClass("WCAccountMainLoginViewController"), @selector(onNext), new_onNext, "v@:");
}
//原来的IMP
IMP (*old_onNext)(id self,SEL _cmd);
//新的IMP
void new_onNext(id self,SEL _cmd){
UITextField * pwd = (UITextField *)[[self valueForKey:@"_textFieldUserPwdItem"] valueForKey:@"m_textField"];
NSLog(@"密码是:%@",pwd.text);
//调用回原来的逻辑!!
//调用原来的方法!
old_onNext(self,_cmd);
//objc_msgSend();
}
第三种, 最好的, 推荐
大部分HOOK框架
method_getImplementation
method_setImplementation
+(void)load{
//原始的Method
old_onNext = method_getImplementation(class_getInstanceMethod(objc_getClass("WCAccountMainLoginViewController"), @selector(onNext)));
method_setImplementation(class_getInstanceMethod(objc_getClass("WCAccountMainLoginViewController"), @selector(onNext)), new_onNext);
}
//原来的IMP
IMP (*old_onNext)(id self,SEL _cmd);
//新的IMP
void new_onNext(id self,SEL _cmd){
UITextField * pwd = (UITextField *)[[self valueForKey:@"_textFieldUserPwdItem"] valueForKey:@"m_textField"];
NSLog(@"密码是:%@",pwd.text);
//调用回原来的逻辑!!
//调用原来的方法!
old_onNext(self,_cmd);
}