Class: Ronin::Support::Binary::Template

Inherits:
Object
  • Object
show all
Includes:
CTypes::Mixin
Defined in:
lib/ronin/support/binary/template.rb

Overview

Provides a translation layer between C-types and Ruby Array#pack codes.

Supported Types

  • :uint8 - unsigned 8-bit integer.
  • :uint16 - unsigned 16-bit integer.
  • :uint32 - unsigned 32-bit integer.
  • :uint64 - unsigned 64-bit integer.
  • :int8 - signed 8-bit integer.
  • :int16 - signed 16-bit integer.
  • :int32 - signed 32-bit integer.
  • :int64 - signed 64-bit integer.
  • :uchar - unsigned character.
  • :ushort - unsigned short integer, native endian.
  • :uint - unsigned integer, native endian.
  • :ulong - unsigned long integer, native endian.
  • :ulong_long - unsigned quad integer, native endian.
  • :char - signed character.
  • :short - signed short integer, native endian.
  • :int - signed integer, native endian.
  • :long - signed long integer, native endian.
  • :long_long - signed quad integer, native endian.
  • :float - single-precision float, native format.
  • :double - double-precision float, native format.
  • :float_le - single-precision float, little endian.
  • :double_le - double-precision float, little endian.
  • :float_be - single-precision float, big endian.
  • :double_be - double-precision float, big endian.
  • :byte - signed byte.
  • :string - binary String, \0 terminated.
  • :uint16_le - unsigned 16-bit integer, little endian.
  • :uint32_le - unsigned 32-bit integer, little endian.
  • :uint64_le - unsigned 64-bit integer, little endian.
  • :int16_le - signed 16-bit integer, little endian.
  • :int32_le - signed 32-bit integer, little endian.
  • :int64_le - signed 64-bit integer, little endian.
  • :uint16_be - unsigned 16-bit integer, big endian.
  • :uint32_be - unsigned 32-bit integer, big endian.
  • :uint64_be - unsigned 64-bit integer, big endian.
  • :int16_be - signed 16-bit integer, big endian.
  • :int32_be - signed 32-bit integer, big endian.
  • :int64_be - signed 64-bit integer, big endian.
  • :ushort_le - unsigned short integer, little endian.
  • :uint_le - unsigned integer, little endian.
  • :ulong_le - unsigned long integer, little endian.
  • :ulong_long_le - unsigned quad integer, little endian.
  • :short_le - signed short integer, little endian.
  • :int_le - signed integer, little endian.
  • :long_le - signed long integer, little endian.
  • :long_long_le - signed quad integer, little endian.
  • :ushort_be - unsigned short integer, little endian.
  • :uint_be - unsigned integer, little endian.
  • :ulong_be - unsigned long integer, little endian.
  • :ulong_long_be - unsigned quad integer, little endian.
  • :short_be - signed short integer, little endian.
  • :int_be - signed integer, little endian.
  • :long_be - signed long integer, little endian.
  • :long_long_be - signed quad integer, little endian.

Instance Attribute Summary collapse

Attributes included from CTypes::Mixin

#arch, #endian, #os, #type_resolver, #type_system

Class Method Summary collapse

Instance Method Summary collapse

Methods included from CTypes::Mixin

#initialize_type_system

Constructor Details

#initialize(fields, **kwargs) ⇒ Template

Creates a new Binary template.

The desired architecture for the values within the template.

The Operating System (OS) to use.

Examples:

template = Template.new([:uint32, [:char, 10]])
template.pack(0x123456, ['A', 'B', 'C'])
# => "CBA\x00XYZ\x00\x00\x00\x00\x00\x00\x00"
template.unpack("CBA\x00XYZ\x00\x00\x00\x00\x00\x00\x00")
# => [4276803, #<Ronin::Support::Binary::Array: "XYZ\x00\x00\x00\x00\x00\x00\x00">]

Parameters:

  • fields (::Array<Symbol, (Symbol, Integer)>)

    The C-types which the packer will use.

  • kwargs (Hash{Symbol => Object})

    Additional keyword arguments.

Options Hash (**kwargs):

  • :endian (:little, :big, :net, nil)

    The desired endianness of the values within the template.

  • :arch (:x86, :x86_64, :ppc, :ppc64, :mips, :mips_le, :mips_be, :mips64, :mips64_le, :mips64_be, :arm, :arm_le, :arm_be, :arm64, :arm64_le, :arm64_be)
  • :os (:linux, :macos, :windows, :android, :apple_ios, :bsd, :freebsd, :openbsd, :netbsd)

Raises:

  • (ArgumentError)

    A given type is not known.



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/ronin/support/binary/template.rb', line 150

def initialize(fields, **kwargs)
  initialize_type_system(**kwargs)

  @fields = []
  @types  = []

  @pack_string = String.new

  fields.each do |field|
    type = @type_resolver.resolve(field)

    @fields      << field
    @types       << type

    if @pack_string
      if type.pack_string then @pack_string << type.pack_string
      else                     @pack_string = nil
      end
    end
  end
end

Instance Attribute Details

#fields::Array<Symbol, (Symbol, Integer), Range(Symbol)> (readonly)

The fields of the binary template.

Returns:



97
98
99
# File 'lib/ronin/support/binary/template.rb', line 97

def fields
  @fields
end

#pack_stringString (readonly)

The Array#pack string for the binary template.

Returns:

Since:

  • 1.0.0



113
114
115
# File 'lib/ronin/support/binary/template.rb', line 113

def pack_string
  @pack_string
end

#types::Array<CTypes::Type, CTypes::ArrayType, CTypes::UnboundArrayType> (readonly)

The field types of the binary template.

Returns:

Since:

  • 1.0.0



106
107
108
# File 'lib/ronin/support/binary/template.rb', line 106

def types
  @types
end

Class Method Details

.[](*fields, **kwargs) ⇒ Template

Alias for Template.new.

The desired architecture for the values within the template.

The Operating System (OS) to use.

Examples:

template = Template[:uint32, [:char, 10]]
template.pack(0x123456, ['A', 'B', 'C'])
# => "CBA\x00XYZ\x00\x00\x00\x00\x00\x00\x00"
template.unpack("CBA\x00XYZ\x00\x00\x00\x00\x00\x00\x00")
# => [4276803, #<Ronin::Support::Binary::Array: "XYZ\x00\x00\x00\x00\x00\x00\x00">]

Parameters:

  • fields (::Array<Symbol, (Symbol, Integer)>)

    The C-types which the packer will use.

  • kwargs (Hash{Symbol => Object})

    Additional keyword arguments.

Options Hash (**kwargs):

  • :endian (:little, :big, :net, nil)

    The desired endianness of the values within the template.

  • :arch (:x86, :x86_64, :ppc, :ppc64, :mips, :mips_le, :mips_be, :mips64, :mips64_le, :mips64_be, :arm, :arm_le, :arm_be, :arm64, :arm64_le, :arm64_be)
  • :os (:linux, :macos, :windows, :android, :apple_ios, :bsd, :freebsd, :openbsd, :netbsd)

Returns:

  • (Template)

    The new template object.

Raises:

  • (ArgumentError)

    A given type is not known.

See Also:

Since:

  • 1.0.0



214
215
216
# File 'lib/ronin/support/binary/template.rb', line 214

def self.[](*fields,**kwargs)
  new(fields,**kwargs)
end

Instance Method Details

#pack(*arguments) ⇒ String

Packs the data.

Examples:

template = Template.new[:uint32, [:char, 10]]
template.pack(0x123456, ['A', 'B', 'C'])
# => "CBA\x00XYZ\x00\x00\x00\x00\x00\x00\x00"

Parameters:

  • arguments (::Array)

    The values to pack.

Returns:

  • (String)

    The packed data.



232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/ronin/support/binary/template.rb', line 232

def pack(*arguments)
  if @pack_string
    values = []

    @types.each do |type|
      # shift off the next value(s) and enqueue them
      type.enqueue_value(values,arguments.shift)
    end

    values.pack(@pack_string)
  else
    buffer = String.new

    @types.each do |type|
      # shift off the next value and pack it
      buffer << type.pack(arguments.shift)
    end

    return buffer
  end
end

#to_sString Also known as: to_str

Converts the template to a Array#pack template String.

Examples:

template = Template.new[:uint32, [:char, 10]]
template.to_s
# => "La10"

Returns:

  • (String)

    The template String.

See Also:



307
308
309
# File 'lib/ronin/support/binary/template.rb', line 307

def to_s
  @pack_string
end

#unpack(data) ⇒ ::Array

Unpacks the string.

Examples:

template = Template.new[:uint32, [:char, 10]]
template.unpack("CBA\x00XYZ\x00\x00\x00\x00\x00\x00\x00")
# => [4276803, #<Ronin::Support::Binary::Array: "XYZ\x00\x00\x00\x00\x00\x00\x00">]

Parameters:

  • data (String)

    The raw String to unpack.

Returns:



268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
# File 'lib/ronin/support/binary/template.rb', line 268

def unpack(data)
  if @pack_string
    values = data.unpack(@pack_string)

    @types.map do |type|
      type.dequeue_value(values)
    end
  else
    array  = []
    offset = 0

    @types.each do |type|
      slice = if type.size == Float::INFINITY
                data.byteslice(offset..)
              else
                data.byteslice(offset,type.size)
              end

      array  << type.unpack(slice)
      offset += type.size
    end

    return array
  end
end