谁的青春不迷茫,总是在想的多,做的少。
《iOS底层原理文章汇总》
上一篇文章《iOS-逆向18-Cycript》介绍了虚拟内存、LLDB、Chisel和Cycript,本文介绍Logos。
image
1.封装常用Cycript命令
I.在根目录下新建CloudShell文件夹,创建脚本vim cyConnect.sh,输入指令
cycript -r 172.20.190.37:6666
图片.png
image
II.在zshrc文件文件中配置环境变量,确保能全局使用,source ~/.zshrc
图片.png
III.执行脚本进入cy
图片.png
IV.修改微信BadgeString和转账值
sh cyConnect.sh
[UIApp setApplicationBadgeString:@"999"]
image
比如对方向我转账一分钱,我先通过金额数0.01找到显示的Label,通过重新给Label的text赋值
choose (UILabel)找到转账值的Label的地址0x121671410
image
修改内存中显示金额UILabel地址的值:#0x121671410.text = @"¥8880.00"
image
切换页面后,这个值会消失
通过cycript找界面会比较难,最好的方式是通过附加的方式
通过ViewDebugger能清晰的定位到控件的值
image
V其他命令
APPID直接获取Bundle Identifier
pviews()获取图层结构
pvcs()获取控制器
图片.png
这些指令封装在Monkey工程Config目录MDConfig.plist文件里面的ms和md对应的url中的MS.cy和md.cy文件中
image
2.自定义封装cy文件
I.新建test.cy文件
image
II.拖入目标工程中,在工程中勾选复制到Framework中
图片.png
image
运行,进入cy,使用test.cy中的语句前要先@import test
图片.png
III定义常用的函数
问题:为什么LLDB修改内存中的值没有立刻生效,而cy修改内存中中的值,立刻生效看到了变化,因为LLDB中断了进程程序静止,过掉断点后生效,而cy并没有中断进程
//IIFE 匿名函数自执行表达式
(function(exports){
APPID = [NSBundle mainBundle].bundleIdentifier,
APPPATH = [NSBundle mainBundle].bundlePath,
APPHOME = NSHomeDirectory(),
//如果有变化,就用function去定义!!
HKRootvc = function(){
return UIApp.keyWindow.rootViewController;
};
HKKeyWindow = function(){
return UIApp.keyWindow;
};
HKGetCurrentVCFromRootVc = function(rootVC){
var currentVC;
if([rootVC presentedViewController]){
rootVC = [rootVC presentedViewController];
}
if([rootVC isKindOfClass:[UITabBarController class]]){
currentVC = HKGetCurrentVCFromRootVc(rootVC.selectedViewController);
}else if([rootVC isKindOfClass:[UINavigationController class]]){
currentVC = HKGetCurrentVCFromRootVc(rootVC.visibleViewController);
}else{
currentVC = rootVC;
}
return currentVC;
};
HKCurrentVC = function(){
return HKGetCurrentVCFromRootVc(HKRootvc());
};
})(exports);
将hank.cy拖入到工程中,重新运行
![](https://img.haomeiwen.com/i4193251/4213487988c16242.png)
![](https://img.haomeiwen.com/i4193251/3439cf2fe8747914.jpg)
3.Logos
1.新建简单登录工程Demo,通过Monkey新建HookDemo模拟Hook,拷贝MachO文件并提取DemoHeaders
2.将Demo.app拷贝到HookDemo的TargetApp目录下,运行
image
image
3.logos语句Hook
Logos语法其实是CydiaSubstruct框架提供的一组宏定义。便于开发者使用宏进行HOOK操作。语法简单,功能强大且稳定。
http://iphonedevwiki.net/index.php/Logos
Logos语法分为三大类:
Block level
这一类型的指令会开辟一个代码块,以%end结束。
%group、%hook、% subclass 、 %end
Top level
这个TopLevel指令不放在BlockLevel中。
%config、%hookf、%ctor、%dtor
Function level
这一块的指令就放在方法中。
%init、%class、 %c、 %orig、%log
#import <UIKit/UIKit.h>
@interface ViewController:UIViewController
@end
%hook ViewController
-(void)loginBtnClick:(id)arg1{
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"Hook成功" message:nil preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:nil];
[alertVC addAction:cancel];
[self showDetailViewController:alertVC sender:nil];
}
%end
![](https://img.haomeiwen.com/i4193251/338a473a6e1b676f.jpg)
![](https://img.haomeiwen.com/i4193251/8b5f123dfd95ec5b.png)
group语法,没有分配组会有一个默认隐藏组,有默认的构造%ctor和%init
image
%group group1
%hook ViewController
- (void)loginBtnClick:(id)arg1{
%log;
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"Hook成功group1" message:nil preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:nil];
[alertVC addAction:cancel];
[self showDetailViewController:alertVC sender:nil];
}
%new
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
NSLog(@"爽爽爽!!!");
}
%end
%end
%group group2
%hook ViewController
- (void)loginBtnClick:(id)arg1{
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"Hook成功group2" message:nil preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:nil];
[alertVC addAction:cancel];
[self showDetailViewController:alertVC sender:nil];
}
%end
%end
%ctor{
if([UIDevice currentDevice].systemVersion.doubleValue >= 11){
%init(group1)
}else{
%init(group2)
}
}
![](https://img.haomeiwen.com/i4193251/e3ac4b7fde2d6d2c.jpg)
添加条件判断
![](https://img.haomeiwen.com/i4193251/031f786f8e678825.jpg)
%log打印与此方法相关的所有信息,相当于po,打印description方法
![](https://img.haomeiwen.com/i4193251/41996fe775276942.png)
%orig保持原有方法的实现,拿到原始调用的结果,在原来的结果上进行修改,%dtor析构函数,%new为Hook的类ViewController添加新的方法,%new必须在%hook里面
%new
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
NSLog(@"爽爽爽!!!");
}
%end
![](https://img.haomeiwen.com/i4193251/47a9bd790439e809.png)
通过runtime也可以实现动态添加方法,但写法动态注入会比较多语句,但logos简化了这一流程,添加逻辑,点击屏幕收起键盘
%hook ViewController
- (void)loginBtnClick:(id)arg1{
%log;
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"Hook成功" message:nil preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:nil];
[alertVC addAction:cancel];
[self showDetailViewController:alertVC sender:nil];
}
%new
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
NSLog(@"爽爽爽!!!");
[self.view endEditing:YES];
}
%end
可将头文件中的属性和方法都引入,按照头文件的方式定义,添加类方法,通过类名调用类方法[NSClassFromString(@"ViewController") Cloud_classMethod]
简化写法通过%c拿到类名[%c(ViewController) Cloud_classMethod],并不能直接调用[ViewController Cloud_classMethod],会报错
#import <UIKit/UIKit.h>
@interface ViewController:UIViewController
{
UITextField *_uid;
UITextField *_pwd;
}
@property(nonatomic) __weak UITextField *pwd; // @synthesize pwd=_pwd;
@property(nonatomic) __weak UITextField *uid; // @synthesize uid=_uid;
- (void)postUid:(id)arg1 Pwd:(id)arg2;
- (void)viewDidLoad;
- (void)loginBtnClick:(id)arg1;
+(void)Cloud_classMethod;
@end
%hook ViewController
- (void)loginBtnClick:(id)arg1{
%log;
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"Hook成功" message:nil preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:nil];
[alertVC addAction:cancel];
[self showDetailViewController:alertVC sender:nil];
}
%new
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
NSLog(@"爽爽爽!!!");
[self.view endEditing:YES];
//调用类方法
[NSClassFromString(@"ViewController") Cloud_classMethod];
// [self.class Cloud_classMethod];
}
%new
+(void)Cloud_classMethod{
NSLog(@"这是一个类方法!");
}
%end
网友评论