} elif op == "CALL": # E8 xxxxxxxx call <dword> ; (dword is relative to next instruction address) labels.append(arg) # we need to remember where it jumps mutated_code += """ add esp, -4 mov dword [esp], _%(returnaddress)i_ret add esp, -4 mov dword [esp], _%(calltarget)i retn _%(returnaddress)i_ret: """ % { "returnaddress": addr, "calltarget": arg } elif op == "JUMP": # FF25 xxxxxxxx jump [<dword>] mutated_code += """ mov eax, dword [%i] add esp, -4 mov dword [esp], eax retn""" % arg # generate our stub stub = mypacklib.build_stub(mutated_code) #patch the file with our changes, and modify EntryPoint value mypacklib.patchas(pe, "mutated.exe", oep, stub) # Ange Albertini, Creative Commons BY, 2009-2010
mutated_code += """ add esp, -4 mov dword [esp], %(arg)i """ % {"arg" : arg} elif op == "CALL": # E8 xxxxxxxx call <dword> ; (dword is relative to next instruction address) labels.append(arg) # we need to remember where it jumps mutated_code += """ add esp, -4 mov dword [esp], _%(returnaddress)i_ret add esp, -4 mov dword [esp], _%(calltarget)i retn _%(returnaddress)i_ret: """ % {"returnaddress": addr, "calltarget":arg} elif op == "JUMP": # FF25 xxxxxxxx jump [<dword>] mutated_code += """ mov eax, dword [%i] add esp, -4 mov dword [esp], eax retn""" % arg # generate our stub stub = mypacklib.build_stub(mutated_code) #patch the file with our changes, and modify EntryPoint value mypacklib.patchas(pe, "mutated.exe", oep, stub) # Ange Albertini, Creative Commons BY, 2009-2010
ret donedepacking: push 0%(oep_va)08xh retn compressed_data: """ # fill fake values to be able to get the stub size dummy_stub = my_stub % {"start_va": oep + ib, "oep_va": oep + ib} stub_length = len(mypacklib.build_stub(dummy_stub)) # now we can locate our stub accurately stub_start = start + size - (stub_length + len(compressed_data)) # and generate it my_stub = my_stub % {"start_va": stub_start + ib, "oep_va": oep + ib} stub = mypacklib.build_stub(my_stub) stub += compressed_data # we need to make that first section writable section = pe.sections[mypacklib.getEPsection(pe)] section.Characteristics |= pefile.SECTION_CHARACTERISTICS[ "IMAGE_SCN_MEM_WRITE"] # patch the file with our changes, and modify EntryPoint value mypacklib.patchas(pe, "compressed.exe", stub_start, stub) # Ange Albertini, Creative Commons BY, 2009-2010
push_handler: lodsd push eax jmp vm_fetch call_handler: lodsd call eax jmp vm_fetch handlers dd push_handler, call_handler ; generated according to the virtual opcodes table """ dummy_stub = my_stub % {'vc_va': start + ib, 'stub_va': start + ib + 1} stub_length = len(mypacklib.build_stub(dummy_stub)) ep = start + (size - stub_length) stub_start = ep - vc_len my_stub = my_stub % {'vc_va': stub_start + ib, 'stub_va': ep + ib} stub = mypacklib.build_stub(my_stub) # concat our virtual code and our virtual machine code stub = virtualized_code + stub #patch the file with our changes, and modify EntryPoint value mypacklib.patchas(pe, "virtualized.exe", stub_start, stub, ep) # Ange Albertini, Creative Commons BY, 2009-2010
pe, oep, ib, start, size = mypacklib.load() # generates our stub my_stub = """bits 32 pushad ; let's save registers mov eax, dword [fs:018h] ; implementing IsDebuggerPresent mov eax, dword [eax + 030h] movzx eax, byte [eax + 2] test al, al ; al is 1 if debugger is present jnz _fail popad push 0%(oep_va)08xh retn _fail: popad retn """ % { 'oep_va': oep + ib } stub = mypacklib.build_stub(my_stub) stub_length = len(stub) # our stub will be located at the end of the section that contains the entry point new_ep = start + (size - stub_length) # patch the file with our changes, and modify EntryPoint value mypacklib.patchas(pe, "protected.exe", new_ep, stub) # Ange Albertini, Creative Commons BY, 2009-2010
# incorrect values, just to get the stub size dummy_stub = my_stub % {'start_va':start + ib, 'size':size, 'oep_va':oep + ib} stub_length = len(mypacklib.build_stub(dummy_stub)) # calculating real values crypted_size = size - stub_length # final stub generation final_stub = my_stub % {'start_va':start + ib, 'size':crypted_size, 'oep_va':oep + ib} stub = mypacklib.build_stub(final_stub) # crypts the original section buffer = list(pe.get_data(start, crypted_size)) for i,b in enumerate(buffer): buffer[i] = chr(ord(b) ^ 0x42) buffer = str().join(buffer) # write crypted section pe.set_bytes_at_rva(start, buffer) # our stub will be located near the end of the section that contains the entry point new_ep = start + (size - stub_length) # patch the file with our changes, and modify EntryPoint value mypacklib.patchas(pe, "crypted.exe", new_ep, stub) # Ange Albertini, Creative Commons BY, 2009-2010
import pefile, mypacklib pe, oep, ib, start, size = mypacklib.load() # generates our stub my_stub = """bits 32 pushad ; let's save registers mov eax, dword [fs:018h] ; implementing IsDebuggerPresent mov eax, dword [eax + 030h] movzx eax, byte [eax + 2] test al, al ; al is 1 if debugger is present jnz _fail popad push 0%(oep_va)08xh retn _fail: popad retn """ % {'oep_va':oep + ib} stub = mypacklib.build_stub(my_stub) stub_length = len(stub) # our stub will be located at the end of the section that contains the entry point new_ep = start + (size - stub_length) # patch the file with our changes, and modify EntryPoint value mypacklib.patchas(pe, "protected.exe", new_ep, stub) # Ange Albertini, Creative Commons BY, 2009-2010
jc .getgammaloop ret donedepacking: push 0%(oep_va)08xh retn compressed_data: """ # fill fake values to be able to get the stub size dummy_stub = my_stub % {"start_va":oep + ib, "oep_va":oep + ib} stub_length = len(mypacklib.build_stub(dummy_stub)) # now we can locate our stub accurately stub_start = start + size - (stub_length + len(compressed_data)) # and generate it my_stub = my_stub % {"start_va":stub_start + ib, "oep_va":oep + ib} stub = mypacklib.build_stub(my_stub) stub += compressed_data # we need to make that first section writable section = pe.sections[mypacklib.getEPsection(pe)] section.Characteristics |= pefile.SECTION_CHARACTERISTICS["IMAGE_SCN_MEM_WRITE"] # patch the file with our changes, and modify EntryPoint value mypacklib.patchas(pe, "compressed.exe", stub_start, stub) # Ange Albertini, Creative Commons BY, 2009-2010
# Minimalist entry-point patcher # adds extra code that just jumps to the original entry point. import pefile, mypacklib pe, oep, ib, start, size = mypacklib.load() # generate our stub my_stub = """bits 32 push 0%(oep_va)08xh retn """ % {"oep_va":oep + ib} stub = mypacklib.build_stub(my_stub) stub_length = len(stub) #our stub will be located at the end of the section that contains the entry point new_ep = start + size - stub_length # patch the file with our changes, and modify EntryPoint value mypacklib.patchas(pe, "eppatched.exe", new_ep, stub) # Ange Albertini, Creative Commons BY, 2009-2010
stub_length = len(mypacklib.build_stub(dummy_stub)) # calculating real values crypted_size = size - stub_length # final stub generation final_stub = my_stub % { 'start_va': start + ib, 'size': crypted_size, 'oep_va': oep + ib } stub = mypacklib.build_stub(final_stub) # crypts the original section buffer = list(pe.get_data(start, crypted_size)) for i, b in enumerate(buffer): buffer[i] = chr(ord(b) ^ 0x42) buffer = str().join(buffer) # write crypted section pe.set_bytes_at_rva(start, buffer) # our stub will be located near the end of the section that contains the entry point new_ep = start + (size - stub_length) # patch the file with our changes, and modify EntryPoint value mypacklib.patchas(pe, "crypted.exe", new_ep, stub) # Ange Albertini, Creative Commons BY, 2009-2010