2010-02-08 01:43:24 +00:00
|
|
|
#!/usr/bin/env ruby
|
|
|
|
#
|
2010-05-03 17:13:09 +00:00
|
|
|
# $Id$
|
|
|
|
#
|
2010-02-08 01:43:24 +00:00
|
|
|
# This tool provides an easy way to see what opcodes are associated with
|
|
|
|
# certain x86 instructions by making use of Metasm!
|
|
|
|
#
|
2010-05-03 17:13:09 +00:00
|
|
|
#
|
|
|
|
# $Revision$
|
|
|
|
#
|
2010-02-08 01:43:24 +00:00
|
|
|
|
|
|
|
# This file is part of Metasm, the Ruby assembly manipulation suite
|
|
|
|
# Copyright (C) 2007 Yoann GUILLOT
|
|
|
|
#
|
|
|
|
# Licence is LGPL, see LICENCE in the top-level directory
|
|
|
|
|
|
|
|
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
|
|
|
2010-02-13 06:10:37 +00:00
|
|
|
require 'rex'
|
|
|
|
require 'rex/ui'
|
2010-02-08 01:43:24 +00:00
|
|
|
require 'metasm'
|
|
|
|
|
|
|
|
|
|
|
|
class String
|
|
|
|
@@cpu = Metasm::Ia32.new
|
|
|
|
class << self
|
|
|
|
def cpu() @@cpu end
|
|
|
|
def cpu=(c) @@cpu=c end
|
|
|
|
end
|
|
|
|
|
|
|
|
# encodes the current string as a Shellcode, returns the resulting EncodedData
|
|
|
|
def encode_edata
|
|
|
|
s = Metasm::Shellcode.assemble @@cpu, self
|
|
|
|
s.encoded
|
|
|
|
end
|
|
|
|
|
|
|
|
# encodes the current string as a Shellcode, returns the resulting binary String
|
|
|
|
# outputs warnings on unresolved relocations
|
|
|
|
def encode
|
|
|
|
ed = encode_edata
|
|
|
|
if not ed.reloc.empty?
|
|
|
|
puts 'W: encoded string has unresolved relocations: ' + ed.reloc.map { |o, r| r.target.inspect }.join(', ')
|
|
|
|
end
|
|
|
|
ed.fill
|
|
|
|
ed.data
|
|
|
|
end
|
|
|
|
|
|
|
|
# decodes the current string as a Shellcode, with specified base address
|
|
|
|
# returns the resulting Disassembler
|
|
|
|
def decode_blocks(base_addr=0, eip=base_addr)
|
|
|
|
sc = Metasm::Shellcode.decode(self, @@cpu)
|
|
|
|
sc.base_addr = base_addr
|
|
|
|
sc.disassemble(eip)
|
|
|
|
end
|
|
|
|
|
|
|
|
# decodes the current string as a Shellcode, with specified base address
|
|
|
|
# returns the asm source equivallent
|
|
|
|
def decode(base_addr=0, eip=base_addr)
|
|
|
|
decode_blocks(base_addr, eip).to_s
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-02-13 06:10:37 +00:00
|
|
|
# Start a pseudo shell and dispatch lines to be assembled and then
|
|
|
|
# disassembled.
|
|
|
|
shell = Rex::Ui::Text::PseudoShell.new("%bldmetasm%clr")
|
2010-04-27 18:11:09 +00:00
|
|
|
shell.init_ui(Rex::Ui::Text::Input::Stdio.new, Rex::Ui::Text::Output::Stdio.new)
|
2010-02-13 06:10:37 +00:00
|
|
|
|
|
|
|
puts 'type "exit" or "quit" to quit', 'use ";" or "\\n" for newline', ''
|
|
|
|
|
|
|
|
shell.run { |l|
|
|
|
|
l.gsub!(/(\r|\n)/, '')
|
|
|
|
l.gsub!(/\\n/, "\n")
|
|
|
|
l.gsub!(';', "\n")
|
|
|
|
|
|
|
|
break if %w[quit exit].include? l.chomp
|
|
|
|
next if l.strip.empty?
|
|
|
|
|
|
|
|
begin
|
|
|
|
l = l.encode
|
|
|
|
puts '"' + l.unpack('C*').map { |c| '\\x%02x' % c }.join + '"'
|
|
|
|
rescue Metasm::Exception => e
|
|
|
|
puts "Error: #{e.class} #{e.message}"
|
|
|
|
end
|
|
|
|
}
|