在使用了一个学期的自动打卡之后,学校突然宣布停用原来的“我在校园”小程序(好像是合作期到了),改用“奕辅导”小程序。虽说程序改了,但是实现自动打卡的原理基本是不变的,所以这几天有空研究了一下这个新的小程序。

首先还是通过 Fiddler 抓包小程序的请求并进行分析,这个就不赘述了。打卡过程基本可以归纳为如下:

  • 用户通过微信登录小程序,小程序调用 wx.login 获取 jsCode,再将其作为参数发送请求 1,获取用户的 accessToken。其有效期为一星期左右。
  • 将 accessToken 作为参数,发送请求 2,获取用户今日打卡状态以及一个很重要的问卷 id(每个用户、每一天都有自己的一个问卷id)
  • 将问卷 id 拼接到 url 中,发送请求 3,获取今日问卷
  • 创建 json 格式的问卷答案,发送请求 4,提交问卷(完成打卡)

知道了大致流程之后,接下来就很简单了,写脚本模拟这个过程即可。

之前的小程序我是用 Python 写的,但语法始终用不习惯,这回就改用 JS 写了。请求头、请求参数和接口地址都是知道的,由于一天只需打卡一次,少了早中晚的时间段判断,所以逻辑上也比“我在校园”小程序简单得多。需要注意的就是创建问卷答案这一块,其实这里提交的 json 内容可以是固定的,毕竟每天的问卷内容不大可能更改,但由于中间(大概是 1 号的时候)确实修改了一次,所以谨慎起见还是要检验一下。问卷大概有 8 个子问题,每个子问题有一个 id,每天打卡的时候会先获取所有子问题的 id,与准备提交的 json 中的子问题 id 做比对,确认是完全一样之后才会提交问卷。

既然是自动打卡,肯定少不了 token 过期的问题。从请求返回的字段来看,accessToken 的有效期大概一星期,但实际上解包小程序之后发现只有六天。过期了怎么办呢?目前来说只有重新抓包,无法自动获取新的 token,因为这个 token 是发送带 jsCode 参数的请求获取的,jsCode 只有调用 wx.login 才能拿到,且是一次性的,脚本无法模拟这个过程。看了小程序源码之后发现似乎还提供了账密登录的方式,但小程序中未发现相关入口,应该是还在开发中的功能,或许后续可以作为一个实现自动登录、自动获取 token 的突破口。

顺便也记录一下小程序反编译的步骤(虽然反编译完没有特别大的收获):

1. 获取原始包

首先要拿到小程序的包,一开始用的安卓模拟器去拿,半天没搞定,还贼麻烦,后面发现 PC 微信不也有小程序的包吗?于是直接 PC 微信文件夹里面拿就行了。具体地址是在:wechat files/applet/wx+字母数字/数字/__APP__.wxapkg。可能 applet 文件夹中有很多个小程序文件夹,可以先清空一遍再打开小程序,就会自动重新生成文件夹了。当然也可以按日期排个序,排在最前面的就是了。

2. 解密原始包

__APP__.wxapkg 是加密的,不能直接解包,所以先用 UnpackMiniApp 解密。这时候会生成一个 wxapp 文件夹,里面有一个以小程序 id 命名的新的 wxapkg 文件

3. 解包

使用 wxappUnpacker 解包 wxapkg 文件。在 wxappUnpacker 文件夹下运行 node wuWxapkg.js wxapkg所在路径 即可。最终会在 wxapp 文件夹中输出小程序的源码文件夹。

4. 导入开发者工具

打开微信开发者工具,选择导入项目,选择对应文件夹,选择测试号。

最后是脚本的地址,有需要的自取。