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.

Parameters:

  • values ({Integer, Symbol => Context::Value?}) (defaults to: {})

    Value to be set to reg/mem.

  • known_data (Array<Integer?>) (defaults to: [])

    Records which index of data is known. It’s used for tracking if the syscall number is known, which can be used to display argument names of the syscall.



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)

Returns Records the known value of data.

Returns:

  • (Array<Integer?>)

    Records the known value of data.



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

def known_data
  @known_data
end

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

Returns Records reg and mem values.

Returns:

  • ({Integer, Symbol => Context::Value})

    Records reg and mem values.



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.

Parameters:

  • key (String, Symbol, Integer)

Returns:



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.

Parameters:

  • reg (#downcase, :a, :x)

    Can be ‘A’, ‘a’, :a, ‘X’, ‘x’, :x.

  • val (Value)

    Value to set.



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.

Returns:



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

def a
  values[:a]
end

#dupContext

Implements a deep dup.

Returns:



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.

Parameters:

  • val (Integer, :x)

    An immediate value or the symbol x.

Returns:

  • (self)

    Returns the object itself.



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 if 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.

Parameters:

Returns:

  • (Boolean)


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.

Returns:

  • (Integer)


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.

Parameters:

  • reg (#downcase, :a, :x)

    Register to be set



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: rel, val: val)
                end
end

#store(idx, reg) ⇒ void

This method returns an undefined value.

Is used for the st/stx instructions.

Parameters:

  • idx (Integer)

    Index of mem array.

  • reg (#downcase, :a, :x)

    Register.

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.

Returns:



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

def x
  values[:x]
end