nccgroup / blackboxprotobuf

Blackbox Protobuf is a set of tools for working with encoded Protocol Buffers (protobuf) without the matching protobuf definition.
MIT License
516 stars 86 forks source link

encode_message error #29

Closed jdf159357 closed 10 months ago

jdf159357 commented 10 months ago

import blackboxprotobuf

hex_str = "20 0c" senddata = bytes.fromhex(hex_str)

deserialize_data, message_type = blackboxprotobuf.protobuf_to_json(senddata) print(deserialize_data) print(message_type)

deserialize_data = eval(deserialize_data) form_data = bytes(blackboxprotobuf.encode_message(deserialize_data, message_type)) print(form_data)

jdf159357 commented 10 months ago

{ "4": "12" } {'4': {'type': 'int', 'name': ''}} it should be int 12, not str "12",how to solve it by code

rwinkelmaier-ncc commented 10 months ago

Hi!

When I run the code against the latest version I'm getting

{
  "4": 12
}

Could you make sure you are using the bbpb package from pypi and not the blackboxprotobuf package?

Additionally, I would recommend against using eval for parsing the deserialized data. Since it's JSON data, you can do one of the following:

jdf159357 commented 10 months ago

Hi!

When I run the code against the latest version I'm getting

{
  "4": 12
}

Could you make sure you are using the bbpb package from pypi and not the blackboxprotobuf package?

Additionally, I would recommend against using eval for parsing the deserialized data. Since it's JSON data, you can do one of the following:

  • parse it with json.loads instead of eval
  • you can use protobuf_from_json instead of eval + encode_message, it will automatically do the json.loads
  • or if you don't need a string representation, you can skip JSON and use decode_message instead of protobuf_to_json.

Thank you for your reply! I did use the wrong package,Also I have another question

import blackboxprotobuf import json

hex_str = "1a 3b 0a 1b 09 ff e3 b2 c0 82 0a 93 40 11 00 00 50 d7 99 4e 5d 40 19 45 76 80 f3 79 8d 43 40 12 0f 0d 00 00 00 00 15 00 00 00 00 1d 00 00 00 00 1a 06 08 9b 03 10 a8 04 25 00 00 f0 41" senddata = bytes.fromhex(hex_str)

deserialize_data, message_type = blackboxprotobuf.protobuf_to_json(senddata) print(deserialize_data) print(message_type)

deserialize_data = json.loads(deserialize_data) form_data = bytes(blackboxprotobuf.encode_message(deserialize_data, message_type)) print(form_data)

I want decode result "1": { "1": 4653074396698829823, "2": 4637949613910786048, "3": 4630700396782843461 },

to "1": { "1": 1218.6276882125528, "2": 117.22813971340656, "3": 39.10528415463026 },

Can I do it automatically by code, or do I have to change the type manually? int to float

rwinkelmaier-ncc commented 10 months ago

There's a few ways you can do it:

  1. If you want all fixed64 fields to decode to a double by default, you can pass a Config object with a default_types to protobuf_to_json:

    from blackboxprotobuf.lib.types import wiretypes
    config = blackboxprotobuf.lib.config.Config()
    config.default_types[wiretypes.FIXED32] = 'float'
    config.default_types[wiretypes.FIXED64] = 'double'
    
    deserialize_data, message_type = blackboxprotobuf.protobuf_to_json(senddata, config=config)
  2. If you just want those specific fields to be decoded as a double, then you can define a type definition to pass into protobuf_to_json. Passing the type definition in tells bbpb to use a different decoder for that field instead of the default (you can also rename fields by adding a "name" attribute):

    message_type = {
       "3": {
           "type": "message",
           "message_typedef": {
               "1": {
                   "type": "message",
                   "message_typedef": {
                       "1": {
                           "type": "double"
                           },
                       "2": {
                           "type": "double"
                           },
                       "3": {
                           "type": "double"
                           }
                   }
               }
           }
       }
    }
    deserialize_data, message_type = blackboxprotobuf.protobuf_to_json(senddata, message_type)

    If you're going the typedef route, you can either hand craft the typedefs like above, or save and edit the message_type returned by protobuf_to_json. You can print to json with print(json.dumps(message_type, indent=4), edit the fields you want in a text editor, and then do a message_type = json.loads("...") or load from a file. Then pass the message_type that you created into protobuf_to_json.

jdf159357 commented 10 months ago

Thank you very much for your answer!