美文网首页
iOS-逆向19-Cycript高级用法和Logos

iOS-逆向19-Cycript高级用法和Logos

作者: 一亩三分甜 | 来源:发表于2021-06-27 10:43 被阅读0次

谁的青春不迷茫,总是在想的多,做的少。

《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拖入到工程中,重新运行


图片.png
image

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
image
图片.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)
    }
}
image

添加条件判断


image

%log打印与此方法相关的所有信息,相当于po,打印description方法


图片.png

%orig保持原有方法的实现,拿到原始调用的结果,在原来的结果上进行修改,%dtor析构函数,%new为Hook的类ViewController添加新的方法,%new必须在%hook里面

%new
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    NSLog(@"爽爽爽!!!");
}
%end
图片.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

相关文章

网友评论

      本文标题:iOS-逆向19-Cycript高级用法和Logos

      本文链接:https://www.haomeiwen.com/subject/eutxultx.html