目录
1.设置BreakPoint,手动修改Multipart中的file
2.使用Map Remote将请求重定向到本地的服务器,然后修改file并重新发送到原始服务器
01 引言

先来欣赏一下~
不知道是哪位天才想出来的,能用微信相机来采集照片,此处不作过多评价。🤐
目前网络上流传的方法主要有:
- 使用Android模拟器的虚拟摄像头,此方法配置麻烦且不容易通过活体检测。
- Github大佬chimeElm开源的项目(点此跳转),原理是使用Python + Requests直接向上传图片的api接口请求。由于2024年3月小程序升级,此api需要携带wx.login()获取的登录code来校验身份,此方法貌似已失效。😅
本文尝试通过逆向解析小程序的源代码,看看具体的照片上传逻辑,并给出一个目前可用的上传方案(Charles抓包 + Map Remote + Multipart Encoder)。具体实现步骤可跳转到第三部分。
代码已在Github开源,欢迎点个Star:Little-King2022/jstc_pic_uploader: 在江苏图采微信小程序中上传自定义照片 (github.com)https://github.com/Little-King2022/jstc_pic_uploader
不管使用哪种方法,上传的照片都会经过系统检测和学校老师审核。所以一定要按照要求拍摄哦!否则有被审核老师退回的风险(检测不通过3次临时锁定,老师退回不会锁号)
阅读本文前,默认您已具有相关的知识和抓包、编程能力。一些简单的知识这里不再赘述,请自行搜索相关教程!!!
免责声明:仅供学习交流使用,请勿用于非法用途!!!
02 小程序源码解析
具体逆向方法自行寻找,此处直接上代码
1.页面结构
其中最主要的就是collect和camera页面。其他页面可忽略。
2.collect页面
由wxml源码可以看到,其实小程序也提供了直接从相册中选取的功能,只不过是学校设置了只能现场拍摄。这锅还得是学校背。
正常情况下,type===2,这就要求我们只能现场拍摄。只需将type设置为1或者3即可开启“相册选取”功能。
来看看对应的js代码是如何处理type值的~
可以看到是根据userInfo中collect_type数组来配置type的值。这里肯定是通过api获取的,Charles抓包看看,如下图~
因此,第一种方案就是Rewrite此response,将"collect_type"改为["photo", "draft"],或者改为["photo", "camera", "draft"],都是一样的效果。Charles中也提供了此功能,可以很方便的重写响应。具体步骤移步:Charles Rewrite功能-重写出入参https://blog.csdn.net/weixin_48520816/article/details/130871943
经测试,直接从相册中选取照片后,还需要进行人脸比对。因此这个方法仅适用于上传自己的照片。
3.camera页面
wxml没什么好看的,直接看js中是如何上传图片的~
可以看到,每次上传照片前都调用了wx.login(),小程序可以通过微信官方提供的登录能力方便地获取微信提供的用户身份标识。
- 调用 wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。
- 服务器端调用 auth.code2Session 接口,换取 用户唯一标识 OpenID 、 用户在微信开放平台账号下的唯一标识UnionID(若当前小程序已绑定到微信开放平台账号) 和 会话密钥 session_key。
之后开发者服务器可以根据用户标识来生成自定义登录态,用于后续业务逻辑中前后端交互时识别用户身份。
抓包看看request~
每次request都在表单中携带了code,并在Server中校验身份。该code由微信维护,无法伪造,这也导致了只能从小程序中获取到code之后,才能顺利地上传照片。
03 几个可行的解决思路
1.设置BreakPoint,手动修改Multipart中的file
Charles提供了BreakPoint断点调试功能,可以打断点拦截此request,手动修改Multipart中的file字段。具体步骤如下:
(1)小程序中跑一遍照片上传逻辑,抓到“/v2/camera/upload”包,然后选中该请求,勾选“Breakpoint”
(2)Proxy -> Breakpoint Settings -> 点击刚才这条url,进入设置
具体配置如下,只用勾选“Request”即可。
断点配置完成。
(3)在小程序中重新跑一遍照片上传逻辑
即可弹出断点页面,如下图,点击“Multipart”,只用修改这里的照片文件。
然后选中,右击Delete Part删除原来的file,右击add一个新的File Part,记得把name改成“file”才行。图片大小要小于3MB,否则有被waf拦截的风险!
(4)点击“Execute”执行请求
可以看到,小程序中的照片已经成功被替换了。
2.使用Map Remote将请求重定向到本地的服务器,然后修改file并重新发送到原始服务器
代码已放在Github:GitHub - Little-King2022/jstc_pic_uploader: 在江苏图采微信小程序中上传自定义照片
主要原理:Charles抓包,Map Remote到本地Flask服务器,使用Multipart Encoder修改multipart中的照片文件。
目前还未实现wx.login()的code自动获取。欢迎大佬在Github中提PR共同完善此项目!🫡
(1)配置Charles抓包
现在安卓系统越来越封闭,建议使用IOS/PC/MAC端配置好Charles抓包(Fiddler等工具也可以)。具体方法自行搜索,这里不再赘述。
配置好后,请先在小程序中跑一遍上传逻辑,确认可以正常抓到“jstxcj.91job.org.cn”的包
(2)修改并运行modify_multipart.py
请将程序中第40行的照片路径修改为你要上传的照片路径,然后运行:
pip3 install flask python3 /path/to/modify_multipart.py
(3)Charles中配置好Map Remote
在Charles中,Tools -> Map Remote -> Add,注意端口号和程序中保持一致,如果运行在本机,Map To的Host就填127.0.0.1。参考配置如下:
(4)在小程序中直接拍照吧~
你会惊讶地发现,照片会被成功替换!🥳
如果没有,控制台中将输出详细的错误信息,供你参考。如需帮助,请留言,或在此提交Issue。