metasploit-framework/modules/encoders/x86/call4_dword_xor.rb

64 lines
1.7 KiB
Ruby

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Encoder::Xor
def initialize
super(
'Name' => 'Call+4 Dword XOR Encoder',
'Description' => 'Call+4 Dword XOR Encoder',
'Author' => [ 'hdm', 'spoonm' ],
'Arch' => ARCH_X86,
'License' => MSF_LICENSE,
'Decoder' =>
{
'KeySize' => 4,
'BlockSize' => 4,
})
end
#
# Returns the decoder stub that is adjusted for the size of
# the buffer being encoded
#
def decoder_stub(state)
# Sanity check that saved_registers doesn't overlap with modified_registers
if (modified_registers & saved_registers).length > 0
raise BadGenerateError
end
decoder =
Rex::Arch::X86.sub(-(((state.buf.length - 1) / 4) + 1), Rex::Arch::X86::ECX,
state.badchars) +
"\xe8\xff\xff\xff" + # call $+4
"\xff\xc0" + # inc eax
"\x5e" + # pop esi
"\x81\x76\x0eXORK" + # xor [esi + 0xe], xork
"\x83\xee\xfc" + # sub esi, -4
"\xe2\xf4" # loop xor
# Calculate the offset to the XOR key
state.decoder_key_offset = decoder.index('XORK')
return decoder
end
# Indicate that this module can preserve some registers
def can_preserve_registers?
true
end
# A list of registers always touched by this encoder
def modified_registers
[ Rex::Arch::X86::ECX, Rex::Arch::X86::EAX, Rex::Arch::X86::ESI ]
end
# Convert the SaveRegisters to an array of x86 register constants
def saved_registers
Rex::Arch::X86.register_names_to_ids(datastore['SaveRegisters'])
end
end