Class: SeccompTools::Disasm::Context

Inherits:
Object
  • Object
show all
Defined in:
lib/seccomp-tools/disasm/context.rb

Overview

Context for disassembler to analyze.

This class maintains:

  • if reg/mem can be one of data

  • if data[0] (i.e. sys_number) is a known value

Defined Under Namespace

Classes: Value

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(values: {}, known_data: []) ⇒ Context

Instantiate a SeccompTools::Disasm::Context object.



63
64
65
66
67
68
69
# File 'lib/seccomp-tools/disasm/context.rb', line 63

def initialize(values: {}, known_data: [])
  @values = values
  16.times { |i| @values[i] ||= Value.new(rel: :mem, val: i) } # make @values always has all keys
  @values[:a] ||= Value.new
  @values[:x] ||= Value.new
  @known_data = known_data
end

Instance Attribute Details

#known_dataArray<Integer?> (readonly)



54
55
56
# File 'lib/seccomp-tools/disasm/context.rb', line 54

def known_data
  @known_data
end

#values{Integer, Symbol => Context::Value} (readonly)



52
53
54
# File 'lib/seccomp-tools/disasm/context.rb', line 52

def values
  @values
end

Instance Method Details

#[](key) ⇒ Context::Value

For conveniently get instance variable.



141
142
143
144
145
# File 'lib/seccomp-tools/disasm/context.rb', line 141

def [](key)
  return values[key] if key.is_a?(Integer) # mem

  values[key.downcase.to_sym]
end

#[]=(reg, val) ⇒ void

This method returns an undefined value.

For conveniently set an instance variable.



153
154
155
# File 'lib/seccomp-tools/disasm/context.rb', line 153

def []=(reg, val)
  values[reg.downcase.to_sym] = val
end

#aContext::Value

Register A.



128
129
130
# File 'lib/seccomp-tools/disasm/context.rb', line 128

def a
  values[:a]
end

#dupContext

Implements a deep dup.



122
123
124
# File 'lib/seccomp-tools/disasm/context.rb', line 122

def dup
  Context.new(values: values.dup, known_data: known_data.dup)
end

#eql!(val) ⇒ self

Hints context that current value of register A equals to val.



105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/seccomp-tools/disasm/context.rb', line 105

def eql!(val)
  tap do
    # only cares when A is fetched from data
    next unless a.data?
    next known_data[a.val] = val if val.is_a?(Integer)
    # A == X, we can handle these cases:
    # * X is an immi
    # * X is a known data
    next unless x.data? || x.imm?
    next known_data[a.val] = x.val if x.imm?

    known_data[a.val] = known_data[x.val]
  end
end

#eql?(other) ⇒ Boolean

For Set to compare two SeccompTools::Disasm::Context objects.



160
161
162
# File 'lib/seccomp-tools/disasm/context.rb', line 160

def eql?(other)
  values.eql?(other.values) && known_data.eql?(other.known_data)
end

#hashInteger

For Set to get the hash value.



166
167
168
# File 'lib/seccomp-tools/disasm/context.rb', line 166

def hash
  values.hash ^ known_data.hash
end

#load(reg, rel: nil, val: nil) ⇒ void

This method returns an undefined value.

Is used for the ld/ldx instructions.



76
77
78
79
80
81
82
83
# File 'lib/seccomp-tools/disasm/context.rb', line 76

def load(reg, rel: nil, val: nil)
  reg = reg.downcase.to_sym
  values[reg] = if rel == :mem
                  values[val]
                else
                  Value.new(rel:, val:)
                end
end

#store(idx, reg) ⇒ void

This method returns an undefined value.

Is used for the st/stx instructions.

Raises:

  • (RangeError)


93
94
95
96
97
# File 'lib/seccomp-tools/disasm/context.rb', line 93

def store(idx, reg)
  raise RangeError, "Expect 0 <= idx < 16, got #{idx}." unless idx.between?(0, 15)

  values[idx] = values[reg.downcase.to_sym]
end

#xContext::Value

Register X.



134
135
136
# File 'lib/seccomp-tools/disasm/context.rb', line 134

def x
  values[:x]
end