一、前言
之前刚刚分享了一篇破解支付宝自动生成付款二维码的文章,点我查看。这篇是对上一篇的补充,既然实现了支付宝的二维码生成,那么继续把微信的二维码生成搞定,把这个插件做的更完整一些。如果你只想随便看看破解思路,那直接看上面一篇就可以了,那篇思路比较清晰,容易看明白。
这次在破解过程中还是遇到了一些问题,我反编译的是微信6.6.7版本,可能遇到的两个最主要的问题就是:
1. 微信混淆的比支付宝要复杂的多,看反编译后的代码,大部分都是不相关的字符名称,看起来很费劲,而且用jadx反编译出来的代码,经常有错误的或者缺失的导航,直接go不过去,还需要去看相应的smali代码,找到正确的包名或者类的路径,是不是有更好的工具我不知道呢?
2. 我开始也是用DDMS的traceview去分析,但是感觉帮助不大,是不是我的分析思路不太对,因为像生成二维码这种需要网络异步操作的,我从traceview很难找准相应的发起和接收的方法,找一些点击事件倒还是很简单的。
有可能是我的分析方法不对路,如果论坛哪位大神看到了我下面的分析思路,有更简洁更好的方法希望能在留言中指点一下。
二、寻找突破口
其实经过了破解支付宝的过程,再去破解微信,还是有了不少的帮助的,比如你去对比一下微信和支付宝设置金额和备注,还有生成二维码的页面基本都是相似的,说明他们的流程基本也是相同的。所以还是先找到那两个最主要的操作页面,和上次的分析方法一样就不贴截图了,最后找到的是CollectMainUI(对应展示二维码页面)和CollectCreateQRCodeUI(对应设置金额和备注信息页面)。
一、CollectMainUI页面分析
先去看第一个页面CollectMainUI,其实有了上次的分析经验,我直接去找这个类有没有onActivityResult方法,也就是当你设置完金额和备注以后返回来时的回调,然后发现确实是有的:

从代码上看得出,标红框的代码应该就是设置以后返回的结果,每个字段的意义基本也都清晰,ftf_pay_url应该是二维码信息url,剩下的几个就是描述,金额,货币单位等等,然后这个case分支又调用了两个方法aoV和aCp,其中应该有一个是生成二维码的处理逻辑,先看aOv,它里面又会调用两个方法aCo和aCq:



中间的截图是aCo方法,可以看到第一处代码,有个this.hXM是个ImageView类型的变量,先去把显示的图像清空,然后第二处代码的变量hYj,还记得刚才说的onActivityResult吗,他是一个支付信息的URI,接着第三处代码调用了一个yF(String)的方法,返回的结果是一个Bitmap,赋值给了this.hYf变量,后面的代码又会调用刚才的ImageView(this.hXM)去把他显示出来,看到这里,其实基本就可以知道,这个肯定就是生成二维码图片,然后显示的逻辑操作了


如果你go到里面的方法去看看,就会知道他就是生成图像的工具类方法,有点类似之前支付宝分析中的按个辅助类,截图我就不贴了,我也没有仔细去看,反正已经找到地方了,但是还有一个问题,如果我们想使用这个方法的话,他的调用需要传递好几个参数,他们都是干什么的呢,会有哪些值呢?最简单的方法就是去hook一下这个方法,然后我们去操作生成二维码,调用的时候反射打印一下这个几个值,看看有没有规律可循,下面是写的一个hook的测试方法:

然后再看看打印结果是什么:

其中那个打了码的gf是从刚才说的yF方法中q.GF()这个调用获取的,为啥打码,因为他返回的是你的微信号。。。其他几个参数都没什么特别的,我们传0或者null就ok了。这里其实还有一个this.hYI我没有打印,因为他是一个内部类,用来下载图片用的,但是只有那个this.hYW为1时,才会用到,所以咱们使用的时候也直接传null就可以了。
总结一下CollectMainUI这个页面:
简单分析以后,知道了调用逻辑和支付宝相似,也找到了实际生成二维码图像的方法yF(String),实际内部调用的是com.tencent.mm.plugin.collect.b.b辅助类的a方法,有一堆参数,有用的没几个,那么这个页面就分析完毕了,剩下的我们就是要去寻找刚才那个二维码信息URI是如何在下一个页面生成的了。
二、CollectCreateQRCodeUI页面分析
这个页面,最主要还是要关注那个【确定】按钮点击后的逻辑,因为只有确定以后才真正的去请求二维码信息:

它实际处理的是一个内部类:CollectCreateQRCodeUI$3,直接看看onClick的处理吧:

从上到下,就是把金额double值做一下转换,然后一堆分支,很明显前两个都是toast警告你输入非法值,后两个调用哪个呢?方法都是一样的只不过参数不同,这里有两种办法来确定调用的哪个分支,我们看到其中那些红色的都是jadx反编译以后信息对不上的,你直接找不到源码对应的路径,所以可以去看smali代码,确定那些变量的意义,缺失的包名等等,或者咱们再来hook调用的那个方法,看看到底是哪一个,我就不贴代码了,这里直接说,就是最后一个分支。这个方法,第一个参数是new 了一个com.tencent.mm.plugin.collect.b.s类型的变量,这个需要go进去看一下:

我们先看构造函数,也就是代码块(1),没错,就是把你设置的金额和备注放到Map中,然后调用了一个F方法,这个方法明显是一个基类中的方法,你往上去找这个类的基类,就会找到,位置在com.tencent.mm.wallet_core_c.i,代码比较长:


里面还会调用一些方法,我也没去看,反正从这个函数大概的代码和注释上看,应该是把网络请求做了一些封装,然后我们再返回去看上一张图中的代码块(2),我在看到这个函数的时候,我就猜测它很可能是网络请求后回调结果的地方,到底是不是呢,hook看一下就知道了:


可以从结果上看到,返回的JSONObject里面的pay_url就是我们需要的二维码信息URI,那么这个类的作用也比较明显了,我觉得就是一个对二维码网络请求作封装的包装类,包装了请求的参数以及提供了请求结果的回调解析。那现在最最关键的问题就是,这个网络请求是在什么地方发出去的呢?毕竟我们如果知道发送请求的方法,就可以按照方法调用去构造参数,然后自己在插件中去请求了,然后我就在这里卡住了,最开始呢,我用traceview去找有没有可疑的地方,但是这种异步请求,我是没找到地方,也可能是方法不对路,没办法,只能再看看刚才说的onClick方法:

这种混淆很严重的代码看起来很枯燥,但是找不到地方也只能去看看这个方法的实现了,它内部简单处理了一下以后,最终调用的地方是:com.tencent.mm.wallet_core.d.i的a(l lVar, boolean z, int i)方法,


几个可疑的地方,第一个红框的q(lVal),进去看了一下,只是设置了几个变量而已,而且我hook方法验证了一下,应该都是空值,看来和他没关系,排除,第二个红框的变量this.eXG是个Dialog,当你设置好金额【确定】的时候就会走到这里弹出一个loading框等待网络请求返回,最后面的红框代码块(1),很可惜jadx反编译的有问题,看一下对应的smali代码:

原来这个dpP是com.tencent.mm.ab.o,那最后看一下它的a方法吧:

经过一些assert断言以后,实际调用了b方法,这个方法很长,我没仔细看,但是简单看过这个o类以后,基本可以知道他是把请求放到一个消息处理队列里面,然后一个个开始执行,所以实际调用发送请求的方法就是这里,你可以去按照a方法来构造调用,你也可以按照b方法来构造调用,都是一样的。
所以再来总结一下,设置好金额和备注后,将参数封装(使用的是com.tencent.mm.plugin.collect.b.s)成一个请求参数,然后将请求参数放到队列里等待执行(使用的是com.tencent.mm.ab.o),所以我们可以按照这个逻辑走早好参数,调用方法加入任务队列,然后hook com.tencent.mm.plugin.collect.b.s的回调方法。
三、总结
我破解的思路就是上面这样,不像支付宝那么思路清晰,微信混淆的很严重,而且目前算个半成品,只支持微信6.6.7版本,每个版本差异还是有的,所以别的版本还有问题,但是好在有了分析支付宝的经验,还是能够找到正确的地方来解决问题,最后XPosed hook相关的代码我就不贴出来了,都提交到github上了,地址不变
https://github.com/wayu002/AlipayQRHook,项目名称起得比较尴尬。。。本来没想破解微信的
- 文章2305
- 用户1336
- 访客11455720
没有努力,天份不代表什么。
MySQL 数据库优化
This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its de
免ROOT实现模拟点击任意位置
Mobaxterm终端神器
CreateProcessW要注意的细节问题
Autonomous NAT Traversal
【教程】win10 彻底卸载edge浏览器
eclipse工程基于Xposed的一个简单Hook
排名前5的开源在线机器学习
Mac OS最简单及(Karabiner)快捷键设置
发一款C++编写的麻将
VMware NAT端口映射外网访问虚拟机linux
独家发布最新可用My-AutoPost——wordpress 采集器