Class: Haxor::Vm::Os

Inherits:
Subsystem show all
Defined in:
lib/haxor/vm/os.rb

Constant Summary collapse

TABLE =
{
  0x01 => :sys_printf,
  0x02 => :sys_scanf,
  0x03 => :sys_rand
}

Instance Attribute Summary

Attributes inherited from Subsystem

#vm

Instance Method Summary collapse

Methods inherited from Subsystem

#register, #subsystem

Instance Method Details

#collect_string(addr) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/haxor/vm/os.rb', line 15

def collect_string(addr)
  i = 0
  string = ''
  loop do
    char = @vm.subsystem(:mem).read(addr + i)
    break if char == 0
    string << char.ord

    i += Consts::WORD_SIZE
  end

  string
end

#parse_format(fmt) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/haxor/vm/os.rb', line 29

def parse_format(fmt)
  fmt = fmt.tr '^A-Za-z%', ''
  fmt = fmt.gsub '%%', ''

  types = []
  last_char = nil
  fmt.each_char do |char|
    if last_char == '%'
      if %w(b B d i o u x X).include? char
        types << :integer
      elsif %w(c s).include? char
        types << :string
      else
        fail
      end
    end

    last_char = char
  end

  types
end

#sys_printf ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/haxor/vm/os.rb', line 52

def sys_printf
  fd = subsystem(:stack).pop_value
  x = subsystem(:stack).pop_value
  fmt = collect_string x
  args = []
  parse_format(fmt).each do |type|
    case type
    when :string
      args << collect_string(subsystem(:stack).pop_value)
    when :integer
      args << subsystem(:stack).pop_value
    else
      fail
    end
  end

  file = IO.new(fd, 'a')
  file.write sprintf(fmt, *args)
end

#sys_rand ⇒ Object



99
100
101
102
103
104
105
106
# File 'lib/haxor/vm/os.rb', line 99

def sys_rand
  min = subsystem(:stack).pop_value
  max = subsystem(:stack).pop_value

  prng = Random.new
  v = prng.rand(min..max)
  subsystem(:stack).push_value v
end

#sys_scanf ⇒ Object



72
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
# File 'lib/haxor/vm/os.rb', line 72

def sys_scanf
  fd = subsystem(:stack).pop_value
  fmt = collect_string subsystem(:stack).pop_value
  types = parse_format fmt

  file = IO.new(fd, 'r')
  result = file.scanf fmt

  if result.size != types.size
    subsystem(:cpu).reg Vm::Cpu::Core::REG_SYSCALL, -1
    return
  end

  types.each do |type|
    value = result.shift

    case type
    when :string
      subsystem(:mem).write_string subsystem(:stack).pop_value, value
    when :integer
      subsystem(:mem).write subsystem(:stack).pop_value, value
    else
      fail
    end
  end
end

#syscall ⇒ Object



10
11
12
13
# File 'lib/haxor/vm/os.rb', line 10

def syscall
  func = subsystem(:cpu).reg(Vm::Cpu::Core::REG_SYSCALL)
  send(TABLE[func])
end