Class: Rex::Assembly::Nasm

Inherits:
Object
  • Object
show all
Defined in:
lib/rex/assembly/nasm.rb

Overview

This class uses nasm to assemble and disassemble stuff.

Constant Summary collapse

@@nasm_path =
'nasm'
@@ndisasm_path =
'ndisasm'

Class Method Summary collapse

Class Method Details

.assemble(assembly, bits = 32) ⇒ Object

Assembles the supplied assembly and returns the raw opcodes.


40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/rex/assembly/nasm.rb', line 40

def self.assemble(assembly, bits=32)
  check

  # Open the temporary file
  tmp = Tempfile.new('nasmXXXX')
  tmp.binmode

  tpath = tmp.path
  opath = tmp.path + '.out'

  # Write the assembly data to a file
  tmp.write("BITS #{bits}\n" + assembly)
  tmp.flush()
  tmp.seek(0)

  # Run nasm
  if (system(@@nasm_path, '-f', 'bin', '-o', opath, tpath) == false)
    raise RuntimeError, "Assembler did not complete successfully: #{$?.exitstatus}"
  end

  # Read the assembled text
  rv = ::IO.read(opath)

  # Remove temporary files
  File.unlink(opath)
  tmp.close(true)

  rv
end

.checkObject

Ensures that the nasm environment is sane.


23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/rex/assembly/nasm.rb', line 23

def self.check
  @@nasm_path =
    Rex::FileUtils.find_full_path('nasm')      ||
    Rex::FileUtils.find_full_path('nasm.exe')  ||
    Rex::FileUtils.find_full_path('nasmw.exe') ||
    raise(RuntimeError, "No nasm installation was found.")

  @@ndisasm_path =
    Rex::FileUtils.find_full_path('ndisasm')      ||
    Rex::FileUtils.find_full_path('ndisasm.exe')  ||
    Rex::FileUtils.find_full_path('ndisasmw.exe') ||
    raise(RuntimeError, "No ndisasm installation was found.")
end

.disassemble(raw, bits = 32) ⇒ Object

Disassembles the supplied raw opcodes


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
98
99
# File 'lib/rex/assembly/nasm.rb', line 73

def self.disassemble(raw, bits=32)
  check

  tmp = Tempfile.new('nasmout')
  tmp.binmode

  tfd = File.open(tmp.path, "wb")

  tfd.write(raw)
  tfd.flush()
  tfd.close

  p = ::IO.popen("\"#{@@ndisasm_path}\" -b #{bits} \"#{tmp.path}\"")
  o = ''

  begin
    until p.eof?
      o += p.read
    end
  ensure
    p.close
  end

  tmp.close(true)

  o
end