[Bro-Dev] BinPac: is there a way to get the length of decoded field?

Song oldpopsong at qq.com
Thu Nov 29 01:08:08 PST 2018


Hi,

I'm trying to write an analyzer for a protocol which uses Google Protocol Buffers for serialization. The request message MyProto_Req is like:

    <4 bytes indicating the length of the rest of the message>
    <Protobuf varint indicating the length of the REQUEST_HEADER>
    <REQUEST_HEADER data>
    <Protobuf varint indicating the length of the REQUEST_PARAMETER>
    <REQUEST_PARAMETER data>
    <optional data>

( You can find the Protobuf varint encoding here: https://developers.google.com/protocol-buffers/docs/encoding#varints )

Obviously the length of <optional data> must be calculated using previous length fields.

Below is my code:

type PBVarint = record {
        val_bytes      : uint8[] &until($element < 0x80);
} &let {
        val                : uint64 = varint_to_int64(val_bytes);
        my_len          : uint8 = varint_len(val_bytes);    # the length of this varint
};

function varint_to_int64(val_bytes: uint8[]) : uint64
        %{
        uint64 v = 0;

        for ( unsigned int i = 0; i < val_bytes->size(); ++i )
                {
                uint64 byte = ((*val_bytes)[i] & 0x7f);
                v |= byte << (8 * i);
                }

        return v;
        %}

function varint_len(val_bytes: uint8[]) : uint8
        %{
        return val_bytes->size();
        %}

type MyProto_Req = record {
        length              : uint32;
        len_reqHeader   : PBVarint;
        reqHeader         : bytestring &length = len_reqHeader.val;
        len_reqPara       : PBVarint;
        reqPara             : bytestring &length = len_reqPara.val;
        optionalData      : bytestring &length = (length - len_reqHeader.val - len_reqHeader.my_len - len_reqPara.val - len_reqPara.my_len);
};

It works. But I wonder if there is a better way to calcuate the length of optionalData (to kill the function varint_len()). I've tried:
        optionalData    : bytestring &length = (length - len_reqHeader.val - lenHeader.val_bytes->size() - len_reqPara.val - len_reqPara.val_bytes->size())
but failed.

Any hints?



More information about the bro-dev mailing list