找出 Profobuf 消息的类型(Google Chrome 同步)

Posted

技术标签:

【中文标题】找出 Profobuf 消息的类型(Google Chrome 同步)【英文标题】:Find out the type of a Profobuf message (Google Chrome Sync) 【发布时间】:2013-01-01 17:56:58 【问题描述】:

我正在尝试连接到 Google Chrome 同步(同步您的 Chrome 设置和您当前打开的标签)。 现在我专注于标签同步。我连接到 Google Talk 服务器,每当我在 Chrome 中导航到新网页时,都会收到来自 tango bot 的消息。

但是我很难解码这些消息,因为它们是用 Google 的 protobuf 格式编码的——因为有大量不同的 protobuf 类专用于 Chrome Sync,我认为没有办法确定二进制 protobuf 消息的类型?

典型的消息如下所示(base64 编码,XXXX't out my mail address):

CAAilQEKQAoGCgQIAxACEiUKBgoECAMQARISCZwF6dZYmkeFEXZLABNN3/yMGgcIhSwQAxgBINP80ri/JyoIMTgxOTgxMjYaUQpPCgwI7AcSB1NFU1NJT04QARiw64/I0se0AiIyVzpDaGZDeU9JWUZXdXFuUmRXaGtJWk94VkRSM1lmTGU1M0FoRGVxT2EwOHVQUHcyOD0wASoGCgQIAxACMAI4AUIrCG8SJxAEGAIiFGRlbHXXXXXXXXdAZ21haWwuY29tQgl0YW5nb19yYXdIAQ==

我尝试使用一些 protobuf 类(我为 Java 编译的)对其进行解码,但没有任何一个我得到任何有用的数据。

有没有人有关于这个话题的更多信息?关于如何找到正确的 protobuf 类来解码某个二进制消息的一些见解会很棒。它甚至会在某种程度上帮助我能够解码我作为上面示例给出的确切消息。 public documentation 很少,如果你不是 C++ 人,Chromium 源代码真的很难看... (如果这很重要,我正在使用 Java 进行开发)

【问题讨论】:

【参考方案1】:

是的,这在很大程度上是可能的;但是,它无法处理您发布的数据,因为您在尝试删除您的电子邮件地址时已经不可挽回地损坏了它。 Protobuf 对此非常敏感;我尝试将 XXXXXXXX 替换为 base-64 以获得 6 个字母的电子邮件地址,但紧接在此之前的字节是 199,并且 199 在那里不合法(紧接在字符串内容之前的数据是编码为的字符串的长度varint,并且 varint 永远不能以最后一个字节集的最高有效位结束,因为 MSB 是一个延续标志)。

如果你有原始的 protobuf 二进制文件,你可以尝试通过protoc --decode_raw 运行它,看看它说了什么;这可能足以让您开始重建布局。或者,您可以尝试使用首选实现的“阅读器”API(如果有的话)手动解析它。例如,使用 protobuf-net 和 ProtoReader,我能够拼凑起来(括号中的数字是 读取每个字段标题后的偏移量):


    (1) field 1: varint, value 0 if int
    (3) field 4: string, looks like sub-message
    // everything after this point is really really suspect
        (6) field 1, string, looks like sub-message
            (8) field 1, string, looks like sub-message
            (16) field 2, string, looks like sub-message
            (55) field 4, varint, 1357060030035 assuming int64
            (62) field 5, string; "18198126"
        (72) field 3, string, looks like sub-message
            (64) field 1, string, looks like some encoded session data
    (155) field 5: string, looks like sub-message
        (157) field 1: string, looks like sub-message
    (163) field 6: varint, value 2 if int
    (165) field 7: varint, value 1 if int
    (167) field 8: string, looks like sub-message
        (169) field 1: varint, value 111 if int
        (171) field 2: string, looks like sub-message

问题是由于损坏(由于您的替换),除了该字段 4 之外无法说太多;到那时,由于长度已关闭,一切都可能完全是胡言乱语。所以我对那一点没有信心。上面的主要观点只是为了说明:是的,你可以在不知道架构的情况下解析protobuf数据,对架构进行逆向工程——但它需要:

耐心和一点猜测来解释每个字段(每种线型可能意味着多种东西) 如果您知道存储的值是什么,而不必知道每个值如何映射到字段,那么您就有了先机;例如,如果您知道正在向您发送值 22、1325、“hello world”和 123.45F 的内容;那么你应该能够很容易地找出映射 完整的数据(遗憾的是在这种情况下丢失了)

【讨论】:

感谢您的回复,这对我帮助很大!我很抱歉破坏了数据,我意识到这有点太晚了。但是我能够使用 --decode_raw 标志对其进行解码,并且与您的解释很接近!现在我只需要在那个子子子消息噩梦中找到自己的方法……你知道当 protoc 无法解码消息时可能出了什么问题吗?因为我有一些其他的样本我无法通过它—— 但我还必须尝试使用​​偏移量,以防有一些自定义标题… @florianh 没有模式的解码既是一门科学,也是一门艺术;我可能需要查看它们,但首先想到的是:“一些自定义长度前缀格式,用于在单个流中分隔多个谨慎消息”

以上是关于找出 Profobuf 消息的类型(Google Chrome 同步)的主要内容,如果未能解决你的问题,请参考以下文章

google 的从 c# 到 java 的协议缓冲区 - 协议消息标签的线路类型无效

在 android 中找出 Mime 类型的默认应用程序

Google protobuf proto文件编写规则

类型 googlemaps index.d.ts 不是模块错误消息

有没有办法找出对象的类型(以字节数组形式)C++?

Akka 消息传递保证