декомпиляция bin-файла protobufs-Net - PullRequest
1 голос
/ 24 октября 2019

У меня есть сериализованный bin-файл protobufs, написанный в основном в protobufs-net. Я хочу декомпилировать его и посмотреть его структуру.

Я использовал некоторые тулды, такие как: https://protogen.marcgravell.com/decode

, а также использовал protoc:

protoc --decode_raw < ~/Downloads/file.bin

и это часть результата, который я получаю:

1 {
  1: "4f81b7bb-d8bd-e911-9c1f-06ec640006bb"
  2: 0x404105b1663ef93a
  3: 0x4049c6158c593f36
  4: 0x40400000
  5 {
    1: "53f8afde-04c6-e811-910e-4622e9d1766e"
    2 {
      1: "e993fba0-8fc9-e811-9c15-06ec640006bb"
    }
    2 {
      1: "9a7c7210-3aca-e811-9c15-06ec640006bb"
      2: 1
    }
    2 {
      1: "2d7d12f1-2bc9-e811-9c15-06ec640006bb"
    }
    3: 18446744073709551615
  }
  6: 46
  7: 1571059279000
}

как я могу декомпилировать его? я хочу узнать структуру и изменить данные в ней и создать новый файл bin.

1 Ответ

3 голосов
/ 24 октября 2019

Обратный инжиниринг файла .proto - это, в основном, случай просмотра результатов инструментов, о которых вы упомянули, и попытки написать .proto, который выглядит аналогично. К сожалению, ряд понятий неоднозначен , если вы не знаете схему, поскольку несколько различных типов данных и форм имеют одинаковые детали кодирования, но ... мы можем догадываться.

Глядя на ваш вывод:

1 {
...
}

говорит нам, что наше корневое сообщение, вероятно, имеет под-сообщение в поле 1;так:

message Root {
    repeated Foo Foos = 1;
}

(я предполагаю, что repeated здесь; если 1 появляется только один раз, он может быть единичным)

со всем на следующем уровненаш Foo.

  1: "4f81b7bb-d8bd-e911-9c1f-06ec640006bb"
  2: 0x404105b1663ef93a
  3: 0x4049c6158c593f36
  4: 0x40400000
  5: { ... }
  6: 46,
  7: 1571059279000

похоже, что может быть

message Foo {
  string A = 1;
  sfixed64 B = 2;
  sfixed64 C = 3;
  sfixed32 D = 4;
  repeated Bar E = 5; // again, might not be "repeated" - see how many times it occurs
  int64 F = 6;
  int64 G = 7;
}

однако;эти sfixed64 могут быть double или fixed64;и эти sfixed32 могут быть fixed32 или float;аналогично, int64 может быть sint64 или uint64 - или int32, sint32, uint32 или bool, и я не смог бы сказать (все они просто "varint"). Каждый параметр дает различное значение значению!

наш Bar определенно имеет своего рода repeated, из-за всех 2:

    1: "53f8afde-04c6-e811-910e-4622e9d1766e"
    2 { ... }
    2 { ... }
    2 { ... }
    3: 18446744073709551615

догадаемся по:

message Bar {
  string A = 1;
  repeated Blap B = 2;
  int64 C = 3;
}

и, наконец, глядя на 2 из предыдущего бита, мы имеем:

      1: "e993fba0-8fc9-e811-9c15-06ec640006bb"

и

      1: "9a7c7210-3aca-e811-9c15-06ec640006bb"
      2: 1

и

      1: "2d7d12f1-2bc9-e811-9c15-06ec640006bb"

комбинируя их, мы можем догадаться:

message Blap {
    string A = 1;
    int64 B = 2;
}

В зависимости от того, есть ли у вас больше данных, могут быть дополнительные поля или вы можете вывести большеконтекст. Например, если значение int64, такое как Blap.B, равно всегда 1 или не указано, оно может фактически быть bool. Если один из элементов repeated всегда имеет самое большее одно значение, это может быть не repeated.

Хитрость заключается в том, чтобы играть с ними до тех пор, пока вы не сможете десериализовать данные, повторно сериализовать их и получите ту же полезную нагрузку (т.е. туда и обратно).

Как только вы получите , что : вы захотите десериализовать его, мутировать вещь васхотел изменить и сериализовать.

...