ASPack-2.29 Unpacker
# | |
# ASPack 2.29 unpacker via. Dynamic Analysis | |
# | |
$:.unshift("C:\\Lib\\metasm") | |
require 'metasm' | |
AS229_OEP_PUSH_OFFSET = 0x420 | |
def _msg(m, error = false) | |
if error | |
$stderr.puts("[-] #{m}") | |
else | |
$stdout.puts("[+] #{m}") | |
end | |
end | |
def as229_unpack(inexe, outexe) | |
_msg("Trying to get debug privilege") | |
Metasm::WinOS.get_debug_privilege | |
pe = Metasm::PE.decode_file(inexe) | |
aspack_sec = pe.sections.find {|s| s.name == ".aspack"} | |
if aspack_sec.nil? | |
_msg("Failed to find .aspack section (not ASPack protected??)", true) | |
return | |
end | |
_msg("Starting #{inexe} in debug mode") | |
dbg = Metasm::OS.current.create_process(inexe).debugger() | |
pe_base = pe.optheader.image_base # TODO: Get it from PEB | |
dbg.bpx(pe_base + pe.optheader.entrypoint, true) do | |
_msg("Breakpoint hit: aspack!EP") | |
dbg.bpx(pe.optheader.image_base + aspack_sec.virtaddr + AS229_OEP_PUSH_OFFSET, true) do | |
_msg("Breakpoint hit: OEP call") | |
if dbg.memory[dbg.get_reg_value(:eip), 1].unpack('C').first() != 0x68 | |
_msg("Unexpected instruction at OEP call (was expecting 'push'") | |
dbg.kill | |
return | |
end | |
oep_addr = dbg.memory[dbg.get_reg_value(:eip) + 1, 4].unpack('V').first() | |
_msg("OEP address: 0x%08x" % [oep_addr]) | |
_msg("Trying to dump PE") | |
pe_dump = Metasm::LoadedPE.memdump(dbg.memory, pe_base, oep_addr) | |
#pe_dump.sections.delete_if {|sec| ['.aspack', '.asdata'].include? sec.name } | |
# TODO: rebuild IAT | |
pe_dump.encode_file(outexe) | |
_msg("Terminating debugger") | |
dbg.kill | |
end | |
end | |
_msg("Executing") | |
begin | |
dbg.run_forever | |
rescue Interrupt | |
dbg.kill | |
end | |
end | |
if __FILE__ == $0 | |
as229_unpack(ARGV.shift, ARGV.shift) # packed.exe, unpacked.exe | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment