ESP trick in PyEmu

ESP trick is an old way to defeat some packer, this procedure is really simple: first look for a PUSHAD near the entrypoint, step over the PUSHAD, follow ESP into memory and then set an hardware breakpoint on access to this location. Wait for a POPAD which accesses this location and then look for a near JMP.

How to do this within a debugger is quite obvious but this time we want achieve this objective in a different way, we wanna use PyEmu.

Ok warm-up ended… let’s code…

Step 1, define our PUSHAD instruction handler:

def pushad_instruction_handler(emu, instruction, eip, op1, op2, op3):
    #get and save ESP
    global _esp_
    _esp_ = emu.get_register("ESP") - 4
    #set our memory handler
    emu.set_memory_access_handler(memory_access_handler)

    return True

Step 2, define our memory access handler:

def memory_access_handler(emu, address, value, size, type):
    global _esp_
    if address == _esp_ and type == "read":
        #set JMP handler
        emu.set_opcode_handler(0xE9, jmp_instruction_handler)

    return True

Step 3, define our JMP instruction handler:

def jmp_instruction_handler(emu, instruction, address, op1, op2, op3):
    #stop emulation
    emu.emulating = False
    #print OEP
    raw_input("[*] OEP: 0x%08x" % address)

    return True

Step 4, put all together:

_esp_ = None

def pushad_instruction_handler(emu, instruction, eip, op1, op2, op3):
    #get and save ESP
    global _esp_
    _esp_ = emu.get_register("ESP") - 4
    #set our memory handler
    emu.set_memory_access_handler(memory_access_handler)

    return True

def memory_access_handler(emu, address, value, size, type):
    global _esp_
    if address == _esp_ and type == "read":
        #set JMP handler
        emu.set_opcode_handler(0xE9, jmp_instruction_handler)

    return True

def jmp_instruction_handler(emu, instruction, address, op1, op2, op3):
    #stop emulation
    emu.emulating = False
    #print OEP
    raw_input("[*] OEP: 0x%08x" % address)

    return True


emu = PEPyEmu()

if not emu.load(EXE_TO_UNPACK):
    print "[!] unable to load target exe: %s" % EXE_TO_UNPACK
else:
    #library
    emu.set_library_handler("LoadLibraryA", LoadLibrary)
    emu.set_library_handler("GetProcAddress", GetProcAddress)
    emu.set_library_handler("VirtualProtect", VirtualProtect)

    #opcode
    emu.set_opcode_handler(0x60, pushad_instruction_handler)

    #misc
    emu.execute(start=emu.entry_point, end=-1)

This program has been tested versus an UPX packed exe, so maybe that with a different packer it will not work fine. Full source code is available here.

I hope you enjoyed this little trip into PyEmu… see you next post 8)

Advertisements

3 Responses to “ESP trick in PyEmu”


  1. 1 s4tan August 11, 2009 at 11:23 am

    Very nice post 🙂

    In order to use pyemu there are some prerequisites (like to have IDA Pro installed)?

  2. 2 ratsoul August 11, 2009 at 12:26 pm

    Thanks.

    In order to use PyEmu you need to download PyEmu code from: http://code.google.com/p/pyemu/.

    This package doesn’t require any setup you only need to add the following lines in your code:

    sys.path.append(PY_EMU_DIR), PyEmu base directory path
    sys.path.append(PY_EMU_LIB_DIR), PyEmu lib directory

    and then you can import from PyEmu.

    PyEmu has 3 “flavours”:
    – PEPyEmu, standalone emulator;
    – IDAPyEmu, requires IDA in order to work;
    – PyDbgPyEmu, requires PyDbg in order to work;

    Have fun 😉


Comments are currently closed.




%d bloggers like this: