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?