07-2-theos实战: 给微信的"发现”界面增加2行功能

需求

  • 给微信的"发现”界面增加2行功能
    在这里插入图片描述

此教程所需要的工具/文件

  • class-dump
  • iTools
  • OpenSSH(Cydia)
  • iFile(Cydia)
  • Cycript(Cydia)
  • Reveal
  • dumpdecrypted
  • 一台越狱的iPhone

分析

  1. 找到 发现 界面的数据源
  2. 获取微信的脱壳的Mach-O文件
  3. class-dump 将Mach-O的头文件导出, 找到对应的头文件
  4. 用theos编写插件

1. 根据TableView找到它的数据源, 修改数据源方法

  • 主TableView: MMMainTableView
cy# #0x15e9bfa00.dataSource
#"delegate[0x15ea09e00], class[FindFriendEntryViewController]"

// 也就是当前的控制器
cy# MJFrontVc()
#"<FindFriendEntryViewController: 0x15ea09e00>"

在这里插入图片描述

2. 获取微信的脱壳的Mach-O文件

2.1 获取微信的存储路径

ps -A
  • 输出:
/var/containers/Bundle/Application/62F0E867-833E-44A6-8900-A3E98B303807/WeChat.app/WeChat
  • 通过iFunBox获取Mach-O文件
    在这里插入图片描述

2.2 查看Mach-O文件是否加密

 otool -l WeChat | grep crypt
  • 输出
     cryptoff 16384
    cryptsize 65617920
      cryptid 1

2.3 脱壳

DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/containers/Bundle/Application/62F0E867-833E-44A6-8900-A3E98B303807/WeChat.app/WeChat

在这里插入图片描述

  • 脱壳成功的文件在/var/root/下, 默认 xxx.decrypt, 验证是否脱壳成功
otool -l WeChat | grep crypt
  • 输出
     cryptoff 16384
    cryptsize 65617920
      cryptid 0
  • 脱壳成功,文件就是在 var/root/WeChat.decrypted

3. 用 class-dump 将Mach-O的头文件导出

class-dump -H WeChat -o Headers

4. 用theos编写插件

4.1 获取微信的bundle Id

cy# MJAppId
@"com.tencent.xin"

4.2 编写tweak文件

nic.pl

4.2.1 返回cell个数和cell内容

%hook FindFriendEntryViewController

// 一共多少组
- (long long)numberOfSectionsInTableView:(id)tableView {
	return %orig + 1;
}

// 每组多少行
- (long long)tableView:(id)tableView numberOfRowsInSection:(long long)section {

	if (section == [self numberOfSectionsInTableView:tableView] - 1) {
		return 2;
	} else {
		return %orig;
	}
}

// cell内容布局
- (id)tableView:(id)tableView cellForRowAtIndexPath:(id)indexPath {
	if ([indexPath section] != [self numberOfSectionsInTableView:tableView] - 1) {
		return %orig;
	}

	UITableViewCell *cell = [[UITableViewCell alloc] 
		initWithStyle:UITableViewCellStyleDefault 
		reuseIdentifier:nil];
	cell.backgroundColor = [UIColor whiteColor];
	cell.textLabel.text = @"666";
	return cell;
}

// 返回cell的高度
- (double)tableView:(id)tableView heightForRowAtIndexPath:(id)indexPath {
	if ([indexPath section] != [self numberOfSectionsInTableView:tableView] - 1) {
		return %orig;
	}

	return 44;
}

%end

4.2.2 界面调整和退出微信

// cell内容布局
- (id)tableView:(id)tableView cellForRowAtIndexPath:(id)indexPath {
	if ([indexPath section] != [self numberOfSectionsInTableView:tableView] - 1) {
		return %orig;
	}

	UITableViewCell *cell = nil;

	if ([indexPath row] == 0) {
		static NSString *autoCellId = @"autoCellId";
    	cell = [tableView dequeueReusableCellWithIdentifier:autoCellId];
	    if (cell == nil) {
	        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:autoCellId];
			cell.backgroundColor = [UIColor whiteColor];
	    }
	    cell.textLabel.text = @"自动抢红包";

	    UISwitch *s = [[UISwitch alloc] init];
		cell.accessoryView = s;

	} else if ([indexPath row] == 1) {
		static NSString *exitCellId = @"exitCellId";
    	cell = [tableView dequeueReusableCellWithIdentifier:exitCellId];
	    if (cell == nil) {
	        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:exitCellId];
			cell.backgroundColor = [UIColor whiteColor];
	    }
	    cell.textLabel.text = @"退出微信";
	}
	
	return cell;
}

// 选中cell
- (void)tableView:(id)tableView didSelectRowAtIndexPath:(id)indexPath {
	if ([indexPath section] != [self numberOfSectionsInTableView:tableView] - 1) {
		%orig;
		return;
	}

	[tableView deselectRowAtIndexPath:indexPath animated:YES];
	if ([indexPath row] == 1) {
		// exit(); // 这种方式有卡顿,不推荐
		abort(); // 终止进程, 使用这种方式退出无卡顿
	}
}

4.2.3 数据存储

#define ADUserDefaults [NSUserDefaults standardUserDefaults]
#define ADAutoKey @"ad_auto_key"

// switch按钮
UISwitch *switchView = [[UISwitch alloc] init];
    	[switchView addTarget:self action:@selector(valueChange:) forControlEvents:UIControlEventValueChanged];
    	switchView.on = [ADUserDefaults boolForKey:ADAutoKey];
		cell.accessoryView = switchView;

// 自动抢红包按钮打开/关闭(如果是新方法, 需要加上%new)
%new 
- (void)ad_valueChange:(UISwitch *)switchView {
    [ADUserDefaults setBool:switchView.isOn forKey:ADAutoKey];
    [ADUserDefaults synchronize];
}

4.2.4 加载图片资源

  • 新建一个layout文件夹,相当于手机的根文件夹,将文件放在手机的资源文件夹 /Library/PreferenceLoader/Preferences/, 并再新建一个XXApp文件夹,防止重名
  • 如果想让路径简单点,也可以放到缓存文件夹Library/Caches/
    在这里插入图片描述
    在这里插入图片描述
  • 加载图片代码
cell.imageView.image = [UIImage imageWithContentsOfFile:@"/Library/PreferenceLoader/Preferences/ADWeChat/AppIcon@2x.png"];
  • 重新安装插件
    在这里插入图片描述

4.2.5 宏定义资源路径

#define ADFile(path) @"/Library/PreferenceLoader/Preferences/ADWeChat/" #path

cell.imageView.image = [UIImage imageWithContentsOfFile:ADFile(AppIcon@2x.png)];

5. 最终代码


#define ADUserDefaults [NSUserDefaults standardUserDefaults]
#define ADAutoKey @"ad_auto_key"
#define ADFile(path) @"/Library/PreferenceLoader/Preferences/ADWeChat/" #path

%hook FindFriendEntryViewController

// 一共多少组
- (long long)numberOfSectionsInTableView:(id)tableView {
	return %orig + 1;
}

// 每组多少行
- (long long)tableView:(id)tableView numberOfRowsInSection:(long long)section {

	if (section == [self numberOfSectionsInTableView:tableView] - 1) {
		return 2;
	} else {
		return %orig;
	}
}

// cell内容布局
- (id)tableView:(id)tableView cellForRowAtIndexPath:(id)indexPath {
	if ([indexPath section] != [self numberOfSectionsInTableView:tableView] - 1) {
		return %orig;
	}

	static NSString *cellId = [indexPath row] == 0 ? @"autoCellId" : @"exitCellId";
	UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
		cell.backgroundColor = [UIColor whiteColor];
		cell.imageView.image = [UIImage imageWithContentsOfFile:ADFile(AppIcon@2x.png)];
    }

	if ([indexPath row] == 0) {
	    cell.textLabel.text = @"自动抢红包";

	    UISwitch *switchView = [[UISwitch alloc] init];
    	[switchView addTarget:self action:@selector(ad_valueChange:) forControlEvents:UIControlEventValueChanged];
    	switchView.on = [ADUserDefaults boolForKey:ADAutoKey];
		cell.accessoryView = switchView;
	} else if ([indexPath row] == 1) {
	    cell.textLabel.text = @"退出微信";
	}
	
	return cell;
}

// 自动抢红包按钮打开/关闭(如果是新方法, 需要加上%new)
%new 
- (void)ad_valueChange:(UISwitch *)switchView {
    [ADUserDefaults setBool:switchView.isOn forKey:ADAutoKey];
    [ADUserDefaults synchronize];
}

// 返回cell的高度
- (double)tableView:(id)tableView heightForRowAtIndexPath:(id)indexPath {
	if ([indexPath section] != [self numberOfSectionsInTableView:tableView] - 1) {
		return %orig;
	}

	return 44;
}

// 选中cell
- (void)tableView:(id)tableView didSelectRowAtIndexPath:(id)indexPath {
	if ([indexPath section] != [self numberOfSectionsInTableView:tableView] - 1) {
		%orig;
		return;
	}

	[tableView deselectRowAtIndexPath:indexPath animated:YES];
	if ([indexPath row] == 1) {
		// exit(); // 这种方式有卡顿,不推荐
		abort(); // 终止进程, 使用这种方式退出无卡顿
	}
}

%end
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值