小谷秃头合集微信
今天又是接近逆向的一天~markdown
今天准备来个案例:在某信
的设置界面,注入UI
(为了之后的自动抢红包
来个前奏~)ide
首先咱们看下效果图post
不管是
正向
仍是逆向
开发,咱们写代码以前,都要缕一波思路:咱们的目的就是在设置界面增长UI
学习
上一篇博客已经说了
Monkey
和Logos
,咱们正好来用一波。测试
咱们使用的是8.0.2的微信包
。(固然你可使用最新的8.0.5
的,咱们应该是同样的)ui
WeChat
,运行Monkey
viewDebug
定位控制器的名称为:NewSettingViewController
WCTableView
,咱们要找到他的数据源(dataSource)
,因此咱们先看下能够知道:
datasource=<WCTableViewManager: 0x282ba8db0>
atom
class-dump
获取微信
的H文件
,sublime
打开以后寻找WCTableViewManager
WCTableViewManager
里面有section组
和tableView
的代理方法响应链条
,找到设置界面咱们已经找到了设置界面,能够经过
class-dump
.经过头文件查看他的方法spa
#import <UIKit/UIKit.h>
#define XGDefaults [NSUserDefaults standardUserDefaults]
#define XGSWITCHKEY @"XGSWITCHKEY"
#define XGTEXTKEY @"XGTEXTKEY"
@interface WCTableViewManager : NSObject
//在class-dump中的方法。我要调用,因此copy过来~
@property(retain, nonatomic) NSMutableArray *sections;
- (long long)numberOfSectionsInTableView:(UITableView *)tableView;
@end
//因为用到self,须要知道self的定位
@interface MMUIViewController : UIViewController
@end
@interface NewSettingViewController : MMUIViewController
@end
%hook WCTableViewManager
//要hook的方法~ 滑动时,键盘回收
- (void)scrollViewWillBeginDragging:(id)arg1{
%orig;
//肯定是在设置界面
if([MSHookIvar <UITableView *>(self,"_tableView").nextResponder.nextResponder isKindOfClass:%c(NewSettingViewController)]){
[MSHookIvar <UITableView *>(self,"_tableView") endEditing:YES];
}
}
//自定义textfield方法
%new
-(void)xg_textFieldDidChangeValue:(NSNotification *)notification{
UITextField *textField = (UITextField *)[notification object];
[XGDefaults setValue:textField.text forKey:XGTEXTKEY];
[XGDefaults synchronize];
[MSHookIvar <UITableView *>(self,"_tableView") reloadData];
}
//自定义switch开关方法
%new
-(void)xg_switchChang:(UISwitch *)switchView{
[XGDefaults setBool:switchView.isOn forKey:XGSWITCHKEY];
[XGDefaults synchronize];
[MSHookIvar <UITableView *>(self,"_tableView") reloadData];
}
//cell设置
- (id)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
// NSLog(@"indexPath:%ld,section:%ld",indexPath,[indexPath section]);
//若是在设置界面而且是最后一组。设置cell
if([tableView.nextResponder .nextResponder isKindOfClass:%c(NewSettingViewController)] && ([indexPath section] == [self numberOfSectionsInTableView:tableView]-1)){
UITableViewCell * cell = nil;
//笑脸UI SWICH开关
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 = [XGDefaults boolForKey:XGSWITCHKEY];
[switchView addTarget:self action:@selector(xg_switchChang:) forControlEvents:(UIControlEventValueChanged)];
cell.accessoryView = switchView;
cell.imageView.image = [UIImage imageNamed:([XGDefaults boolForKey:XGSWITCHKEY] == 1) ? @"unlocked" : @"locked"];
}else if([indexPath row] == 1){
static NSString * waitCell = @"UICELL";
cell = [tableView dequeueReusableCellWithIdentifier:waitCell];
if(!cell){
cell = [[UITableViewCell alloc] initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:nil];
}
cell.textLabel.text = @"增长个小UI!";
//首先设置一个输入框的大小
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 80, 30)];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(xg_textFieldDidChangeValue:) name:UITextFieldTextDidChangeNotification object:textField];
textField.text = [XGDefaults valueForKey:XGTEXTKEY];
//咱们经过class-dump中header能够知道,cell有一个- (void)setAccessoryView:(id)arg1;方法
[cell setAccessoryView:textField];
cell.imageView.image = [UIImage imageNamed:@"1003_filled"];
}
cell.backgroundColor = [UIColor whiteColor];
return cell;
}else{
return %orig;
}
}
//每组有多少行
- (long long)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
//若是在设置界面而且是最后一组。增长2行
if([tableView.nextResponder .nextResponder isKindOfClass:%c(NewSettingViewController)] && (section == [self numberOfSectionsInTableView:tableView]-1)){
return 2;
}else{
return %orig;
}
}
// 多少组 .nextResponder .nextResponder
- (long long)numberOfSectionsInTableView:(UITableView *)tableView {
//能够判断是在设置界面
if([tableView.nextResponder .nextResponder isKindOfClass:%c(NewSettingViewController)]){
return %orig + 1;
}else{
return %orig;
}
}
//行高
- (double)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
//若是在设置界面而且是最后一组。设置行高~
if([tableView.nextResponder .nextResponder isKindOfClass:%c(NewSettingViewController)] && ([indexPath section] == [self numberOfSectionsInTableView:tableView]-1)){
return 44;
}else{
return %orig;
}
}
%end
//因为咱们增长了一个textfield控件,想象一下,键盘谈起的话,会遮挡视图因此咱们能够处理下(固然,能够能够不处理,只是个界面遮挡的问题,不过对于有点小小强迫症的我来讲,仍是要处理下)
//要作的2件事,,一、键盘谈起,tableview,上移!二、滑动tableview,键盘回收
%hook NewSettingViewController
//弹出
%new
- (void)xg_keyboardWillShow:(NSNotification *)notification{
UIView * view = self.view;
CGRect keyBoardRect=[notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
view.frame = CGRectMake(0, -keyBoardRect.size.height, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height );
}
//消失
%new
- (void)xg_keyboardWillHide:(NSNotification *)notification{
UIView * view = self.view;
view.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
}
// hook 方法,增长通知~
- (void)viewDidLoad{
%orig;
//监听键盘的弹出和消失
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(xg_keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(xg_keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
%end
复制代码
某信
有风险,慎触~ 😆3d
这篇博客主要是为自动抢红包
作个准备,要不一下代码太多兄弟研究的时候就很差预览了~
兄弟们要是试的话,用大号测试。到时候能够解封(因为有被封的风险)
咱们就是研究下他的技术,学习一下,因此没有什么问题的
此次注入UI没有写什么功能,因此比较简单些。最后,兄得们,我去加班了~ (公司总是下班以前来工做!!😿)