# This file is part of Metasm, the Ruby assembly manipulation suite # Copyright (C) 2006-2009 Yoann GUILLOT # # Licence is LGPL, see LICENCE in the top-level directory Metasmdir = File.dirname(__FILE__) $:.unshift(Metasmdir) ## # The code below is used to do demand loading of requires, but it breaks # Metasploit integration. It has been commented out until a better # long-term solution is developed. ## =begin module Metasm # root directory for metasm files # used by some scripts, eg to find samples/dasm-plugin directory Metasmdir = File.dirname(__FILE__) # constant defined in the same file as another Const_autorequire_equiv = { 'X86' => 'Ia32', 'PPC' => 'PowerPC', 'X64' => 'X86_64', 'AMD64' => 'X86_64', 'UniversalBinary' => 'MachO', 'COFFArchive' => 'COFF', 'DEY' => 'DEX', 'PTrace' => 'LinOS', 'FatELF' => 'ELF', 'LoadedELF' => 'ELF', 'LoadedPE' => 'PE', 'LoadedAutoExe' => 'AutoExe', 'LinuxRemoteString' => 'LinOS', 'LinDebugger' => 'LinOS', 'WinAPI' => 'WinOS', 'WindowsRemoteString' => 'WinOS', 'WinDbgAPI' => 'WinOS', 'WinDebugger' => 'WinOS', 'VirtualFile' => 'OS', 'VirtualString' => 'OS', 'GdbRemoteString' => 'GdbClient', 'GdbRemoteDebugger' => 'GdbClient', 'DecodedInstruction' => 'Disassembler', 'DecodedFunction' => 'Disassembler', 'InstructionBlock' => 'Disassembler', } Const_autorequire = { 'CPU' => ['encode', 'decode', 'render', 'main', 'exe_format/main', 'os/main'], 'Ia32' => 'ia32', 'MIPS' => 'mips', 'PowerPC' => 'ppc', 'ARM' => 'arm', 'X86_64' => 'x86_64', 'Sh4' => 'sh4', 'Dalvik' => 'dalvik', 'C' => ['parse_c', 'compile_c'], 'MZ' => 'exe_format/mz', 'PE' => 'exe_format/pe', 'ELF' => 'exe_format/elf', 'COFF' => 'exe_format/coff', 'Shellcode' => 'exe_format/shellcode', 'AutoExe' => 'exe_format/autoexe', 'AOut' => 'exe_format/a_out', 'MachO' => 'exe_format/macho', 'DEX' => 'exe_format/dex', 'NDS' => 'exe_format/nds', 'XCoff' => 'exe_format/xcoff', 'Bflt' => 'exe_format/bflt', 'Dol' => 'exe_format/dol', 'Gui' => 'gui', 'WindowsExports' => 'os/windows_exports', 'GNUExports' => 'os/gnu_exports', 'LinOS' => 'os/linux', 'WinOS' => 'os/windows', 'GdbClient' => 'os/remote', 'Disassembler' => 'disassemble', 'Decompiler' => 'decompile', 'DynLdr' => 'dynldr', } def self.autorequire_const_missing(c) cst = Const_autorequire_equiv[c.to_s] || c.to_s files = Const_autorequire[cst] return if not files files = [files] if files.kind_of? ::String files.each { |f| require ::File.join('metasm', f) } const_get c end def self.require(f) # temporarily put the current file directory in the ruby include path if not $:.include? Metasmdir incdir = Metasmdir $: << incdir end super(f) $:.delete incdir if incdir end end # handle subclasses, nested modules etc (e.g. Metasm::PE, to avoid Metasm::PE::Ia32: const not found) class Module alias premetasm_const_missing const_missing def const_missing(c) # Object.const_missing => Module#const_missing and not the other way around # XXX should use Module.nesting, but ruby sucks arse # e.g. module Metasm ; module Bla ; class << self ; Ia32 ; end ; end ; end -> fail if (name =~ /^Metasm(::|$)/ or ancestors.include? Metasm) and cst = Metasm.autorequire_const_missing(c) cst else premetasm_const_missing(c) end end end # load core files by default (too many classes to check for otherwise) Metasm::CPU.class =end # load core files by default (too many classes to check for otherwise) require 'metasm/encode' require 'metasm/decode' require 'metasm/main' require 'metasm/exe_format/main' require 'metasm/os/main' # remove an 1.9 warning, couldn't find a compatible way... if {}.respond_to? :key puts "using ruby1.9 workaround for Hash#index warning" if $DEBUG class Hash alias index_premetasm index rescue nil undef index rescue nil alias index key end end