module TurboRex::CStruct

Constants

NON_FALLBACK_METHODS

Public Class Methods

new(receiver, fallback) click to toggle source
Calls superclass method
# File lib/turborex/cstruct.rb, line 20
def initialize(receiver, fallback)
  @__receiver__ = receiver
  @__fallback__ = fallback

  # Enables calling DSL methods from helper methods in the block's context
  unless fallback.respond_to?(:method_missing)
    # NOTE: There's no {#define_singleton_method} on Ruby 1.8.x
    singleton_class = (
    class << fallback;
      self;
    end)

    # instrument {#method_missing} on the block's context to fallback to
    # the DSL object. This allows helper methods in the block's context to
    # contain calls to methods on the DSL object.
    singleton_class.
        send(:define_method, :method_missing) do |method, *args, &block|
      m = method.to_sym
      if !NON_FALLBACK_METHODS.include?(m) && !fallback.respond_to?(m) && receiver.respond_to?(m) || receiver.respond_to?(:method_missing)
        receiver.__send__(method.to_sym, *args, &block)
      else
        super(method, *args, &block)
      end
    end

    # instrument a helper method to remove the above instrumentation
    singleton_class.
        send(:define_method, :__docile_undo_fallback__) do
      singleton_class.send(:remove_method, :method_missing)
      singleton_class.send(:remove_method, :__docile_undo_fallback__)
    end
  end
end

Public Instance Methods

append(obj) click to toggle source
# File lib/turborex/cstruct.rb, line 184
        def append(obj)
  elements.push(obj)
  @name_table.push('padding')
end
calc_padding(length, offset, pack = nil) click to toggle source
# File lib/turborex/cstruct.rb, line 189
        def calc_padding(length, offset, pack = nil)
  if pack != nil && pack < length
    length = pack
  end

  (length - (offset % length)) % length
end
define_structs(opts = {}, str = nil, &block) click to toggle source
# File lib/turborex/cstruct.rb, line 239
def define_structs(opts = {}, str = nil, &block)
  if block_given?
    Docile.dsl_eval(StructMgr.new(opts), &block)
  elsif opts[:native_parse] # parse with Metasm::C::Parser
    opts.delete[:native_parse]
    NativeParser.new(str, opts)
  end
end
effective_align(pack = nil) click to toggle source
# File lib/turborex/cstruct.rb, line 165
def effective_align(pack = nil)
  pack ||= @pack
  effective_value = get_member_self_align.max
  unless pack.nil?
    effective_value = [effective_value, pack].min
  end

  return effective_value
end
get_member_length(arr = []) click to toggle source
# File lib/turborex/cstruct.rb, line 126
def get_member_length(arr = [])
  self.each do |member|
    #if member.is_a? Rex::Struct2::CStruct
    #  member.get_member_length(arr)
    #else
    arr << member.slength
    #end
  end

  arr
end
get_member_self_align() click to toggle source
# File lib/turborex/cstruct.rb, line 152
def get_member_self_align
  arr = []
  self.each do |member|
    if member.is_a? Rex::Struct2::CStruct
      arr << member.self_align
    else
      arr << member.slength
    end
  end

  arr
end
insert(index, obj) click to toggle source
# File lib/turborex/cstruct.rb, line 179
        def insert(index, obj)
  elements.insert(index, obj)
  @name_table.insert(index, 'padding')
end
make_struct(pack = nil, natural_align = nil) click to toggle source
# File lib/turborex/cstruct.rb, line 219
def make_struct(pack = nil, natural_align = nil)
  s = ::Rex::Struct2::CStruct.new(*self.template).
      create_restraints(*self.template_create_restraints).
      apply_restraint(*self.template_apply_restraint)

  pack ||= @pack
  natural_align ||= @natural_align

  if pack
    s.pack(pack)
  end

  if natural_align
    s.padding_align
  end

  s
end
natural_align(align = true) click to toggle source
# File lib/turborex/cstruct.rb, line 207
def natural_align(align = true)
  @natural_align = align

  self
end
offset(struct, index, base_offset = 0) click to toggle source
# File lib/turborex/cstruct.rb, line 58
def offset(struct, index, base_offset = 0)
  if index == 0
    return index
  end

  offset = 0

  (0...index).each do |i|
    offset += struct[i].slength
  end

  base_offset + offset
end
pack(n) click to toggle source
# File lib/turborex/cstruct.rb, line 175
def pack(n)
  @pack = n
end
padding_align(base_offset = 0, pack = nil) click to toggle source
# File lib/turborex/cstruct.rb, line 72
def padding_align(base_offset = 0, pack = nil)
  i = 0

  loop do
    current_offset = offset(self, i, base_offset)
    if self[i].is_a? Rex::Struct2::CStruct

      self[i].pack(@pack)
      self[i].padding_align(@pack)
      #break if self[i + 1] == nil
      #binding.pry if @pack == 8

      padding = calc_padding(self[i].self_align, current_offset, @pack)
    else
      padding = calc_padding(self[i].slength, current_offset, @pack)
    end

    if padding == 0
      break if self[i + 1] == nil

      i += 1
      next
    end

    s = Rex::Struct2::CStructTemplate.new
    padding.times do
      s.template << ['uint8', 'padding', 0]
    end

    insert(i, s.make_struct)

    i += 1
    break if self[i + 1] == nil
    i += 1
  end

  self.trailing_padding(@pack)
end
self_align() click to toggle source
# File lib/turborex/cstruct.rb, line 138
def self_align
  arr = []

  self.each do |member|
    if member.is_a? Rex::Struct2::CStruct
      arr << member.get_member_self_align.max
    else
      arr << member.slength
    end
  end

  arr.max
end
trailing_padding(pack = nil) click to toggle source
# File lib/turborex/cstruct.rb, line 111
def trailing_padding(pack = nil)
  pack ||= @pack
  trailing = self.slength % effective_align(pack)
  if trailing != 0
    s = Rex::Struct2::CStructTemplate.new
    trailing.times do
      s.template << ['uint8', 'padding', 0]
    end

    append(s.make_struct)
  end

  self
end