129 lines
2.2 KiB
Ruby
129 lines
2.2 KiB
Ruby
|
require 'postgres_msf'
|
||
|
require 'postgres/byteorder'
|
||
|
|
||
|
# Namespace for Metasploit branch.
|
||
|
module Msf
|
||
|
module Db
|
||
|
|
||
|
# This mixin solely depends on method read(n), which must be defined
|
||
|
# in the class/module where you mixin this module.
|
||
|
module BinaryReaderMixin
|
||
|
|
||
|
# == 8 bit
|
||
|
|
||
|
# no byteorder for 8 bit!
|
||
|
|
||
|
def read_word8
|
||
|
ru(1, 'C')
|
||
|
end
|
||
|
|
||
|
def read_int8
|
||
|
ru(1, 'c')
|
||
|
end
|
||
|
|
||
|
alias read_byte read_word8
|
||
|
|
||
|
# == 16 bit
|
||
|
|
||
|
# === Unsigned
|
||
|
|
||
|
def read_word16_native
|
||
|
ru(2, 'S')
|
||
|
end
|
||
|
|
||
|
def read_word16_little
|
||
|
ru(2, 'v')
|
||
|
end
|
||
|
|
||
|
def read_word16_big
|
||
|
ru(2, 'n')
|
||
|
end
|
||
|
|
||
|
# === Signed
|
||
|
|
||
|
def read_int16_native
|
||
|
ru(2, 's')
|
||
|
end
|
||
|
|
||
|
def read_int16_little
|
||
|
# swap bytes if native=big (but we want little)
|
||
|
ru_swap(2, 's', ByteOrder::Big)
|
||
|
end
|
||
|
|
||
|
def read_int16_big
|
||
|
# swap bytes if native=little (but we want big)
|
||
|
ru_swap(2, 's', ByteOrder::Little)
|
||
|
end
|
||
|
|
||
|
# == 32 bit
|
||
|
|
||
|
# === Unsigned
|
||
|
|
||
|
def read_word32_native
|
||
|
ru(4, 'L')
|
||
|
end
|
||
|
|
||
|
def read_word32_little
|
||
|
ru(4, 'V')
|
||
|
end
|
||
|
|
||
|
def read_word32_big
|
||
|
ru(4, 'N')
|
||
|
end
|
||
|
|
||
|
# === Signed
|
||
|
|
||
|
def read_int32_native
|
||
|
ru(4, 'l')
|
||
|
end
|
||
|
|
||
|
def read_int32_little
|
||
|
# swap bytes if native=big (but we want little)
|
||
|
ru_swap(4, 'l', ByteOrder::Big)
|
||
|
end
|
||
|
|
||
|
def read_int32_big
|
||
|
# swap bytes if native=little (but we want big)
|
||
|
ru_swap(4, 'l', ByteOrder::Little)
|
||
|
end
|
||
|
|
||
|
# == Aliases
|
||
|
|
||
|
alias read_uint8 read_word8
|
||
|
|
||
|
# add some short-cut functions
|
||
|
%w(word16 int16 word32 int32).each do |typ|
|
||
|
alias_method "read_#{typ}_network", "read_#{typ}_big"
|
||
|
end
|
||
|
|
||
|
{:word16 => :uint16, :word32 => :uint32}.each do |old, new|
|
||
|
['_native', '_little', '_big', '_network'].each do |bo|
|
||
|
alias_method "read_#{new}#{bo}", "read_#{old}#{bo}"
|
||
|
end
|
||
|
end
|
||
|
|
||
|
# read exactly n characters, otherwise raise an exception.
|
||
|
def readn(n)
|
||
|
str = read(n)
|
||
|
raise "couldn't read #{n} characters" if str.nil? or str.size != n
|
||
|
str
|
||
|
end
|
||
|
|
||
|
private
|
||
|
|
||
|
# shortcut method for readn+unpack
|
||
|
def ru(size, template)
|
||
|
readn(size).unpack(template).first
|
||
|
end
|
||
|
|
||
|
# same as method +ru+, but swap bytes if native byteorder == _byteorder_
|
||
|
def ru_swap(size, template, byteorder)
|
||
|
str = readn(size)
|
||
|
str.reverse! if ByteOrder.byteorder == byteorder
|
||
|
str.unpack(template).first
|
||
|
end
|
||
|
end
|
||
|
|
||
|
end
|
||
|
end
|