Created
October 18, 2016 01:08
-
-
Save aquynh/d01f4926bb9435c0e65f39ee470ac0de to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
Still remembers the Catwestern problem in the last Defcon CTF? | |
https://github.com/smokeleeteveryday/CTF_WRITEUPS/tree/master/2015/DEFCONCTF/coding/catwestern | |
In the writeup above, they complained about missing x86-64 emulator. | |
We solved this problem with Unicorn framework in this simple code. | |
''' | |
from unicorn import * | |
from unicorn.x86_const import * | |
X86_CODE64 = b"\x41\xBC\x3B\xB0\x28\x2A\x49\x0F\xC9\x90\x4D\x0F\xAD\xCF\x49\x87\xFD\x90\x48\x81\xD2\x8A\xCE\x77\x35\x48\xF7\xD9\x4D\x29\xF4\x49\x81\xC9\xF6\x8A\xC6\x53\x4D\x87\xED\x48\x0F\xAD\xD2\x49\xF7\ | |
xD4\x48\xF7\xE1\x4D\x19\xC5\x4D\x89\xC5\x48\xF7\xD6\x41\xB8\x4F\x8D\x6B\x59\x4D\x87\xD0\x68\x6A\x1E\x09\x3C\x59" | |
# memory address where emulation starts | |
ADDRESS = 0x1000000 | |
def test_x86_64(): | |
print("Emulate x86_64 code") | |
try: | |
# Initialize emulator in X86-64bit mode | |
mu = Uc(UC_ARCH_X86, UC_MODE_64) | |
# map 2MB memory for this emulation | |
mu.mem_map(ADDRESS, 2 * 1024 * 1024) | |
# write machine code to be emulated to memory | |
mu.mem_write(ADDRESS, X86_CODE64) | |
# initialize machine registers | |
mu.reg_write(X86_REG_RAX, 0x71f3029efd49d41d) | |
mu.reg_write(X86_REG_RBX, 0xd87b45277f133ddb) | |
mu.reg_write(X86_REG_RCX, 0xab40d1ffd8afc461) | |
mu.reg_write(X86_REG_RDX, 0x919317b4a733f01) | |
mu.reg_write(X86_REG_RSI, 0x4c24e753a17ea358) | |
mu.reg_write(X86_REG_RDI, 0xe509a57d2571ce96) | |
mu.reg_write(X86_REG_R8, 0xea5b108cc2b9ab1f) | |
mu.reg_write(X86_REG_R9, 0x19ec097c8eb618c1) | |
mu.reg_write(X86_REG_R10, 0xec45774f00c5f682) | |
mu.reg_write(X86_REG_R11, 0xe17e9dbec8c074aa) | |
mu.reg_write(X86_REG_R12, 0x80f86a8dc0f6d457) | |
mu.reg_write(X86_REG_R13, 0x48288ca5671c5492) | |
mu.reg_write(X86_REG_R14, 0x595f72f6e4017f6e) | |
mu.reg_write(X86_REG_R15, 0x1efd97aea331cccc) | |
# setup stack | |
mu.reg_write(X86_REG_RSP, ADDRESS + 0x200000) | |
# emulate machine code in infinite time | |
mu.emu_start(ADDRESS, ADDRESS + len(X86_CODE64)) | |
# done! now print out the CPU registers | |
print(">>> Emulation done. Below is the CPU context") | |
rax = mu.reg_read(X86_REG_RAX) | |
rbx = mu.reg_read(X86_REG_RBX) | |
rcx = mu.reg_read(X86_REG_RCX) | |
rdx = mu.reg_read(X86_REG_RDX) | |
rsi = mu.reg_read(X86_REG_RSI) | |
rdi = mu.reg_read(X86_REG_RDI) | |
r8 = mu.reg_read(X86_REG_R8) | |
r9 = mu.reg_read(X86_REG_R9) | |
r10 = mu.reg_read(X86_REG_R10) | |
r11 = mu.reg_read(X86_REG_R11) | |
r12 = mu.reg_read(X86_REG_R12) | |
r13 = mu.reg_read(X86_REG_R13) | |
r14 = mu.reg_read(X86_REG_R14) | |
r15 = mu.reg_read(X86_REG_R15) | |
print(">>> RAX = %x" %rax) | |
print(">>> RBX = %x" %rbx) | |
print(">>> RCX = %x" %rcx) | |
print(">>> RDX = %x" %rdx) | |
print(">>> RSI = %x" %rsi) | |
print(">>> RDI = %x" %rdi) | |
print(">>> R8 = %x" %r8) | |
print(">>> R9 = %x" %r9) | |
print(">>> R10 = %x" %r10) | |
print(">>> R11 = %x" %r11) | |
print(">>> R12 = %x" %r12) | |
print(">>> R13 = %x" %r13) | |
print(">>> R14 = %x" %r14) | |
print(">>> R15 = %x" %r15) | |
except UcError as e: | |
print("ERROR: %s" % e) | |
if __name__ == '__main__': | |
test_x86_64() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment