Files
metasploit-gs/lib/rex/encoder/alpha2/alpha_upper.rb
T
2015-06-08 14:35:48 -05:00

139 lines
4.4 KiB
Ruby

# -*- coding: binary -*-
require 'rex/encoder/alpha2/generic'
module Rex
module Encoder
module Alpha2
class AlphaUpper < Generic
def self.default_accepted_chars ; ('B' .. 'Z').to_a + ('0' .. '9').to_a ; end
# Generates the decoder stub prefix
#
# @param [String] reg the register pointing to the encoded payload
# @param [Fixnum] offset the offset to reach the encoded payload
# @param [Array] modified_registers accounts the registers modified by the stub
# @return [String] the alpha upper decoder stub prefix
def self.gen_decoder_prefix(reg, offset, modified_registers = [])
if offset > 20
raise 'Critical: Offset is greater than 20'
end
mod_registers = []
nop_regs = []
mod_regs = []
edx_regs = []
# use inc ebx as a nop here so we still pad correctly
if (offset <= 10)
nop = 'C' * offset
nop_regs.push(Rex::Arch::X86::EBX) unless nop.empty?
mod = 'I' * (10 - offset) + nop + 'QZ' # dec ecx,,, push ecx, pop edx
mod_regs.push(Rex::Arch::X86::ECX) unless offset == 10
mod_regs.concat(nop_regs)
mod_regs.push(Rex::Arch::X86::EDX)
edxmod = 'J' * (11 - offset)
edx_regs.push(Rex::Arch::X86::EDX) unless edxmod.empty?
else
mod = 'A' * (offset - 10)
mod_regs.push(Rex::Arch::X86::ECX) unless mod.empty?
nop = 'C' * (10 - mod.length)
nop_regs.push(Rex::Arch::X86::EBX) unless nop.empty?
mod << nop + 'QZ'
mod_regs.concat(nop_regs)
mod_regs.push(Rex::Arch::X86::EDX)
edxmod = 'B' * (11 - (offset - 10))
edx_regs.push(Rex::Arch::X86::EDX) unless edxmod.empty?
end
regprefix = {
'EAX' => 'PY' + mod, # push eax, pop ecx
'ECX' => 'I' + mod, # dec ecx
'EDX' => edxmod + nop + 'RY', # mod edx,,, push edx, pop ecx
'EBX' => 'SY' + mod, # push ebx, pop ecx
'ESP' => 'TY' + mod, # push esp, pop ecx
'EBP' => 'UY' + mod, # push ebp, pop ecx
'ESI' => 'VY' + mod, # push esi, pop ecx
'EDI' => 'WY' + mod, # push edi, pop ecx
}
reg.upcase!
unless regprefix.keys.include?(reg)
raise ArgumentError.new("Invalid register name")
end
case reg
when 'EDX'
mod_registers.concat(edx_regs)
mod_registers.concat(nop_regs)
mod_registers.push(Rex::Arch::X86::ECX)
else
mod_registers.push(Rex::Arch::X86::ECX)
mod_registers.concat(mod_regs)
end
mod_registers.uniq!
modified_registers.concat(mod_registers)
return regprefix[reg]
end
# Generates the decoder stub
#
# @param [String] reg the register pointing to the encoded payload
# @param [Fixnum] offset the offset to reach the encoded payload
# @param [Array] modified_registers accounts the registers modified by the stub
# @return [String] the alpha upper decoder stub
def self.gen_decoder(reg, offset, modified_registers = [])
mod_registers = []
decoder =
gen_decoder_prefix(reg, offset, mod_registers) +
"V" + # push esi
"T" + # push esp
"X" + # pop eax
"30" + # xor esi, [eax]
"V" + # push esi
"X" + # pop eax
"4A" + # xor al, 41
"P" + # push eax
"0A3" + # xor [ecx+33], al
"H" + # dec eax
"H" + # dec eax
"0A0" + # xor [ecx+30], al
"0AB" + # xor [ecx+42], al
"A" + # inc ecx <---------------
"A" + # inc ecx |
"B" + # inc edx |
"TAAQ" + # imul eax, [ecx+41], 10 * |
"2AB" + # xor al [ecx+42] |
"2BB" + # xor al, [edx+42] |
"0BB" + # xor [edx+42], al |
"X" + # pop eax |
"P" + # push eax |
"8AC" + # cmp [ecx+43], al |
"JJ" + # jnz * --------------------
"I" # first encoded char, fixes the above J
mod_registers.concat(
[
Rex::Arch::X86::ESP,
Rex::Arch::X86::EAX,
Rex::Arch::X86::ESI,
Rex::Arch::X86::ECX,
Rex::Arch::X86::EDX
])
mod_registers.uniq!
modified_registers.concat(mod_registers)
return decoder
end
end end end end