Command line 用protoc和无模式对protobuf重新编码
我正在玩一个应用程序,并试图对它可以导出和导入的数据文件进行反向工程。这些文件是二进制的protobufs。我的目标是能够导出文件、转换为文本、使用其他数据记录对其进行修改、重新编码为二进制,并将其重新导入,以避免繁琐的手动数据输入应用程序。我在windows机器上使用了Command line 用protoc和无模式对protobuf重新编码,command-line,protocol-buffers,protoc,Command Line,Protocol Buffers,Protoc,我正在玩一个应用程序,并试图对它可以导出和导入的数据文件进行反向工程。这些文件是二进制的protobufs。我的目标是能够导出文件、转换为文本、使用其他数据记录对其进行修改、重新编码为二进制,并将其重新导入,以避免繁琐的手动数据输入应用程序。我在windows机器上使用了protoc二进制文件和--decode_raw,可以生成可读性很好的分层数据,而不知道实际使用的.proto模式。使用Marc Gravell的解析器会得到类似的结果(有些含糊不清的地方我不太明白)。我的问题如下: 是否有一种
protoc
二进制文件和--decode_raw
,可以生成可读性很好的分层数据,而不知道实际使用的.proto
模式。使用Marc Gravell的解析器会得到类似的结果(有些含糊不清的地方我不太明白)。我的问题如下:
protoc
或其他工具重新编码--decode_raw
的输出以生成原始二进制文件?我知道原始解码是在对未知模式进行假设,到目前为止,这些假设似乎可以产生可理解的结果。原始解码上是否有数据丢失,从而阻止重新编码为原始编码?难道仅仅是protoc
开发人员认为不需要这个功能吗?有了这个功能,我可以修改文本并重新编码,并且有机会生成有效的二进制文件.proto
文件和文本消息输入文件,使用protoc--encode
对原始二进制文件重新编码?我希望有一个指向示例文本文件的指针,可以用作protoc
的命令行输入,以便我学习所需的语法。我看到的示例内容似乎都是为了使用protoc
生成源代码。我测试的二进制protobufs已经解码为字符串、整数和一些十六进制值(我仍然需要破译),它们与应用程序中可见的数据很好地对应,因此我有信心,如果我看到工作示例,我可以生成所需的模式
1 {
1: "ThisItem:name1"
2 {
1: "name1"
2: <string>
4: <string>
5: 1
}
}
1 {
1: "ThisItem:name2"
2 {
1: "name2"
2: <string>
4: <string>
5: 1
}
}
1 {
1: "ThatItem:name1"
2 {
1: "name1"
3: <string>
5: <data structure>
8: <string>
}
}
1 {
1: "ThatItem:name2"
2 {
1: "name2"
3: <string>
5: <data structure>
8: <string>
}
}
1 {
1: "ThisItem:name3"
2 {
1: "name3"
2: <string>
4: <string>
5: 1
}
}
1 {
1:“此项:名称1”
2 {
1:“名称1”
2:
4:
5: 1
}
}
1 {
1:“此项:名称2”
2 {
1:“名称2”
2:
4:
5: 1
}
}
1 {
1:“该项目:名称1”
2 {
1:“名称1”
三:
5:
8:
}
}
1 {
1:“该项目:名称2”
2 {
1:“名称2”
三:
5:
8:
}
}
1 {
1:“此项:名称3”
2 {
1:“姓名3”
2:
4:
5: 1
}
}
因此,我看到了数据结构的几个特征:
syntax = "proto3";
message RecordList {
repeated Record records = 1;
}
message Record {
string id = 1;
ThisItem item = 2;
ThatItem item = 2; // Problem here, each record uses field 2, but with different message types.
// Each record has either a ThisItem or ThatItem. Parsing the id field could tell which,
// but that doesn't appear possible with protoc on the command line.
}
message ThisItem {
string id = 1;
string <element2> = 2;
string <element4> = 4;
int32 <element5> = 5;
}
message ThatItem {
string id = 1;
string <element3> = 3;
<message type> <element5> = 5;
string <element8> = 8;
}
syntax = "proto3";
message RecordList {
repeated Record records = 1;
}
message Record {
string id = 1;
ThisItem item = 2;
ThatItem item = 2; // Problem here, each record uses field 2, but with different message types.
// Each record has either a ThisItem or ThatItem. Parsing the id field could tell which,
// but that doesn't appear possible with protoc on the command line.
}
message ThisItem {
string id = 1;
string <element2> = 2;
string <element4> = 4;
int32 <element5> = 5;
}
message ThatItem {
string id = 1;
string <element3> = 3;
<message type> <element5> = 5;
string <element8> = 8;
}
syntax=“proto3”;
消息记录列表{
重复记录=1;
}
消息记录{
字符串id=1;
该项=2;
ThatItem=2;//这里的问题是,每条记录使用字段2,但消息类型不同。
//每个记录都有一个ThisItem或ThatItem。分析id字段可以知道是哪个,
//但在命令行上使用protoc时,这似乎是不可能的。
}
消息此项{
字符串id=1;
字符串=2;
字符串=4;
int32=5;
}
该项目的消息{
字符串id=1;
字符串=3;
= 5;
字符串=8;
}
因此,我不确定是否有方法在命令行上解码/编码此二进制文件。是否有一些语法可用于记录消息通过解析字段1中的字符串在字段2的两个可能选择之间切换?如果没有,我将需要在程序中读取和解析记录,这是我想要避免的
我意识到的另一种可能性是:我可以使用一个子消息并跳过未使用的字段,而不是两个不同的子消息ThisItem
和ThatItem
。子消息将在一种情况下填充字段1、2、4和5,在另一种情况下填充字段1、3、5和8。难度是字段5,即o中的整数1一个是ne,另一个是数据结构。我不知道如何管理它。整数1是空消息的二进制编码吗
谢谢你的帮助。让我看看是否能帮你回答这个问题 1.使用protoc重新编码
protoc--decode_raw
是一条死胡同,以后不能使用protoc进行编码。这是因为没有s
records {
id: "1"
item {
id: "1.1"
element2: "e2"
element4: "e4"
element5: 5
}
}
records {
id: "2"
item {
id: "2.1"
element2: "e2"
element4: "e4"
element5: 5
}
}
message Record {
string id = 1;
ThisItem item = 2;
ThatItem item = 2; // Problem here, each record uses field 2, but with different message types.
// Each record has either a ThisItem or ThatItem. Parsing the id field could tell which,
// but that doesn't appear possible with protoc on the command line.
}
message Record {
optional string id = 1;
oneof datafields {
bytes data = 2;
ThisItem thisitem = 3;
ThatItem thatitem= 4;
}
}
import myschema_pb2
from google.protobuf import text_format
### Read objects from PB and load into RecordList
mylist=myschema_pb2.RecordList()
f=open('objects.pb','rb')
mylist.ParseFromString(f.read())
f.close()
### Parse general data into ThisItem or ThatItem
for rec in mylist.records:
bin1 = rec.data
ss=rec.id
itemID=ss[0:ss.find(':')]
if itemID == 'ThisItem':
rec.thisitem.ParseFromString(rec.data) # parses data into thisitem and clears data
elif itemID == 'ThatItem':
rec.thatitem.ParseFromString(rec.data) # parses data into thatitem and clears data
else:
print('unknown')
### Generalize ThisItem and ThatItem into data
for rec in newlist.records:
ss=rec.id
itemID=ss[0:ss.find(':')]
if itemID == 'ThisItem':
rec.data=rec.thisitem.SerializeToString()
elif itemID == 'ThatItem':
rec.data=rec.thatitem.SerializeToString()
else:
print('unknown')