APP爬虫之-Protobuf协议逆向解析

在做APP抓取时,会发现有的APP Response回来的数据有“加密”。不知道返回的内容是什么。

如下:

如上,内容不是明文的,没办法解析数据。APP常见的对数据加密有三种情况:第一种是,用诸如AES这类加密算法对数据加密,然后在APP里用key进行解密,这类的数据解密的难度不是很大,弄清楚是用的什么加密算法就能反解。
第二种是,用“私有”协议把数据序列化,只有了解该协议的细节才有可能把数据反序列化出来。这个的难度较大,没有功底,头发撸白都不一定撸出来。游戏和大厂APP盛行搞一个自己的私有协议来交换数据。

第三种是,用第三方厂商的协议来数据序列化,自己搞不出来私有协议的就选用第三方厂商的。比如用 Google 的 Protobuf ,来做数据序列化,也就是数据“加密”。
今天聊的就是第三种,Protobuf 的数据反解析。
先来看一个 Protobuf ,做数据序列化的直观例子。比如一个 APP 的 Response 原先是以 json 格式返回的:

这样很容易被解析,用Protobuf把上面数据序列化再传输就变成类似这样:
这张图片只是样例
这样就没法直接解析数据,如果了解 Protobuf 协议的话就能加快反解速度。所以还得从头来聊 Protobuf 。


一、什么是 Protobuf ?
Protobuf 是 Google 开发的一套数据存储传输协议,跟 xml 和 json 一样的,都是用来储存和传输数据的。 因为 Protobuf 能够把数据压缩得很小,所以传输数据就比 xml 和 json 快几倍,Protobuf 解析数据的速度也比它两快,所以在数据网络传输上,用 Protobuf 而不用 json 就有点受欢迎了。
不过 Protobuf 储存、压缩、传输效率比 json 好,付出的代价就是用法麻烦,不像 json.loads() json.dumps() 一下就搞定了这么简单。Protobuf 有一套自己的语法。不了解 Protobuf 协议语法和用法的话也无法反解数据。
先了解下 Protobuf 序列化和反序列化的整个流程:
1.1.先定义一个 Protobuf 语法文件( .proto 文件)
该语法文件用来说明要传输哪些字段、字段的数据类型、数据间的嵌套关系这些。比如一个APP要返回的数据有电话号码,姓名,年龄这三个字段,你就需要把这三个字段定义在 .proto 文件里,并且指明他们的数据类型,比如姓名和电话是字符串, 年龄是整型。
1.2.使用 Protobuf 提供的工具编译该语法文件。用工具编译 .proto 文件的目的是,把 .proto 文件编译成代码,工具会根据该 .proto 文件自动生产代码。 这个代码就是用来做数据序列化和反序列化的。

1.3.服务端用第2步中的代码,把“明文”数据序列化,变成“密文”后,返回给APP。
1.4. APP 客户端用第2步中的代码,把“密文”数据反序列化,就“解密”成明文拉。


理论说多了很迷糊,再整个完整的直观例子:
二、Protobuf 正向开发流程 

2.1.先配置 Protobuf 环境
https://github.com/protocolbuffers/protobuf/releases/在 Google 官方 github 地址下载 Protobuf  。
下载一个 Protobuf 编译器和一个调用编译器的接口程序,我们这里用Python版的。

如上图,箭头所示,解压 protoc.win64.zip 里有个 protoc 命令就是编译器。PS:注意要给 protoc 配置上环境变量,不然没法全局调用该命令。 
解压 protobuf-python-3.11.4.zip 这是Python模块,cd到python目录里运行 Python setup.py build 和 Python setup.py install 安装Python模块。

Python编辑器里运行 import google.protobuf 可以检测是否安装成功。
example目录里有官方写好的Python示例程序 和 示例 .proto文件。

2.2.写一个 .proto 语法文件
语法文件怎么写,要根据具体的传输数据来定制,比如按照 example 里的示例,如果要传输的数据是如下格式:


那么定义的 .proto 语法文件就如下:


这样就定义好了一个 .proto 语法文件,语法文件如何定义要根据传输数据的不同而变。
更全的 protobuf 语法 可以看这个,有网友翻译成了中文版的。https://colobu.com/2017/03/16/Protobuf3-language-guide/


2.3.使用第一步中下载的 protoc 编译器来编译 .proto 文件


protoc --python_out=. addressbook.proto

上述表示把 addressbook.proto 文件编译成Python版的。
如果文件语法错误,在编译的时候会有提示。编译完后,会多出一个.py文件

 


我们就可以调用这个 .py 来序列化上面的数据。

2.4.开始序列化数据

 


print里输出的就是序列化(“加密”)后的数据。

2.5.对序列化后的数据进行反序列化(“解密”)

 
反序列化就把数据又还原啦。


上述过程就是一个完整的正向数据 protobuf 序列化过程。我们可以看出来,主要是定义一个 .proto 文件,然后把它编译生成代码。 后面就主要用这个代码来做序列化和反序列化工作。


三、逆向解析 Protobuf
正向过程比较轻松,因为对方即有 .proto 文件,也有序列化代码,也知道要传输的数据样式。但是逆向这个过程,APP里是没有 .proto文件的,APP里是有反序列化的代码,但是看得也头晕。那该怎么办呢?
借助工具,我们使用上面下载的protoc编译工具,这个工具提供反解析参数

protoc --decode_raw < people.bin

如上,使用 --decode_raw 参数就能把序列化后的数据,反序列化(解密)出来。

上面只是把数据还原了,那如果我们要完全把 .proto 文件也还原出来该怎么办呢?

如果 APP 发送 request 的数据要先序列化后再发送给服务端的话,那爬虫要做的事情就不只反序列化,还要能序列化。
做序列化是一个正向的过程,按照上面流程,必须先要有 .proto 文件才行。所以继续还原 .proto 文件,还原 .proto 是个体力活和细致活。就是参照反解析出来的数据,还原出 .proto 文件。
 

 


上面这张图是关键,看懂了就能还原出来。上图左边是反解析出来的数据,中中间是参照左边写出来的 .proto 文件,右边是人家原本的 .proto 文件。
左边和中间图对比可以看出,就是根据左边的字段,挨个把字段重新定义出来就OK啦。遇到 "{" 就定义一个message。
中间和右边图对比可以看出,变量的名字是无关紧要的,数据类型还原正确就行。变量赋值的那些1,2,3是标识号,message里同一层级的标识号不能重复,一般是按照变量顺序从1开始递增。标识号的数字是个关键,数字写错了反解析出来的数据会不对。
这样就把 .proto 文件还原出来了,然后按照正向流程又去编译,就可以使用它去序列化(“加密”)和反序列化(“解密”)APP数据了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/54364.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

R语言绘图相关函数(含实例)

目录 plot:可用于创建多种类型的图形 dev.new():新建画板 hist&#xff1a;绘制直方图 dotchart&#xff1a;绘制点图的函数 pie:绘制饼图 pair&#xff1a;绘制散点图矩阵 boxplot&#xff1a;绘制箱线图 scatterplot3D&#xff1a; 绘制三维散点图 par&#xff1a;修…

【动态规划】1137. 第 N 个泰波那契数

Halo&#xff0c;这里是Ppeua。平时主要更新C&#xff0c;数据结构算法&#xff0c;Linux与ROS…感兴趣就关注我bua&#xff01; 文章目录 0. 题目解析1.算法原理1.1 状态表示1.2 状态转移方程1.3初始化1.4 填表顺序1.5 返回值 2.算法代码 &#x1f427; 本篇是整个动态规划的…

【八股】2023秋招八股复习笔记4(MySQL Redis等)

文章目录 目录1、MySQLmysql索引实现mysql索引优化mysql索引失效的情况mysql 千万数据优化mysql 事务隔离级别 & 实现原理mysql MVCC版本链&#xff08;undo log&#xff09;mysql数据同步机制 & 主从复制 &#xff08;binlog&#xff09;mysql 日志&数据恢复&…

Springboot开发所遇问题(持续更新)

SpringBoot特征&#xff1a; 1. SpringBoot Starter&#xff1a;他将常用的依赖分组进行了整合&#xff0c;将其合并到一个依赖中&#xff0c;这样就可以一次性添加到项目的Maven或Gradle构建中。 2,使编码变得简单&#xff0c;SpringBoot采用 JavaConfig的方式对Spring进行配置…

3D姿态相关的损失函数

loss_mpjpe: 计算预测3D关键点与真值之间的平均距离误差(MPJPE)。 loss_n_mpjpe: 计算去除尺度后预测3D关键点误差(N-MPJPE),评估结构误差。 loss_velocity: 计算3D关键点的速度/移动的误差,评估运动的平滑程度。 loss_limb_var: 计算肢体长度的方差,引导生成合理的肢体长度…

Redis通信协议

文章目录 Redis通信协议RESP协议数据类型 模拟Redis客户端 Redis通信协议 RESP协议 Redis是一个CS架构的软件&#xff0c;通信一般分为两步(不包含pipeline和PubSub)&#xff1a; 客户端(client)向服务端(server)发送一条命令。服务器解析并执行命令&#xff0c;返回响应结果…

Java面试题—2023年8月25日—PLKJ

2023年8月25日 北京 png ln kē j 答案仅供参考&#xff0c;博主仅记录发表&#xff0c;没有实际查询&#xff0c;不保证正确性。 面试题&#xff1a; 一.选择题 1.下面哪些是不合法的标识符 A.$persons B.TwoUsers C.*point D._endline 2. 下列语句执行后&#xff0c;k的值为…

Nginx 高级配置

目录 1 网页的状态页 2 Nginx 第三方模块 2.1 ehco 模块 3 变量 3.1 内置 3.2 定义变量 4 Nginx压缩功能 5 https 功能 6 自定义图标 1 网页的状态页 基于nginx 模块 ngx_http_stub_status_module 实现&#xff0c;在编译安装nginx的时候需要添加编译参数 --with-http…

Mysql with as定义子查询

文章目录 1. 定义2. 适用场景3. 语法4. 示例 1. 定义 使用with as 可以让子查询重用相同的with查询块&#xff0c; 并在select查询块中直接引用&#xff0c; 一般用在select查询块会多次使用某个查询sql时&#xff0c; 会把这个sql语句放在with as 中&#xff0c; 作为公用的表…

基于PaddleOCR2.7.0发布WebRest服务测试案例

基于PaddleOCR2.7.0发布WebRest服务测试案例 #WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. #警告&#xff1a;这是一个开发服务器。不要在生产部署中使用它。请改用生产WSGI服务器。 输出结果…

我的128天创作纪念日-东离与糖宝

文章目录 机缘收获日常成就憧憬 不知不觉我也迎来了自己的128天创作纪念日&#xff0c;一起来看看我有什么想对大家说的吧 机缘 我的写博客之旅始于参加了代码随想录算法训练营。在训练营期间&#xff0c;代码随想录作者卡尔建议我们坚持每天写博客记录刷题学习的进度和心得体…

K8s学习笔记3

Kubernetes功能&#xff1a; Kubernetes是一个轻便的可扩展的开源平台&#xff0c;用于管理容器化应用和服务。通过Kubernetes能够进行应用的自动化部署和扩缩容。在Kubernetes中&#xff0c;会将组成应用的容器组合成一个逻辑单元以更易管理和发现。Kubernetes积累了作为Goog…

【跟小嘉学 Rust 编程】十六、无畏并发(Fearless Concurrency)

系列文章目录 【跟小嘉学 Rust 编程】一、Rust 编程基础 【跟小嘉学 Rust 编程】二、Rust 包管理工具使用 【跟小嘉学 Rust 编程】三、Rust 的基本程序概念 【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念 【跟小嘉学 Rust 编程】五、使用结构体关联结构化数据 【跟小嘉学…

stm32之USART(总结)

串行通信 UART串口内部结构示意图 普中科技的详细介绍 中断知识补充 代码 #ifndef __USART_H #define __USART_H #include "stdio.h" #include "stm32f10x_usart.h" #define USART1_REC_LEN 200 //定义最大接收字节数 200extern u8 USART1_RX_BUF[US…

排序算法:希尔排序

1959 年 7 月&#xff0c;美国辛辛那提大学的数学系博士 Donald Shell 在 《ACM 通讯》上发表了希尔排序算法&#xff0c;成为首批将时间复杂度降到 O(n)以下的算法之一。虽然原始的希尔排序最坏时间复杂度仍然是 O(n) &#xff0c;但经过优化的希尔排序可以达到 O(n1.3)甚至O(…

飞天使-k8s基础组件分析-服务与ingress

文章目录 服务的介绍服务代理服务发现连接集群外服务服务发布无头服务 服务&#xff0c;pod和dns的关系端口转发通过expose 暴露应用服务案例INGRESSMetalLB使用参考文档 服务的介绍 服务的作用是啥&#xff1f; 提供外部调用&#xff0c;保证podip的真实性看看服务解决了什么…

深入理解 Go 语言中的 iota

iota是go语言的常量计数器&#xff0c;只能在常量表达式中使用&#xff0c;iota在const关键字出现时将被重置为0&#xff0c;const中每新增一行常量声明将使iota计数一次&#xff0c;可理解为const语句块中的行索引。它会自动递增&#xff0c;从0开始。 修改步长 尽管默认步长…

淘宝商品数据采集(如何快速获取淘宝商品信息),淘宝API接口申请指南

淘宝作为国内的电商平台&#xff0c;拥有海量的商品信息。对于想要进行淘宝商品数据采集的人来说&#xff0c;如何快速获取淘宝商品信息是一个重要的问题。本文将介绍一些快速获取淘宝商品信息的方法。 1. 使用淘宝开放平台PI 淘宝开放平台提供了多种PI接口&#xff0c;可以通…

五公里场地训练笔记(完整版)

由于考研和口罩等原因&#xff0c;停跑了比较长的时间。中长距离就是这样&#xff0c;修为尽失&#xff0c;大概是要从头开始了&#xff0c;不过还是要乐观的面对&#xff0c;CHEER UP&#xff01; 翻看咕咚软件&#xff0c;以前的PB是21&#xff1a;12&#xff0c;在2017年9月…

Flask 项目结构

前面我们了解了 Flask 框架的特性和一些用法&#xff0c;比如创建一个简单应用、做些页面&#xff0c;以及增加鉴权模块等&#xff0c;如果要将 Flask 用于实际项目开发&#xff0c;还需要了解一下 Flask 项目结构。 Flask 是一个轻量级的 Web 框架&#xff0c;扩展性强&#…