module Rex::Encoder::XDR

This class implements basic XDR encoding.

Constants

MAX_ARG

Public Class Methods

decode!(buf, *data) click to toggle source

decode(buf, Integer, String, [Integer], [String]) does: [decode_int!(buf), decode_string!(buf),

decode_varray!(buf) { |i| XDR.decode_int!(i) },
decode_varray!(buf) { |s| XDR.decode_string(s) }]
# File lib/rex/encoder/xdr.rb, line 89
def XDR.decode!(buf, *data)
  return *data.collect do |var|
    if data.length == 0
    elsif var.kind_of?(Array) && var[0] == String
      decode_varray!(buf) { |s| XDR.decode_string!(s) }
    elsif var.kind_of?(Array) && var[0] == Integer
      decode_varray!(buf) { |i| XDR.decode_int!(i) }
    elsif var == String
      decode_string!(buf)
    elsif var == Integer
      decode_int!(buf)
    end
  end
end
decode_int!(data) click to toggle source
# File lib/rex/encoder/xdr.rb, line 17
def XDR.decode_int!(data)
    return data.slice!(0..3).unpack('N')[0] if data
    data = 0
end
decode_lchar!(data) click to toggle source
# File lib/rex/encoder/xdr.rb, line 27
def XDR.decode_lchar!(data)
  return (decode_int!(data) & 0xff).chr
end
decode_string!(data) click to toggle source
# File lib/rex/encoder/xdr.rb, line 39
def XDR.decode_string!(data)
  real_len = decode_int!(data)
  return "" if real_len == 0
  align_len = (real_len + 3) & ~3
  return data.slice!(0..align_len-1).slice(0..real_len-1)
end
decode_varray!(data) { |data| ... } click to toggle source
# File lib/rex/encoder/xdr.rb, line 51
def XDR.decode_varray!(data)
  buf = []
  1.upto(decode_int!(data)) { buf.push(yield(data)) }
  return buf
end
encode(*data) click to toggle source

encode(0, [0, 1], “foo”, [“bar”, 4]) does:

encode_int(0) +
encode_varray([0, 1]) { |i| XDR.encode_int(i) } +
encode_string("foo") +
encode_string("bar", 4)
# File lib/rex/encoder/xdr.rb, line 62
def XDR.encode(*data)
  data.collect do |var|
    if var.kind_of?(String)
      encode_string(var)
    elsif var.kind_of?(Integer)
      encode_int(var)
    elsif var.kind_of?(Array) && var[0].kind_of?(String)
      raise ArgumentError, 'XDR: Incorrect string array arguments' if var.length != 2
      encode_string(var[0], var[1])
    elsif var.kind_of?(Array) && var[0].kind_of?(Integer)
      encode_varray(var) { |i| XDR.encode_int(i) }
    # 0 means an empty array index in the case of Integer and an empty string in
    #   the case of String so we get the best of both worlds
    elsif var.kind_of?(Array) && var[0].nil?
      encode_int(0)
    else
      type = var.class
      type = var[0].class if var.kind_of?(Array)
      raise TypeError, "XDR: encode does not support #{type}"
    end
  end.join(nil)
end
encode_int(int) click to toggle source

Also: unsigned int, bool, enum

# File lib/rex/encoder/xdr.rb, line 13
def XDR.encode_int(int)
  return [int].pack('N')
end
encode_lchar(char) click to toggle source
# File lib/rex/encoder/xdr.rb, line 22
def XDR.encode_lchar(char)
  char |= 0xffffff00 if char & 0x80 != 0
  return encode_int(char)
end
encode_string(str, max=MAX_ARG) click to toggle source

Also: Variable length opaque

# File lib/rex/encoder/xdr.rb, line 32
def XDR.encode_string(str, max=MAX_ARG)
  raise ArgumentError, 'XDR: String too long' if str.length > max
  len = str.length
  str << "\x00" * ((4 - (len & 3)) & 3)
  return encode_int(len) + str
end
encode_varray(arr, max=MAX_ARG, &block) click to toggle source
# File lib/rex/encoder/xdr.rb, line 46
def XDR.encode_varray(arr, max=MAX_ARG, &block)
  raise ArgumentError, 'XDR: Too many array elements' if arr.length > max
  return encode_int(arr.length) + arr.collect(&block).join(nil)
end