protobuf协议逆向解析
地址:
aHR0cHM6Ly93d3cudGlrdG9rLmNvbS9tZXNzYWdlcz9sYW5nPWVu
找到接口/v2/message/get_by_user_init
如图所示, 参数和响应并不是可直接使用的, 虽然部分内容可读。
跟栈到这里, 找到封包前的数据
打上断点, 查看变量t
就是请求参数, 经过encode
封包为二进制数据后 发送请求
把变量对象t
复制到一个json
格式化的地方, 方便后续查看
// 接收一个 ArrayBuffer, 转为base64字符串
window.arrayBufferToBase64 = function(buffer) {
let binary = '';
const bytes = new Uint8Array(buffer);
const len = bytes.byteLength;
for (let i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return window.btoa(binary);
}
把base64字符串复制到这里 => Protobuf Decoder (protobuf-decoder.netlify.app)
这是一个在线解析protobuf协议数据的网站, 如图
其实这里就可以还原数据结构了, 只是不知道这些字段的意义; 而刚刚的json数据就可以帮忙对比出它原本的字段名, 进而了解字段的大概意义.
下载protoc
编译器, 注意下载对应的系统版本, 下载地址这里: https://github.com/protocolbuffers/protobuf/releases/latest
下载后解压把bin
目录添加到系统环境中, 出现下面就算是成功了
然后开始准备构建.proto
文件数据结构
就可以大概推出下面这个数据结构
有的实在找不到对应的变量名, 你任意取一个名字也不影响, 你能懂就好
数据类型参考这里的表: 语言指南 (proto 3) |协议缓冲区文档 (protobuf.dev)
然后这里使用的是python的betterproto库, 比官方的好用多了.
pip install betterproto
使用编译命令
protoc -I . --python_betterproto_out=lib example.proto # 生成类
protoc
:这是 Protocol Buffers 编译器的命令行工具。-I .
:这个选项指定了编译器搜索.proto
文件的目录。-I
表示“include”,后面的点(.
)表示当前目录。所以,这个命令告诉protoc
只在当前目录下查找.proto
文件。--python_betterproto_out=lib
:这是编译器的一个输出选项,用于指定生成的代码应该放在哪个目录。--python_betterproto_out
是一个自定义的输出插件,它生成使用betterproto
库的 Python 代码。betterproto
是一个用于处理 Protocol Buffers 的 Python 库,它提供了更现代的 API 和一些额外的功能。lib
表示生成的代码应该放在名为lib
的目录中。example.proto
:这是要编译的 Protocol Buffers 定义文件的名称。有其他问题看官方文档: danielgtaylor/python-betterproto: Clean, modern, Python 3.6+ code generator & library for Protobuf 3 and async gRPC (github.com)
会生成两个文件, 其中一个里面会有下面这个类, 另一个应该是空的, 不用管
万事具备, 测试一下是否可用
import base64
from . import GetByUserInitRequest # 导入刚生成的类
base64_str = 'CMsBEJFOGgUxLjAuOSIAKAMwADofODY0MjQwZDpyZWxlYXNlLXdlYmFwcC0yMDI0MDQwOEIF2gwCCABKEzczNTcxODg0MDg3MjM1MDY3MThaA3dlYnoyCgdyZWZlcmVyEidodHRwczovL3d3dy50aWt0b2suY29tL21lc3NhZ2VzP2xhbmc9ZW56EgoKZnJvbV9hcHBJRBIEMTk4OHoSCgxhcHBfbGFuZ3VhZ2USAmVuehYKCGFwcF9uYW1lEgp0aWt0b2tfd2Vieg4KB2NoYW5uZWwSA3dlYnp9Cgp1c2VyX2FnZW50Em9Nb3ppbGxhLzUuMCAoV2luZG93cyBOVCAxMC4wOyBXaW42NDsgeDY0KSBBcHBsZVdlYktpdC81MzcuMzYgKEtIVE1MLCBsaWtlIEdlY2tvKSBDaHJvbWUvMTI0LjAuMC4wIFNhZmFyaS81MzcuMzZ6gAEKEFdlYi1TZGstTXMtVG9rZW4SbGhsUU1XRERwRkhfRlZWSXZGVVpxbFBaMmJJUGlyclJvSFJxWmhpbGE0ajB2ZjVqajRnZVVXbVd5NjAzbXVqVUdjQTlfQzhQVXpNM01GT1JDYWoxajR0Xzl4MTNkVUJoMHd6T3BTLV9CN2NVPZABAQ=='
print(GetByUserInitRequest().parse(base64.b64decode(base64_str)).to_json(indent=2))
能正常解析出所有数据就没什么问题
PS: 前面断点没注意, 不是同一个url😂,(本想以get_by_user_init
接口举例的, 但是断点那里的接口是get_by_user
) 但是思路是这么个思路
有更好更方便的方法欢迎指导