vADC Docs

HowTo: Techniques for inspecting binary protocols

by on ‎02-24-2013 07:08 AM - edited on ‎06-11-2015 01:51 PM by PaulWallace (1,586 Views)

There are several TrafficScript functions that will help you to manage binary data. Here are some points that may help:

 

  • Strings in TrafficScript can contain binary data as well as ascii text. They are not null terminated, or limited in size.

 

  • You can use request.get( n ) to retrieve the first n bytes of the request data. Trafficscript Request rules are executed when Stingray receives the first request data; if Stingray has not received all n bytes, the request.get() function will block until the data is collected from the client.

request.getline( regex ) can be used instead; it will happily parse binary data, so if you can identify the end of your request with a regular expression, this may be suitable.

 

  • You can then use string.substring() to extract substrings from binary data.

 

The following functions may help to parse binary strings:

 

  • lang.ord( str ) returns the value of the first byte in str
  • lang.chr( i ) returns a 1-byte string with the value 'i'
  • string.intToBytes() and string.bytesToInt() convert between network-order byte strings and integers
  • string.BERToInt() and string.intToBER() converts variable length BER-encoded integers in byte strings to integers, and vice versa.

 

You can assemble a binary string using:

 

  • string.replaceBytes() does an in-place replacement
  • string.insertBytes() does an insertion

 

You can encode non-printable bytes in a string literal using octal escapes:

 

 

$str = "\123\047\110\077";  

 

There are also a range of functions that convert between different ASCII encodings of strings, such as hex, base64 and %-encoding, which may also be useful.

 

Example

 

Suppose that you have a protocol in which the request looks like the following:

 

<2-byte msg length><msg>

 

You wish to add a header to the msg and update the length in a request rule:

 

<2-byte msg length><header><msg>

 

The following TrafficScript rule may suffice:

 

# 1. calculate the length of the entire message:  
$len_str = request.get( 2 );             # read the 2-byte length  
$len = string.bytesToInt( $len_str, 2 ); # parse it  
  
# 2. read the entire message  
$msg = request.get( 2 + $len );  
  
# 3. Insert the header just after the length  
$msg = string.insertBytes( $msg, $header, 2 );  
  
# 4. Update the length  
$len = $len + string.len( $header );  
$len_str = string.intToBytes( $len );  
$msg = string.replaceBytes( $msg, $len_str, 0 );  
  
# 5. Change the request data  
request.set( $msg );  

 

Read more

 

Contributors