首页 > QQ技巧 > 微信iOS客户端任意地区修改实践

微信iOS客户端任意地区修改实践

时间:2017-06-11 14:20 作者:QQ地带 我要评论

0x01 准备
越狱手机一台 - 主要用于脱壳(32Bit 最佳,Hopper Disassembler能直接看伪代码)
Hopper Disassembler - 反编译工具,能够将二进制执行文件反编译出伪代码
ldid - 签名工具
chisel - LLDB 增强
class-dump - 导出可执行文件的 Header
dumpdecrypted - 脱壳工具
Clutch - 高级脱壳工具
theos - 越狱开发工具包,安装与配置可参考Theos 安装与配置
0x02 debugserver 与 LLDB
debugserver为LLDB服务端,接收LLDB所提供的命令,并且进行相应的执行。
 
获取 debugserver
debugserver 存放于 iPhone 设备上 /Developer/usr/bin 目录,如果没有,打开 Xcode 并捅一下手机就能安装上
通过 scp 或者其它任何手段复制到电脑上
处理 debugserver
保存以下 xml 并命名为 ent.xml
 
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">  
<plist version="1.0">  
<dict>  
    <key>com.apple.springboard.debugapplications</key>
    <true/>
    <key>get-task-allow</key>
    <true/>
    <key>task_for_pid-allow</key>
    <true/>
    <key>run-unsigned-code</key>
    <true/>
</dict>  
</plist>  
执行命令: ldid -Sent.xml debugserver
通过 scp 或者其它任何手段复制到设备 /usr/bin 目录下
并加上执行权限(chmod +x)
执行 debugserver 命令无报错即可
LLDB 连接 debugserver
打开微信客户端
通过ssh连接至设备,执行命令: debugserver *:6666 -a 'WeChat'
电脑中运行 LLDB 并执行命令: process connect connect://devcie_ip:6666
设备处于 process interrupted 状态,连接成功
补充知识
在进行 LLDB 调试之前需要了解一些概念:
 
基址:模块在内存中的起始地址
ASLR:虚拟内存起始地址与模块基地址的偏移量(通过 image list -o -f 查看)
因此:内存地址 = ASLR + 基址
 
Hopper Disassembler 进行静态分析中显示的都是基址,LLDB 操作的都是内存地址,因此要进行换算。
 
0x03 定位函数
数据提交时机
想要实现任意地区修改,首先要知道数据提交的时机,来 Hook 相关的方法修改提交的参数。观察微信客户端修改个人资料页,大概猜测出两种修改机制:
 
每修改一项信息,在 Pop 一个 ViewController 的时候提交数据保存
修改好所有的信息,在 Pop 回至 TopViewController 的时候提交数据保存
验证猜想也很简单,找多一台设备进行观察就可以了,结果猜想 2是正确的!
 
找出对应 Controller
打开个人信息页面并执行命令:process interrupt
执行命令 pviews 输出UI层级树,不难找出MMTableView及其内存地址
执行命令 presponder MMTableView内存地址 输出响应层级树,找出个人信息页面的 Controller 为 SettingMyProfileViewController
重复以上步骤找出地区选择页面的 Controller
找出相关方法
利用 dumpdecrypted 脱壳,再通过 class-dump Dump出所有 .h 文件(过程就不再赘述),要关注的是所有与 SettingMyProfileViewController 和 MMRegionPickerViewController 有关的 .h 文件。
 
其中发现 MMRegionPickerViewControllerDelegate-Protocol.h 文件,显然地区选择页面是通过Delegate回调的方式进行传值,并且在 SettingMyProfileViewController.h 文件中找到Delegate对应的方法,因此可以确定 SettingMyProfileViewController 就是实现了对应的Delegate,接受地区参数。
 
动态调试
既然已经基本上确定了参数传递的方法,那就可以通过 Hopper Disassembler + LLDB 进行开刀!
 
在 Hopper Disassembler 中直接搜索 SettingMyProfileViewController MMRegionPickerDidChoosRegion ,找出方法入口基址
根据ASLR与基址计算出内存地址,通过LLDB设置断点: br s -a 内存地址
 
选择任意地区触发断点
 
执行命令: po [$r2 class] 查看参数类型
 
执行命令: po $r2 查看参数值
 
根据输出,发现是 NSArray 类型!并且数组内元素分别为:语言类型、国家、地区。
 
因此关键方法和传递参数已经确定,只要对其进行 Hook 就能实现修改~
 
0x04 编写 Tweak
通过 theos 创建 Tweak 模板,编辑 Tweak.xm:
 
%hook MMRegionPickerViewController
 
- (void)viewDidLoad {
    %orig;
 
    [[self navigationItem] setRightBarButtonItem:[[UIBarButtonItem alloc] initWithTitle:@"自定义" style:UIBarButtonItemStylePlain target:self action:@selector(setCustomRegion)]];
}
 
%new
- (void)setCustomRegion {
    UIAlertView *alert = [[UIAlertView alloc] init];
    alert.alertViewStyle = UIAlertViewStyleLoginAndPasswordInput;
    alert.delegate = self;
    alert.title = @"设置自定义地区";
    [alert addButtonWithTitle:@"取消"];
    [alert addButtonWithTitle:@"确定"];
    [alert textFieldAtIndex:0].secureTextEntry = NO;
    [alert textFieldAtIndex:0].placeholder = @"国家";
    [alert textFieldAtIndex:0].keyboardType = UIKeyboardTypeDefault;
    [alert textFieldAtIndex:1].secureTextEntry = NO;
    [alert textFieldAtIndex:1].placeholder = @"地区";
    [alert textFieldAtIndex:1].keyboardType = UIKeyboardTypeDefault;
    [alert show];
}
 
%new
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    if (buttonIndex == 1) {
        NSString *country = [alertView textFieldAtIndex:0].text;
        NSString *province = [alertView textFieldAtIndex:1].text;
        [[self delegate] MMRegionPickerDidChoosRegion:@[@"", country, province]];
    }
}
 
%end
五、安装Tweak
编辑 Makefile 中 THEOS_DEVICE_IP 为设备IP
执行命令: make package install
 
查看效果

标签: 微信
顶一下
(0)
0%
踩一下
(0)
0%

Google提供的广告