iOS逆向实战三:修改微信钱包零钱

实现效果.gif

网上多数修改零钱是通过cycript修改,这种和reveal修改界面没什么区别,断开数据线或退出当前界面就没有了。要做到动态修改,就要分析来源,找出零钱是用了那个model的字段,然后写出tweak。
先吐槽下微信的代码,臃肿多又乱,新手不建议直接逆向微信。

1.先分析钱包和零钱界面,找到viewController

1.1 ssh root@localhost -p 2222(如果不是usb调试,请ssh到手机ip)->cycript -p WeChat->把keyWindow recursiveDescription写入文件

recursiveDescription写入文件有两个好处:一可避免cycript控制台显示不全,二避免cycript中文显示编码。

查找viewController-1

1.2 打开keyWindow.txt,直接搜索零钱,拿到零钱label地址0x18f79890

iOS逆向实战三:修改微信钱包零钱_第1张图片
搜索零钱

1.3通过nextResponder来找到当前的viewController

iOS逆向实战三:修改微信钱包零钱_第2张图片
nextResponder查找当前viewController

""就是当前viewController,可通过[#0x17c16200 setTitle:@"My Wallet"]修改标题来验证,也可以直接搜索你的余额,直接修改余额的值,这里就自行验证了。同理可得出零钱页面的WCPayBalanceDetailViewController。


iOS逆向实战三:修改微信钱包零钱_第3张图片
搜索余额

以上的结论是: WCBizMainViewController是钱包界面的viewController, WCPayBalanceDetailViewController是零钱界面的viewController。

2.分析WCBizMainViewController和WCPayBalanceDetailViewController

2.1 class-dump WeChat拿到头文件

我只直接把需要的头文件拖入XCode,方便分析


iOS逆向实战三:修改微信钱包零钱_第4张图片
头文件拖入XCode

2.2 先浏览下WCBizMainViewController的头文件

其中有两个refreshView的方法吸引了我。而且还是带参数的


iOS逆向实战三:修改微信钱包零钱_第5张图片
WCBizMainViewController头文件分析

2.3先分析refreshViewWithMallControlData方法,找出(id)arg1是什么

2.3.1 LLDB调试
iOS逆向实战三:修改微信钱包零钱_第6张图片
WeChat当前的偏移地址

0x00002000就是WeChat偏移的地址

2.3.2 使用IDA找到refreshViewWithMallControlData函数偏移的地址
iOS逆向实战三:修改微信钱包零钱_第7张图片
搜索refreshViewWithMallControlData

搜索refreshViewWithMallControlData结果
2.3.3 设置断点并打印参数

r0是当前控制器,r1是当前函数,r2是函数的第一个参数

iOS逆向实战三:修改微信钱包零钱_第8张图片
打印arg1参数

WCMallControlData是refreshViewWithMallControlData的参数

2.3.4分析WCMallControlData数据
2.3.4.1打开WCMallControlData.h

iOS逆向实战三:修改微信钱包零钱_第9张图片
WCMallControlData.h

一眼看去,变量不是很多,但每个变量表示什么?
打开微信进入钱包页->cycript -p WeChat->choose(WCMallControlData),一个一个变量查看吧,或者觉得那个变量是符合的,打印出来。
iOS逆向实战三:修改微信钱包零钱_第10张图片
cycript -p WeChat

打印第二个时候的显示了很多,看着像是配置信息,把\U转成中文。
这个可以放在.py中转换,需要用\u替换\U,否则python也解析不了。
iOS逆向实战三:修改微信钱包零钱_第11张图片
python转换中文

把.py拖入终端
iOS逆向实战三:修改微信钱包零钱_第12张图片
.py文件拖入终端

看到信用卡还款、微粒贷借钱、手机充值、理财通就知道这是腾讯服务这块了。还有icon_link,可以打开看看能不能对应上。

2.3.4.2分析WCPayControlData.h文件

WCPayControlData是refreshViewWithPayControlData的参数,可以用2.3的方法分析得出。我就不再赘述了。


iOS逆向实战三:修改微信钱包零钱_第13张图片
WCPayControlData.h

一看头文件,500多行,我是晕的,一个一个打印,得到后年马月吗,我是个懒人,当然还是要找方便的方法。再吐槽下,model全放一起,是为了管理方便吗?反正我没这么写过。

2.3.4.3 runtime打印WCPayControlData属性

为了省事和长久考虑,我决定尝试用runtime打印属性。下面是我的在网上找的方法,细节不赘述。遍历属性返回一个字典,然后写入手机路径/var/mobile/%@.txt

#import "NSObject+SimplePropertyLog.h"
#import 

@implementation NSObject (SimplePropertyLog)

- (void)writeToFileWithClass{
    //声明一个字典
    NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
    
    //得到当前class的所有属性
    uint count;
    objc_property_t *properties = class_copyPropertyList([self class], &count);
    
    //循环并用KVC得到每个属性的值
    for(int i = 0; i
iOS逆向实战三:修改微信钱包零钱_第14张图片
runtime打印WCPayControlData结果
2.3.4.4 结果分析

去除nil,去除0,剩下的分析就简单的多。我们可以按名称来排优先级.也发现一个规律,微信支付都是WCPay开头。如果你英文还可以,能看到WCPayLoanEntryInfo应该是贷款的,m_payApplyNewCardInfo支付信用卡的,

{
eCardControlData = "";
honeyPayData = "";
"m_arrBindedCard" = (
"",
"",
"",
"",
""
);
"m_f2fControlData" = "";
"m_loanEntryInfo" = "";
"m_payApplyNewCardInfo" = "";
"m_payMenuArrayInfo" = "";
"m_structBalanceInfo" = "";
"m_structLqtInfo" = "";
"m_structSwitchInfo" = "";
"m_structUserInfo" = "";
securityData = "";
transferMoneyData = "";
}

同样的方法,我分析了WCPayLQTInfo应该是零钱通,WCPayBalanceInfo就是我要找的余额。

iOS逆向实战三:修改微信钱包零钱_第15张图片
WCPayBalanceInfo字段分析

3.tweak编写

1.分析完了,就需要写tweak代码了。tweak的语法还是有点奇怪,和真正的OC还是有很多的不同,例如我Category中弹出UIAlertView就显示不出来。
2.其次model的属性需求声明,字段和.h model属性保持一致。勾住对应的类和方法就ok了。

@interface WCPayLqtCellInfo:NSObject
@property(retain, nonatomic) NSString *lqt_wording;
@end

@interface WCPayUserInfo:NSObject
@property(retain, nonatomic) WCPayLqtCellInfo *lqtCellInfo;
@end

//余额支付
@interface WCPayBalanceInfo:NSObject
@property(nonatomic) unsigned long long m_uiAvailableBalance;
@property(nonatomic) unsigned long long m_uiFetchBalance; // @synthesize m_uiFetchBalance;
@property(nonatomic) unsigned long long m_uiTotalBalance;
@end

@interface WCPayControlData:NSObject
@property(retain, nonatomic) WCPayTransferMoneyData *transferMoneyData; 
@property(retain, nonatomic) WCPayUserInfo *m_structUserInfo;
@property(retain, nonatomic) WCPaySwitchInfo *m_structSwitchInfo;
@property(retain, nonatomic) WCPayLQTInfo *m_structLqtInfo;
@property(retain, nonatomic) WCPayBalanceInfo *m_structBalanceInfo;
@property(retain, nonatomic) WCPayBindCardListApplyNewCardInfo *m_payApplyNewCardInfo;
@property(retain, nonatomic) WCPayPayMenuArrayInfo *m_payMenuArrayInfo;
@property(retain, nonatomic) WCPayLoanEntryInfo *m_loanEntryInfo;
@property(retain, nonatomic) WCPayF2FControlData *m_f2fControlData;
@property(retain, nonatomic) WCPayHoneyPayControlData *honeyPayData;
@end


@interface WCBizMainViewController:UIViewController

@end


static long long canUsingMoney = 80000000;

%hook WCBizMainViewController

- (void)viewWillAppear:(BOOL)arg1{
    %orig;
    self.title = @"My Wallet";
}

- (void)refreshViewWithPayControlData:(WCPayControlData *)arg1
{
    [arg1 writeToFileWithClass];
    arg1.m_structBalanceInfo.m_uiAvailableBalance = canUsingMoney;
    arg1.m_structBalanceInfo.m_uiTotalBalance = canUsingMoney;
    arg1.m_structBalanceInfo.m_uiFetchBalance = canUsingMoney;
    %orig;
}

%end

//微信
%hook WCPayBalanceDetailViewController

- (void)refreshViewWithData:(WCPayControlData *)arg1{
    arg1.m_structBalanceInfo.m_uiAvailableBalance = canUsingMoney;
    arg1.m_structBalanceInfo.m_uiTotalBalance = canUsingMoney;
    arg1.m_structBalanceInfo.m_uiFetchBalance = canUsingMoney;

    arg1.m_structUserInfo.lqtCellInfo.lqt_wording = @"¥1000000000";
    
    NSLog(@"WeChat:refreshViewWithData: %s,%@,",object_getClassName(arg1),arg1);
    %orig;
}

%end

总结:

1.分析完了,看似没什么难度,好像一切水到渠成,然而中间的磕磕碰碰只有自己能体会。费了一星期的时间,哈哈。分析的过程是痛苦的,就像在没有光的黑夜里行走,你不知道路在何方,当你得出结果时,就像黎明的曙光,一切都是值得的。
2.文中的方法不一定就是最优解,读者可自行考虑是否可以再优化。例如查看属性除了cycript -p和runtime打印,能不能再做优化,或者有更好的方式。
3.有任何问题欢迎留言交流。

iOS逆向实战一:实现按下home键截屏,如何使用hook的对象属性
iOS逆向实战二:微信聊天界面实现飘气球效果
iOS逆向实战三:修改微信钱包零钱
iOS逆向实战四:去优酷广告

你可能感兴趣的:(iOS逆向实战三:修改微信钱包零钱)