科技打卡¶
本文探索在纯 windows 环境下的科技打卡方式
感谢大佬开源 ForeverHYX/ZJU-gdty-fake-run
科技打卡是违规行为,此文只用于分析 Windows 环境下的小程序协议分析,所有生成的打卡记录均已删除,并未真实计入打卡次数
模拟器崩溃¶
最初使用的是 MuMu 的 Android 12 环境,安装的浙大体艺版本为 2.9.6。下载入口只给了二维码,先解析二维码取得安装包,再在模拟器中安装。安装本身没有问题,启动约一秒就退出。
第一份崩溃日志:
FORTIFY: pthread_mutex_lock called on a destroyed mutex
SIGABRT
调用栈经过 com.security.shell.V5App。能确定的是:程序在启动阶段发生了本地代码错误,访问了已销毁的线程锁,随后被终止。
怀疑 ARM 代码在模拟器中的转译兼容性。
升级 Android 15¶
原来的 MuMu 5.30.1 只有 Android 12 实例,不能任意切换 Android 9、10、15。升级模拟器后,再用 Android 15 测试同一版本的浙大体艺,依然失败,而且日志多了一条关键线索:
No implementation found … com.security.shell.V5App$8.fr()
FORTIFY: pthread_mutex_lock called on a destroyed mutex
Fatal signal 6 (SIGABRT)
Android 15 实例涉及 64 位 ARM 运行情况,因此真实原因可能是启动保护模块在这套模拟器环境中初始化异常。
手机 & 雷电模拟器¶
手机端同样是 Android 15、浙大体艺 2.9.6,可以正常启动。
随后换用雷电的 Android 14 环境,重新复现并读取日志,仍然出现同一组 V5App、线程锁和 SIGABRT 错误。
| 环境 | 浙大体艺版本 | 当时结果 |
|---|---|---|
| MuMu / Android 12 | 2.9.6 | 启动后闪退 |
| MuMu / Android 15 | 2.9.6 | 本地方法加载失败,随后闪退 |
| 雷电 / Android 14 | 2.9.6 | 相同关键错误 |
| 安卓真机 / Android 15 | 2.9.6 | 正常运行 |
这说明问题不只发生在 MuMu,继续调整内存、分辨率或模拟手机型号也没有明确依据。V5App 与应用加固有关,公开资料支持把保护模块作为排查方向,但不能证明具体启用了哪一项反模拟器功能。
但是应该是有方法的,因为我看到过我同学使用(
电脑微信->企业咕咚¶
模拟器不行,但电脑微信能够打开「企业咕咚」小程序。两个思路具体如下:
| 思路 | 数据从哪里产生 | 本次结论 |
|---|---|---|
| 模拟器定位与界面自动化 | 改变安卓环境的位置,由应用记录与上传 | 浙大体艺在测试环境中无法启动,未验证后续流程 |
| 协议请求 | 本地程序构造运动数据,与服务端通信 | 实际使用 |
这次选用的开源项目是 ForeverHYX/ZJU-gdty-fake-run。先下载源码,安装隔离的 Python 环境与依赖,做语法检查和离线路线生成测试,再检查 Windows 登录流程。
登录¶
项目需要借助本地 HTTPS 调试代理,观察自己账号的小程序请求,取得临时登录凭据。这里同时涉及两件事:请求有没有经过调试代理,以及客户端是否信任调试代理的证书。
证书文件¶
测试流程问题:脚本异常退出时执行了清理,把还在下一轮测试中需要使用的证书删掉了。导致证书的重复导入。
修复后的测试流程把阶段分开:先准备代理与证书,核验信任状态,在同一轮重试中保留证书,等全部验证结束后再统一恢复代理和清理临时证书。
代理问题¶
多次刷新“我的/跑步记录”时,页面正常显示,但调试代理没有收到企业咕咚目标接口。
排查先后尝试了关闭重开小程序、彻底退出微信后重启、按进程观察网络连接,以及定位小程序的网络服务进程。旧连接可能继续沿用原来的路径,仅关闭小程序窗口不一定足够。
最后发现,当时已经开启的 Clash 占据了实际流量路径:企业咕咚走的是 Clash 的 7897 端口,绕开了先前准备的调试代理。
调整为代理串联后,终于能观察到企业咕咚的目标连接。随后修正目标过滤、异常恢复和旧连接处理,才完成登录凭据采集。
排查顺序:
- 确认请求属于哪个进程。
- 确认它实际连接到哪个代理端口。
- 确认目标连接进入调试代理。
- 再检查 TLS 证书与目标请求是否可读取。
- 最后通过只读查询验证凭据。
验证¶
登录问题解决后,使用准备好的紫金港路线进行一次完整验证。程序按实际时间推进,分批处理位置、步数和相关数据,再结束记录并关联轨迹图。
这不是瞬间完成的请求。当时约三公里的流程需要十几分钟,期间电脑必须保持唤醒、联网,进程也需要持续运行。
第一条完成记录的查询结果是:
| 项目 | 结果 |
|---|---|
| 轨迹点 | 198 个 |
| 距离 | 3.212 公里 |
| 时长 | 16 分 57 秒 |
| 本地累计步数 | 2,645 步 |
| 服务端保存步数 | 29,212 步 |
步数异常处理¶
对照上报序列和服务端结果后,问题可以直接用数字验证。
程序一共上报了 21 次步数,传入的是从开始到当前的累计值,例如 123、252、384……2645。服务端将每次收到的 cur_steps 作为本次新增量相加,这 21 个累计值之和恰好就是 29,212。
修复¶
本地修改保留两个不同用途的量:累计总数用于本地统计,每次请求只提交当前时段的 step_delta。上面的例子应当提交 120、120、120。
PR¶
修复后又进行了一次完整验证,随后只读查询服务端保存的记录,结果为:
| 项目 | 结果 |
|---|---|
| 距离 | 3.205 公里 |
| 时长 | 16 分 43 秒 |
| 本地上报总步数 | 2,586 步 |
| 服务端保存总步数 | 2,586 步 |
| 轨迹图 | 已关联 |
本地各段上报之和与服务端总步数一致。
整理后提交了 PR #2:修复步数重复累计。截至我写下这段话的时候,PR 已创建并等待维护者审查。
原项目缺少在 Windows 下的完整流程,正在考虑成熟后提交下一个 PR
排查经验¶
- 应用能安装、能打开、能登录、能上传、数据保存正确,是需要分别验证的几个阶段。
- 模拟器崩溃先看日志。
V5App、本地方法加载失败和线程锁错误可以作为排查的证据 - 网络问题先确认请求实际经过哪里。已有的代理和旧连接,会让“系统代理已修改”与“目标请求真实链接”出现差异。
- 证书的准备、核验、重试和清理要形成明确生命周期。过早清理会破坏后续测试条件。
- 对累计字段,必须核对服务端保存值。界面上打印的本地总数不能替代查询结果。
评论