Class: Haxor::Vm::Os
Constant Summary collapse
- TABLE =
{ 0x01 => :sys_printf, 0x02 => :sys_scanf, 0x03 => :sys_rand }
Instance Attribute Summary
Attributes inherited from Subsystem
Instance Method Summary collapse
- #collect_string(addr) ⇒ Object
- #parse_format(fmt) ⇒ Object
- #sys_printf ⇒ Object
- #sys_rand ⇒ Object
- #sys_scanf ⇒ Object
- #syscall ⇒ Object
Methods inherited from 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 |