Class: Evoasm::Buffer

Inherits:
FFI::AutoPointer
  • Object
show all
Defined in:
lib/evoasm/buffer.rb

Overview

Represents an executable area of memory

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(capacity, type = :mmap) ⇒ Buffer

Returns a new instance of Buffer

Parameters:

  • capacity (Integer)

    the buffer's capacity in bytes

  • type (:mmap, :malloc) (defaults to: :mmap)

    the buffer type, only buffers created with :mmap are executable



15
16
17
18
19
20
21
22
# File 'lib/evoasm/buffer.rb', line 15

def initialize(capacity, type = :mmap)
  ptr = Libevoasm.buf_alloc
  unless Libevoasm.buf_init ptr, type, capacity
    Libevoasm.buf_free ptr
    raise Error.last
  end
  super(ptr)
end

Instance Attribute Details

#capacityInteger (readonly)

Returns the buffer's capacity

Returns:

  • (Integer)

    the buffer's capacity



26
27
28
# File 'lib/evoasm/buffer.rb', line 26

def capacity
  Libevoasm.buf_get_capa self
end

#positionInteger (readonly)

Returns the buffer cursor's current position

Returns:

  • (Integer)

    the buffer cursor's current position



32
33
34
# File 'lib/evoasm/buffer.rb', line 32

def position
  Libevoasm.buf_get_pos self
end

#type:mmap, :malloc (readonly)

Returns the buffer's current position

Returns:

  • (:mmap, :malloc)

    the buffer's current position



44
45
46
# File 'lib/evoasm/buffer.rb', line 44

def type
  Libevoasm.buf_get_type self
end

Instance Method Details

#execute!Object

Executes the buffer's content.

Raises:



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/evoasm/buffer.rb', line 73

def execute!
  begin

    unless Libevoasm.buf_protect self, :rx
      raise Error.last
    end

    current_arch = Libevoasm.get_current_arch
    return_value = nil
    exception_enum = Libevoasm.enum_type(:#{current_arch}_exception")
    # catch everything
    exception_mask = exception_enum.flags(exception_enum.symbols, shift: true)

    #FIXME: should be intptr_t, but FFI sucks
    return_value_ptr = FFI::MemoryPointer.new :size_t, 1

    success = Libevoasm.buf_safe_exec(self, exception_mask, return_value_ptr)
    return_value = return_value_ptr.read_size_t


    if success
      return return_value
    else
      raise ExceptionError.new(current_arch, exception_enum[return_value])
    end
  ensure
    unless Libevoasm.buf_protect self, :rw
      raise Error.last
    end
  end
end

#resetvoid

This method returns an undefined value.

Resets the buffers position to zero



38
39
40
# File 'lib/evoasm/buffer.rb', line 38

def reset
  Libevoasm.buf_reset self
end

#to_sString

Gives the buffer's content as string

Returns:

  • (String)


50
51
52
53
# File 'lib/evoasm/buffer.rb', line 50

def to_s
  ptr = Libevoasm.buf_get_data self
  ptr.read_string capacity
end

#write(data) ⇒ Object

Writes data into the buffer and advances the buffer position

Parameters:

  • data (String)

    the data to write into the buffer



62
63
64
65
66
67
68
69
# File 'lib/evoasm/buffer.rb', line 62

def write(data)
  data_ptr = FFI::MemoryPointer.new :uint8, data.size
  data_ptr.write_string data

  if Libevoasm.buf_write(self, data_ptr, data.size) != 0
    raise Error.last
  end
end