Class: OneGadget::Emulators::Lambda

Inherits:
Object
  • Object
show all
Defined in:
lib/one_gadget/emulators/lambda.rb

Overview

A Lambda object can be:

  1. String (variable name)

  2. Numeric

  3. Lambda + Numeric

  4. dereferenced Lambda

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(obj) ⇒ Lambda

Instantiate a OneGadget::Emulators::Lambda object.


17
18
19
20
21
# File 'lib/one_gadget/emulators/lambda.rb', line 17

def initialize(obj)
  @immi = 0
  @obj = obj
  @deref_count = 0
end

Instance Attribute Details

#deref_countInteger


14
15
16
# File 'lib/one_gadget/emulators/lambda.rb', line 14

def deref_count
  @deref_count
end

#immiInteger


13
14
15
# File 'lib/one_gadget/emulators/lambda.rb', line 13

def immi
  @immi
end

#objString, Lambda


12
13
14
# File 'lib/one_gadget/emulators/lambda.rb', line 12

def obj
  @obj
end

Class Method Details

.parse(argument, predefined: {}) ⇒ OneGadget::Emulators::Lambda, Integer

Target: parse string like [rsp+0x50] into a OneGadget::Emulators::Lambda object.

Examples:

obj = Lambda.parse('[rsp+0x50]')#=> #<Lambda @obj='rsp', @immi=80, @deref_count=1>

Lambda.parse('obj+0x30', predefined: { 'obj' => obj }).to_s#=> '[rsp+0x50]+0x30'
Lambda.parse('[x0, -104]')#=> #<Lambda @obj='x0', @immi=-104, @deref_count=1>

109
110
111
112
113
114
115
116
117
118
119
# File 'lib/one_gadget/emulators/lambda.rb', line 109

def parse(argument, predefined: {})
  arg = argument.dup
  return Integer(arg) if OneGadget::Helper.integer?(arg)  # nested []

  return parse(arg[1...arg.rindex(']')], predefined: predefined).deref if arg[0] == '['

  base, disp = mem_obj(arg)
  obj = predefined[base] || Lambda.new(base)
  obj += disp unless disp.zero?
  obj
end

Instance Method Details

#+(other) ⇒ Lambda

Implement addition with Numeric.


26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/one_gadget/emulators/lambda.rb', line 26

def +(other)
  raise Error::InstructionArgumentError, "Expect other(#{other}) to be numeric." unless other.is_a?(Numeric)

  if deref_count > 0
    ret = Lambda.new(self)
  else
    ret = Lambda.new(obj)
    ret.immi = immi
  end
  ret.immi += other
  ret
end

#-(other) ⇒ Lambda

Implement substract with Numeric.


42
43
44
# File 'lib/one_gadget/emulators/lambda.rb', line 42

def -(other)
  self.+(-other)
end

#derefLambda

A new OneGadget::Emulators::Lambda object with dereference count increase 1.


64
65
66
67
68
69
# File 'lib/one_gadget/emulators/lambda.rb', line 64

def deref
  ret = Lambda.new(obj)
  ret.immi = immi
  ret.deref_count = deref_count + 1
  ret
end

#deref!void

This method returns an undefined value.

Increase dreference count with 1.


48
49
50
# File 'lib/one_gadget/emulators/lambda.rb', line 48

def deref!
  @deref_count += 1
end

#evaluate(context) ⇒ Integer

Eval the value of lambda. Only support those like rsp0x30+.


87
88
89
90
91
# File 'lib/one_gadget/emulators/lambda.rb', line 87

def evaluate(context)
  raise Error::InstructionArgumentError, "Can't eval #{self}" if deref_count > 0 || (obj && !context.key?(obj))

  context[obj] + immi
end

#ref!self

Decrease dreference count with 1.

Raises:

  • (Error::InstrutionArgumentError)

    When this object cannot be referenced anymore.


55
56
57
58
59
60
# File 'lib/one_gadget/emulators/lambda.rb', line 55

def ref!
  raise Error::InstructionArgumentError, 'Cannot reference anymore!' if @deref_count <= 0

  @deref_count -= 1
  self
end

#to_sString

Expand the lambda presentation.


73
74
75
76
77
78
79
80
# File 'lib/one_gadget/emulators/lambda.rb', line 73

def to_s
  str = ''
  str += '[' * deref_count
  str += obj.to_s unless obj.nil?
  str += OneGadget::Helper.hex(immi, psign: true) unless immi.zero?
  str += ']' * deref_count
  str
end