class Ronin::Support::Binary::Template
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.
@see rubydoc.info/stdlib/core/Array:pack
@api pbulic
Attributes
The fields of the binary template.
@return [::Array<Symbol, (Symbol, Integer
), Range(Symbol)>]
The ‘Array#pack` string for the binary template.
@return [String]
@since 1.0.0
The field types of the binary template.
@return [::Array<CTypes::Type,
CTypes::ArrayType, CTypes::UnboundArrayType>]
@since 1.0.0
Public Class Methods
Alias for ‘Template.new`.
@param [::Array<Symbol, (Symbol, Integer
)>] fields
The C-types which the packer will use.
@param [Hash{Symbol => Object}] kwargs
Additional keyword arguments.
@option kwargs [:little, :big, :net, nil] :endian
The desired endianness of the values within the template.
@option kwargs [: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] :arch The desired architecture for the values within the template.
@option kwargs [:linux, :macos, :windows,
:android, :apple_ios, :bsd, :freebsd, :openbsd, :netbsd] :os The Operating System (OS) to use.
@return [Template]
The new template object.
@raise [ArgumentError]
A given type is not known.
@example
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">]
@see initialize
@since 1.0.0
# File lib/ronin/support/binary/template.rb, line 214 def self.[](*fields,**kwargs) new(fields,**kwargs) end
Creates a new Binary
template.
@param [::Array<Symbol, (Symbol, Integer
)>] fields
The C-types which the packer will use.
@param [Hash{Symbol => Object}] kwargs
Additional keyword arguments.
@option kwargs [:little, :big, :net, nil] :endian
The desired endianness of the values within the template.
@option kwargs [: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] :arch The desired architecture for the values within the template.
@option kwargs [:linux, :macos, :windows,
:android, :apple_ios, :bsd, :freebsd, :openbsd, :netbsd] :os The Operating System (OS) to use.
@raise [ArgumentError]
A given type is not known.
@example
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">]
# 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
Public Instance Methods
Packs the data.
@param [::Array] arguments
The values to pack.
@return [String]
The packed data.
@example
template = Template.new[:uint32, [:char, 10]] template.pack(0x123456, ['A', 'B', 'C']) # => "CBA\x00XYZ\x00\x00\x00\x00\x00\x00\x00"
# 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
Converts the template to a ‘Array#pack` template String
.
@return [String]
The template String.
@example
template = Template.new[:uint32, [:char, 10]] template.to_s # => "La10"
@see rubydoc.info/stdlib/core/Array:pack
# File lib/ronin/support/binary/template.rb, line 307 def to_s @pack_string end
Unpacks the string.
@param [String] data
The raw String to unpack.
@return [::Array]
The unpacked data.
@example
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">]
# 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