iOS-逆向20-微信抢红包界面项目和越狱

《iOS底层原理文章汇总》
上一篇文章《iOS-逆向19-Cycript高级用法和Logos》介绍了Cycript高级用法和Logos,本文介绍微信项目(自动抢红包)。
仅限于学习技术,无任何商业用途

image

1.模拟微信自动抢红包

I.通过View Debugger看设置界面所在的控制器


图片.png

II.导入cloud.cy


图片.png

A.界面分析:查找要修改的tableView,数据源和要Hook的方法

图片.png

获取当前控制器

cy# HKCurrentVC()
#"<NewSettingViewController: 0x158015e00>"

查看dataSource为WCTableViewManager,通过WCTableViewManager找到tableView和tableView的sections

cy# #0x15784a400.dataSource
#"<WCTableViewManager: 0x1568a8e00>"

导出WeChat所有头文件,找到WCTableViewManager
class-dump -H WeChat -o WeChatHeaders/,查看头文件中的成员变量
可通过给tableView添加背景色验证当前的tableView是否是显示的tableView


图片.png

图片.png

图片.png

修改界面需要hook的tableView方法


图片.png

图片.png

B.hook方法

- (id)tableView:(id)arg1 cellForRowAtIndexPath:(id)arg2;
- (long long)tableView:(id)arg1 numberOfRowsInSection:(long long)arg2;
- (long long)numberOfSectionsInTableView:(id)arg1;

通过调试发现WCTableViewManager在很多地方都用到这个类,但需求只改NewSettingViewController,需要做区分,通过什么区分呢,这里通过响应者链条区分


image

寻找响应者链条,找到所属的控制器,精确定位到设置页面

cy# choose(WCTableViewManager)
[#"<WCTableViewManager: 0x11d0980c0>",#"<WCTableViewManager: 0x12fd1ca80>",#"<WCTableViewManager: 0x11d1bff40>"]
cy# #0x11d1bff40.tableView.nextResponder.nextResponder
#"<NewSettingViewController: 0x11c85a000>"
//有多少组
- (long long)numberOfSectionsInTableView:(UITableView *)tableView{
    if([tableView.nextResponder.nextResponder isKindOfClass:%c(NewSettingViewController)]){
        NSLog(@"是设置页面!!!");
    }
    return %orig;
}
image

图片.png

增加一行两个cell

#import <UIKit/UIKit.h>
//为了编译通过
@interface WCTableViewManager:NSObject
- (long long)numberOfSectionsInTableView:(UITableView *)tableView;
@end

%hook WCTableViewManager
- (double)tableView:(UITableView *)tableView heightForRowAtIndexPath:(id)indexPath{
    //定位设置页面
    if([tableView.nextResponder.nextResponder isKindOfClass:%c(NewSettingViewController)] && [indexPath section] ==
       [self numberOfSectionsInTableView:tableView] - 1){
        return 44;
    }
    return %orig;
}
//cell
- (id)tableView:(UITableView *)tableView cellForRowAtIndexPath:(id)indexPath{
    //定位设置页面
    if([tableView.nextResponder.nextResponder isKindOfClass:%c(NewSettingViewController)] && [indexPath section] ==
       [self numberOfSectionsInTableView:tableView] - 1){
        UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
        cell.backgroundColor = [UIColor whiteColor];
        cell.textLabel.text = @"cloud知识";
        return cell;
    }
    return %orig;
}
//每一组有多少行
- (long long)tableView:(UITableView *)tableView numberOfRowsInSection:(long long)section{
    //定位设置页面
    if([tableView.nextResponder.nextResponder isKindOfClass:%c(NewSettingViewController)] && section ==
       [self numberOfSectionsInTableView:tableView] - 1){
        return 2;
    }
    return %orig;
}
//有多少组
- (long long)numberOfSectionsInTableView:(UITableView *)tableView{
    //定位设置页面
    if([tableView.nextResponder.nextResponder isKindOfClass:%c(NewSettingViewController)]){
        NSLog(@"-------设置页面-------");
        //在原来的基础上多搞一组
        return %orig+1;
    }
    return %orig;
}
%end
image

C.添加自动抢红包界面

1.监听自动抢红包的时间输入框的键盘输入,弹起键盘,则tableView向上抬升,防止键盘挡住tableView


image

image

2.设置时间存储在本地沙盒中,键盘弹起,提升tableView
I.设置时间存储在本地沙盒

%new
- (void)textFieldDidChangeValue:(NSNotification *)notification{
    
    UITextField *sender = (UITextField *)[notification object];
    [HKDefaults setValue:sender.text forKey:HKTIMEKEY];
    [HKDefaults synchronize];
}

II.监听键盘,提升tableView防止被挡住,hook控制器NewSettingViewController,在viewDidLoad中监听keyboardWillShow和keyboardWillHide提升tableView,通过View Debugger发现tableView在控制器的view上面,通过提升view达到防止被遮挡的目的

%hook NewSettingViewController
%new
-(void)keyboardWillShow:(NSNotification*)note{
    
    UIView * view = self.view;
    CGRect keyBoardRect=[note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    view.frame = CGRectMake(0, -keyBoardRect.size.height, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height );
}

%new
-(void)keyboardWillHide:(NSNotification*)note{
    UIView * view = self.view;
    view.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
    
}
- (void)viewDidLoad{
    %orig;
    //监听键盘的弹出和消失
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
%end

III.键盘取消第一响应者,收起键盘,发现微信WCTableViewManager类中已经实现了方法- (void)scrollViewWillBeginDragging:(id)arg1,不能覆盖原来的方法,只能重写加上%orig,使tableView取消第一响应者
严谨起见,只在NewSettingViewController中拖拽收起键盘,防止覆盖掉其他页面

image

//拖拽就退出键盘
- (void)scrollViewWillBeginDragging:(id)arg1{
    %orig;
    //严谨起见,只在NewSettingViewController中拖拽收起键盘,防止覆盖掉其他页面
    if([MSHookIvar <UITableView *>(self,"_tableView").nextResponder.nextResponder isKindOfClass:%c(NewSettingViewController)]){
        [MSHookIvar <UITableView *>(self,"_tableView") endEditing:YES];
    }
}
0

以上可以再hook的方法中加上前缀更加严谨
自动抢红包界面完整代码如下

#import <UIKit/UIKit.h>
#define HKDefaults [NSUserDefaults standardUserDefaults]
#define HKSWITCHKEY @"HKSWITCHKEY"
#define HKTIMEKEY @"HKTIMEKEY"
//为了编译通过
@interface WCTableViewManager:NSObject
- (long long)numberOfSectionsInTableView:(UITableView *)tableView;
@end
@interface NewSettingViewController:UIViewController
@end

%hook WCTableViewManager
%new
- (void)textFieldDidChangeValue:(NSNotification *)notification{
    
    UITextField *sender = (UITextField *)[notification object];
    [HKDefaults setValue:sender.text forKey:HKTIMEKEY];
    [HKDefaults synchronize];
}

%new
-(void)switchChang:(UISwitch *)switchView{
    [HKDefaults setBool:switchView.isOn forKey:HKSWITCHKEY];
    [HKDefaults synchronize];
    [MSHookIvar <UITableView *>(self,"_tableView") reloadData];
}
//拖拽就退出键盘
- (void)scrollViewWillBeginDragging:(id)arg1{
    %orig;
    //严谨起见,只在NewSettingViewController中拖拽收起键盘,防止覆盖掉其他页面
    if([MSHookIvar <UITableView *>(self,"_tableView").nextResponder.nextResponder isKindOfClass:%c(NewSettingViewController)]){
        [MSHookIvar <UITableView *>(self,"_tableView") endEditing:YES];
    }
}

- (double)tableView:(UITableView *)tableView heightForRowAtIndexPath:(id)indexPath{
    //定位设置页面
    if([tableView.nextResponder.nextResponder isKindOfClass:%c(NewSettingViewController)] && [indexPath section] ==
       [self numberOfSectionsInTableView:tableView] - 1){
        return 44;
    }
    return %orig;
}
//cell
- (id)tableView:(UITableView *)tableView cellForRowAtIndexPath:(id)indexPath{
    //定位设置界面,并且是最后一组
    if([tableView.nextResponder.nextResponder isKindOfClass:%c(NewSettingViewController)]
       && [indexPath section] ==[self numberOfSectionsInTableView:tableView]-1){
        
        UITableViewCell * cell = nil;
        if([indexPath row] == 0){
            static NSString * swCell = @"SWCELL";
            cell = [tableView dequeueReusableCellWithIdentifier:swCell];
            if(!cell){
                cell = [[UITableViewCell alloc] initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:nil];
            }
            cell.textLabel.text = @"自动抢红包";
            //抢红包开关!!
            UISwitch * switchView = [[UISwitch alloc] init];
            switchView.on = [HKDefaults boolForKey:HKSWITCHKEY];
            [switchView addTarget:self action:@selector(switchChang:) forControlEvents:(UIControlEventValueChanged)];
            cell.accessoryView = switchView;
            cell.imageView.image = [UIImage imageNamed:([HKDefaults boolForKey:HKSWITCHKEY] == 1) ? @"unlocked" : @"locked"];
        }else if([indexPath row] == 1){
            static NSString * waitCell = @"waitCell";
            cell = [tableView dequeueReusableCellWithIdentifier:waitCell];
            if(!cell){
                cell = [[UITableViewCell alloc] initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:nil];
            }
            cell.textLabel.text = @"等待时间(秒)";
            UITextField * textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 150, 40)];
            //监听键盘输入
            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldDidChangeValue:) name:UITextFieldTextDidChangeNotification object:textField];
            textField.text = [HKDefaults valueForKey:HKTIMEKEY];
            textField.borderStyle = UITextBorderStyleRoundedRect;
            cell.accessoryView = textField;
            cell.imageView.image = [UIImage imageNamed:@"clock"];
            
        }
        cell.backgroundColor = [UIColor whiteColor];
        return cell;
        
    }else{
        return %orig;
    }
}
//每一组有多少行
- (long long)tableView:(UITableView *)tableView numberOfRowsInSection:(long long)section{
    //定位设置页面
    if([tableView.nextResponder.nextResponder isKindOfClass:%c(NewSettingViewController)] && section ==
       [self numberOfSectionsInTableView:tableView] - 1){
        return 2;
    }
    return %orig;
}
//有多少组
- (long long)numberOfSectionsInTableView:(UITableView *)tableView{
    //定位设置页面
    if([tableView.nextResponder.nextResponder isKindOfClass:%c(NewSettingViewController)]){
        //在原来的基础上多搞一组
        return %orig+1;
    }
    return %orig;
}

%end

%hook NewSettingViewController
%new
-(void)keyboardWillShow:(NSNotification*)note{
    
    UIView * view = self.view;
    CGRect keyBoardRect=[note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    view.frame = CGRectMake(0, -keyBoardRect.size.height, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height );
}

%new
-(void)keyboardWillHide:(NSNotification*)note{
    UIView * view = self.view;
    view.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
    
}
- (void)viewDidLoad{
    %orig;
    //监听键盘的弹出和消失
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}

%end

2.越狱

I.iOS系统安全启动链

当启动一台iOS设备时,系统首先会从只读的ROM中读取初始化指令,也就是系统的引导程序(事实上所有的操作系统启动时都要经过这一步,只是过程略有不同)。这个引导ROM包含苹果官方权威认证的公钥,他会验证底层启动加载器(LLB)的签名,一旦通过验证后就启动系统。LLB会做一些基础工作,然后验证第二级引导程序iBoot。iBoot启动后,设备就可以进入恢复模式或启动内核。在iBoot验证完内核签名的合法性之后,整个启动程序开始步入正轨:加载驱动程序、检测设备、启动系统守护进程。这个信任链会确保所有的系统组件都有苹果官方写入、签名、分发,不能来自第三方机构,
图片.png

II.完美越狱和非完美越狱

根据越狱的情况不同可以分为如下两种越狱:
完美越狱
所谓完美越狱就是破解iOS系统漏洞之后,每次系统重启都能自动调用注入的恶意代码,达到破坏安全验证,再次获得ROOT权限。

非完美越狱
所谓非完美越狱是指,越狱系统后,并没有完全破解安全链,有部分信息或功能应用不佳;比如;关机以后必须去连接越狱软件来引导开机;或者重启会导致越狱的失效;这样的越狱称为“不完美越狱”。

III.越狱过程

目前比较靠谱的两种越狱工具:
uncOver 越狱 https://unc0ver.dev/
Odyssey越狱 https://theodyssey.dev/

IV.下载uncOver,通过Monkey重签名安装

A.重签安装,Xcode断掉
B.重新运行unc0ver,勾选OpenSSH
C.越狱过程会重启设备
D.重启之后再次运行越狱工具


image

越狱成功手机桌面会多Cydia和Substitute


图片.png

图片.png

打开Cydia,搜索openssh,绿色勾勾说明已经安装过了
图片.png

安装蜜蜂源和雷锋源,源是服务器存放了插件和安装包
添加源

蜜蜂源:apt.cydiami.com
雷锋源:apt.abcydia.com
两个源有交集


图片.png

image

图片.png

图片.png

V.10.0以下设备爱思助手,完美越狱

VI.odyssey断开网络,开始越狱,执行到一半,会提示打开网络,打开网络点击Ok会重启完成越狱,手机桌面多一个Sileo和Cydia一样的功能

VII.恢复系统,若遇到JailBreak Completed的弹窗错误,重签安装下,即可恢复系统到越狱前的状态

图片.png

图片.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,817评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,329评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,354评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,498评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,600评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,829评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,979评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,722评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,189评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,519评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,654评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,329评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,940评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,762评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,993评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,382评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,543评论 2 349

推荐阅读更多精彩内容