分享一种针对uni-app相对通用的抓包方案
PART1,前言
近年来混合开发APP逐渐成为主流的开发模式,与传统的开发模式相比混合开发极大的提升了开发效率,同时跨平台的特性也降低了开发成本,一直以来混合开发被诟病的性能问题随着技术的发展也得到改善。技术的发展往往是一把双刃剑,混合开发模式的出现导致“一次编码,多端运行”变成了现实,除此之外混合开发的APP相比原生开发的APP逆向成本也有了一定提升,这就给了黑灰产足够的诱惑:低成本、难逆向。混合开发模式的出现和快速发展给了黑灰产、病毒木马可乘之机,为应对未来的威胁我们应该做好技术储备,目前市面主流的混合开发框架有三款:uni-app、React Native和Flutter,三款框架各有优劣,从成本而言uni-app可能是三款框架中最好上手、最快开发、支持最多平台的,同时抓包可以算是最常见的逆向手段,我便对几个用uni-app框架开发的APP进行分析,尝试寻求一种相对通用的抓包方案。
PART2,关于uni-app
概念
uni-app是什么?了解一种技术或者框架最好的渠道就是官网,从uni-app官网可得知“uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等多个平台”,简单翻译下uni-app就是一款使用Vue开发的一套代码多端运行的混合开发框架。
uni-app的优势
官网也介绍了uni-app的优势,其中大多数的优势React Native、Flutter等其他混合开发框架也具备,这里着重说几点uni-app与其他框架比较的优势:
1、uni-app实现真正意义上的“一套代码多端运行”,支持更多的平台,提升开发效率。
2、与Flutter相比,uni-app使用Vue进行开发无需学习新的语言,开发成本较低。
底层原理浅析

上图取自官网uni-app功能框架图,其实我们只需要关注native.js部分提及“使用JS直接调用IOS API”和“使用JS直接调用Android API”大致就可以了解uni-app的运行原理,uni-app在Android或IOS设备运行时从架构上可以分成视图层和逻辑层,其中视图层负责页面渲染,而逻辑层负责执行业务逻辑,最终业务逻辑的执行会直接调用Android或IOS的原生API实现,除此之外页面渲染最终也会利用原生UI组件。所谓一套源码多端运行,也是因为uni-app可以使用条件编译实现不同平台的特性编码。
如何逆向uni-app
关于如何逆向uni-app,正好赶上最近ChatGPT比较火,我也体验了一把号称ChatGPT同根同源的平替“Claude”,得到的答案如上图所示。从图中可以看出Claude建议从几个方面考虑如何逆向,由于我本人是开发出身所以看到第8条建议的时候内心是非常认同的,“阅读uniapp的开发文档与源码示例,可以得到官方提供的一些框架结构与说明信息”,其实之前通过官网我们已经大致清楚了uni-app的功能框架图,并且确定uni-app的逻辑实现最终是通过native.js直接调用Android或IOS的原生API实现。因此我们只需要对官方提供的源码示例(Demo)进行分析,必定会找到一些较为通用的逆向技巧,接下来便以Android为例开始一步步分析,获取一种针对uni-app较为通用的抓包方案。
PART3,抓包实战
加上官网下载的Demo,我的手里一共有三个apk,直接挂代理用BurpSuite等抓包工具抓包的话,毫无疑问三个都是抓包失败,并且另外两个apk是加固的,为了最快的达成目的,我直接逆向Demo一步步探索相对通用的抓包方案:
第一步,思路分析
简单看了下Demo,我脑海瞬间出现4种抓包方案:
1.暴力破解

还是看官网!从API介绍可以了解到,uni-app是通过uni.request(OBJECT)发起请求,并且从上图参数说明中可以看到一个用于验证ssl证书的参数“sslVerify”,所以理论上只要我们能够把这个参数修改为false,即可管不ssl证书验证,那么如何修改该参数呢?
上图为Demo的文件目录部分截图,我们可以从assets目录下找到uni-app的前端代码,所以我们可以通过修改对应的代码后二次打包关闭ssl证书验证,也可以通过定制系统将整个资源包替换来实现同样的功能,那是相当暴力!但是对加固的应用而言,相关代码是经过混淆保护的,很难定位关键代码,这种思路就不通用了。
2.更改网络安全配置
上图为官方Demo的安全配置文件,可以看出debug模式是同时信任系统证书和用户证书的,那么我们可以通过二次打包或者定制ROM对apk的manifest文件进行修改,将debuggable属性修改为true,当然我们也可以直接对安全配置文件进行修改,设置信任用户证书,但是这种思路可能无法覆盖全部的请求,并且逆向两个加固的apk看了下并没有安全配置文件,因此也是不通用的。
3.Hook bypass ssl pinning
通过Hook来破解证书钢钉,在原生APP逆向时是一个常见的思路,对于uni-app其实也是完全可行的,不过个人感觉既然能够Hook,没必要再借助BurpSuite等工具进行抓包了,于是没有进一步验证,但是理论上是绝对可行的,当然还一个主要的原因是许多应用都会检测代理,看起来这种思路也不是那么通用。
4.报文自吐
该思路也是本文接下来要分享的思路,其实很简单,就是通过逆向分析官方Demo,从而确定网络请求框架,然后对网络请求框架进行分析,确定Hook的关键函数,最后打印请求报文和响应报文。
第二步,顺藤摸瓜
使用Jadx打开官网Demo,待反编译完成后查看文件目录,可看到上图红框中对应的目录,基本可以判断uni-app所开发的APP是通过OkHttp这一框架实现网络请求,只不过对应的包名与OkHttp官方包名有所不同,猜测是为了适配uni-app做了一定的改动,但是万变不离其宗,整体的思路应该是相同的。
第三步,照猫画虎
OkHttp作为目前可以说是安卓开发最主流的网络通信框架,用起来也是比较简单的,其支持同步请求和异步请求两种方式,首先需要实例化一个OkHttpClient对象,OkHttpClient有两个构造方法,可以通过传入一个构建好的Builder来设置相关参数,也可以采取默认的构造方,这时候就可以设置不走代理、证书钢钉等配置。
然后构建一个Request对象,其实就是请求,结合最后获得的Response即可得到完整的网络报文。
接下来就是真正的请求了,无论是异步还是同步请求,都需要调用OkHttpClient对象的newCall(Request)方法,而newCall方法最终会调用RealCall的newRealCall方法获取到一个RealCall对象,异步请求对应RealCall的enqueue方法,而同步请求则对应execute方法,如果继续阅读OkHttp框架源码不难发现enqueue最终还是会回到execute,因此只关注该方法即可。
继续跟进getResponseWithInterceptorChain方法,我们可以看到这个方法会创建一个Interceptor的List,并且会向里添加一系列的元素,Interceptor是一个接口,所有的拦截器都要实现该接口,请记住这一点后面会用到。
最终通过chain.proceed(originalRequest)获取到Response对象,也就是响应对象。
再次回到本文的主题,如何抓包呢?所谓抓包其实就是对应用网络通信过程中的请求和响应报文进行截获,也就是前面提及到的Request和Response对象,只要能获取到这两个对象就可以实现相关报文的打印。
前面提及到所有的拦截器都会实现Interceptor接口,目前网上有很多自定义拦截器实现的抓包方案,frida提供了一个名为“registerClass”的api注册接口类,借助这个api可以方便的创建一个自定义拦截器,然后获取Request和Reponse对象。
如果不喜欢frida,非要用xposed实现呢?Xposed并未听说会支持注册接口,那么我么不妨换一种思路,我们的目的本质上是获取Request和Reponse对象,回顾OkHttpClient是如何使用的?其实完全可以对RealCall这个类的getResponseWithInterceptorChain方法进行Hook,通过反射获取到Request对象originalRequest,然后通过getResult获取到返回值,也就是Reponse对象,后面就是报文的打印了,网上可抄的案例很多。
前面其实已经分享了两种OkHttpClient的通用抓包方案:基于Frida、基于Xposed,那么对于uni-app的抓包来说也是小事一桩了,无非就是找到对应的目标类和目标方法即可,关键代码如下图所示:
第四步,大功告成
最后就是简单的验证了,通过验证官网Demo及手头另外两个加固的apk都是可以正常抓到报文的,所以理论上这算是一种针对uni-app相对通用的抓包方案,大功告成。
PART4,总结与展望
Ok,到此接近文章的尾声了,其实本文分享的内容也是比较简单的,无非就是官网资料对uni-app框架有一个初步的认识和了解,判断其业务逻辑最终还是由原生实现,进一步借助官方Demo确定网络请求框架后照葫芦画瓢根据OkHttpClient的通用抓包方案稍加改造即可实现对uni-app相对通用的抓包。
其实混合开发的APP必定会涉及原生与Web端的交互,因此无论是React Native、uni-app,还是Flutter都可以用类似的思路进行分析,比如RN的模块、Flutter的引擎层等等都可以成为我们开始逆向工作的下手点。
相关文章:
分享一种针对uni-app相对通用的抓包方案
PART1,前言 近年来混合开发APP逐渐成为主流的开发模式,与传统的开发模式相比混合开发极大的提升了开发效率,同时跨平台的特性也降低了开发成本,一直以来混合开发被诟病的性能问题随着技术的发展也得到改善。技术的发展往往是一把…...
【2023百度之星备赛】码蹄集 BD202301 公园(BFS求最短路)
题目 https://www.matiji.net/exam/brushquestion/1/4347/179CE77A7B772D15A8C00DD8198AAC74?from1 题目大意: 给定一个无向图,有两个人往同一个目的地走,分别消耗体力TE、FE。如果他们到某个点汇合了,然后一起走向目的地&…...
2022年下半年系统架构设计师真题(下午带答案)
试题一 (25分) 某电子商务公司拟升级其会员与促销管理系统,向用户提供个性化服务,提高用户的粘性。在项目立项之初,公司领导层一致认为本次升级的主要目标是提升会员管理方式的灵活性,由于当前用户规模不大,业务也相对…...
26、ADS瞬时波形仿真-TRANSIENT仿真(以共射放大器为例)
26、ADS瞬时波形仿真-TRANSIENT仿真(以共射放大器为例) 在本科期间,学习模电的时候总是要对各种三极管电路进行MULTISIM仿真,其实ADS具备相同的功能,而且对于射频电路,使用ADS进行仿真可以结合版图进行&am…...
【微服务部署】02-配置管理
文章目录 1.ConfigMap1.1 创建ConfigMap方式1.2 使用ConfigMap的方式1.3 ConfigMap使用要点建议 2 分布式配置中心解决方案2.1 什么时候选择配置中心2.2 Apollo配置中心系统的能力2.2.1 Apollo创建配置项目2.2.2 项目使用2.2.3 K8s中使用Apollo 1.ConfigMap ConfigMap是K8s提供…...
NTP时钟同步服务器
目录 一、什么是NTP? 二、计算机时间分类 三、NTP如何工作? 四、NTP时钟同步方式(linux) 五、时间同步实现软件(既是客户端软件也是服务端软件) 六、chrony时钟同步软件介绍 七、/etc/chrony.conf配置文件介…...
webassembly003 ggml GGML Tensor Library part-2 官方使用说明
https://github.com/ggerganov/whisper.cpp/tree/1.0.3 GGML Tensor Library 官方有一个函数使用说明,但是从初始版本就没修改过 : https://github1s.com/ggerganov/ggml/blob/master/include/ggml/ggml.h#L3-L173 This documentation is still a work in progres…...
ES主集群的优化参考点
因为流量比较大, 导致ES线程数飙高,cpu直往上窜,查询耗时增加,并传导给所有调用方,导致更大范围的延时。如何解决这个问题呢? ES负载不合理,热点问题严重。ES主集群一共有几十个节点࿰…...
全国范围内-二手房小区数据-2023-8月更新
收录融合去重多个平台数据:80万,仅供数字参考 数据纬度字段名注释枚举值基础信息id主键id:名称城市来源生成 md5值00001073838501125ec4473463ead9ccname名称瑞祥安文创园address地址(朝阳)双桥路东柳村口南口lng经度116.581903lat纬度39.89…...
第4章 循环变换
4.1 适配体系结构特征的关键技术 由于高级语言隐藏了底层硬件体系结构的大量细节,如果不经过优化直接将高级程序设计语言编写的程序部署在底层硬件上,往往无法充分利用底层硬件体系结构的处理能力。 算子融合不仅可以提…...
spring cloud使用git作为配置中心,git开启了双因子认证,如何写本地配置文件
问题 spring cloud使用git作为配置中心,git开启了双因子认证,死活认证不成功!!!!! 报错关键字 org.eclipse.jgit.api.errors.TransportException: https://git.qualink.com/zhaoxin15/sc-confi…...
JVM内存管理、内存分区:堆、方法区、虚拟机栈、本地方法栈、程序计数器
内存管理 内存分区 线程共享 堆 存放实例,字符串常量(直接引用),静态变量,线程分配缓冲区(TLAB线程私有)。垃圾收集器管理的区域 方法区 非堆,和堆相对的概念。存储已被虚拟机加载的…...
L1-047 装睡(Python实现) 测试点全过
题目 你永远叫不醒一个装睡的人 —— 但是通过分析一个人的呼吸频率和脉搏,你可以发现谁在装睡!医生告诉我们,正常人睡眠时的呼吸频率是每分钟15-20次,脉搏是每分钟50-70次。下面给定一系列人的呼吸频率与脉搏,请你找…...
Mysql优化原理分析
一、存储引擎 1.1 MyISAM 一张表生成三个文件 xxx.frm:存储表结构xxx.MYD:存储表数据xxx.MYI:存储表索引 索引文件和数据文件是分离的(非聚集) select * from t where t.col1 30; 先去t.MYI文件查找30对应的索引…...
软考高级系统架构设计师系列案例考点专题一:软件架构设计
软考高级系统架构设计师系列案例考点专题一:软件架构设计 一、考点梳理及精讲1.质量属性判断与质量属性效用树2.必备概念3.架构风格对比4.MVC架构5.J2EE架构6.面向服务的架构SOA7.企业服务总线ESB一、考点梳理及精讲 系统架构设计师方面的知识在案例分析中每年必考1~2题,并且…...
css实现垂直上下布局的两种常用方法
例子:将两个<span>元素在<div>内垂直居中放置. 方法一:使用 Flexbox 来实现。 在下面的示例中,我将为 <div> 元素添加样式,使其成为一个 Flex 容器,并使用 Flexbox 属性将其中的两个 <span>…...
【Jetpack】Navigation 导航组件 ⑤ ( NavigationUI 类使用 )
文章目录 一、NavigationUI 类简介二、NavigationUI 类使用流程1、创建 Fragment2、创建 NavigationGraph3、Activity 导入 NavHostFragment4、创建菜单5、Activity 界面开发 NavigationUI 的主要逻辑 ( 重点 )a、添加 Fragment 布局b、处理 Navigation 导航逻辑 ( 重点 )c、启…...
基于NAudio实现简单的音乐播放器
《测试.net开源音频库NAudio》介绍了使用NAudio实现音乐播放和录音的基本用法,本文基于NAudio的音乐播放功能实现简单的mp3音乐播放器程序,主要实现以下功能: 1)导入文件夹中的mp3音乐文件,直接导入多个mp3音乐文件…...
C++之“00000001“和“\x00\x00\x00\x01“用法区别(一百八十六)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…...
Java“魂牵”京东店铺所有商品数据接口,京东店铺所有商品API接口,京东API接口申请指南
要通过京东的API获取店铺所有商品数据,您可以使用京东开放平台提供的接口来实现。以下是一种使用Java编程语言实现的示例,展示如何通过京东开放平台API获取整店商品数据: 首先,确保您已注册成为京东开放平台的开发者,…...
树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...
windows系统MySQL安装文档
概览:本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容,为学习者提供全面的操作指导。关键要点包括: 解压 :下载完成后解压压缩包,得到MySQL 8.…...
