From 22b549a4db464dcb4dc2a7b9f5795a6797fa259a Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Wed, 26 Aug 2015 09:25:29 +0800 Subject: [PATCH] x86: add sample for 16bit mode --- bindings/python/sample_x86.py | 33 +++++++++++++++++++ samples/sample_all.sh | 2 ++ samples/sample_x86.c | 61 +++++++++++++++++++++++++++++++++-- 3 files changed, 94 insertions(+), 2 deletions(-) diff --git a/bindings/python/sample_x86.py b/bindings/python/sample_x86.py index 8f8f361b..24b82450 100755 --- a/bindings/python/sample_x86.py +++ b/bindings/python/sample_x86.py @@ -13,6 +13,7 @@ X86_CODE32_MEM_WRITE = b"\x89\x0D\xAA\xAA\xAA\xAA\x41\x4a" # mov [0xaaaaaaaa], e 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" X86_CODE32_INOUT = b"\x41\xE4\x3F\x4a\xE6\x46\x43" # INC ecx; IN AL, 0x3f; DEC edx; OUT 0x46, AL; INC ebx X86_CODE64_SYSCALL = '\x0f\x05' # SYSCALL +X86_CODE16 = '\x00\x00' # add byte ptr [bx + si], al # memory address where emulation starts ADDRESS = 0x1000000 @@ -437,6 +438,36 @@ def test_x86_64_syscall(): print("ERROR: %s" % e) +def test_x86_16(): + print("Emulate x86 16-bit code") + try: + # Initialize emulator in X86-16bit mode + mu = Uc(UC_ARCH_X86, UC_MODE_16) + + # map 8KB memory for this emulation + mu.mem_map(0, 8 * 1024) + + # set CPU registers + mu.reg_write(UC_X86_REG_EAX, 7) + mu.reg_write(UC_X86_REG_EBX, 5) + mu.reg_write(UC_X86_REG_ESI, 6) + + # write machine code to be emulated to memory + mu.mem_write(0, X86_CODE16) + + # emulate machine code in infinite time + mu.emu_start(0, len(X86_CODE16)) + + # now print out some registers + print(">>> Emulation done. Below is the CPU context") + + tmp = mu.mem_read(11, 1) + print("[0x%x] = 0x%x" %(11, tmp[0])) + + except UcError as e: + print("ERROR: %s" % e) + + if __name__ == '__main__': test_i386() print("=" * 20) @@ -451,3 +482,5 @@ if __name__ == '__main__': test_x86_64() print("=" * 20) test_x86_64_syscall() + print("=" * 20) + test_x86_16() diff --git a/samples/sample_all.sh b/samples/sample_all.sh index 7182a75d..e4ff7d48 100755 --- a/samples/sample_all.sh +++ b/samples/sample_all.sh @@ -15,6 +15,8 @@ if test -e $DIR/sample_x86; then $DIR/sample_x86 -32 echo "==========================" $DIR/sample_x86 -64 + echo "==========================" + $DIR/sample_x86 -16 fi if test -e $DIR/sample_arm; then echo "==========================" diff --git a/samples/sample_x86.c b/samples/sample_x86.c index b62e829e..b0dec117 100644 --- a/samples/sample_x86.c +++ b/samples/sample_x86.c @@ -24,7 +24,8 @@ //#define X86_CODE64 "\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" // <== still crash //#define X86_CODE64 "\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" -#define X86_CODE64 "\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" //\xc3" +#define X86_CODE64 "\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" +#define X86_CODE16 "\x00\x00" // add byte ptr [bx + si], al // memory address where emulation starts #define ADDRESS 0x1000000 @@ -672,6 +673,58 @@ static void test_x86_64(void) uc_close(&handle); } +static void test_x86_16(void) +{ + uch handle; + uc_err err; + uint8_t tmp; + + int32_t eax = 7; + int32_t ebx = 5; + int32_t esi = 6; + + printf("Emulate x86 16-bit code\n"); + + // Initialize emulator in X86-16bit mode + err = uc_open(UC_ARCH_X86, UC_MODE_16, &handle); + if (err) { + printf("Failed on uc_open() with error returned: %u\n", err); + return; + } + + // map 8KB memory for this emulation + uc_mem_map(handle, 0, 8 * 1024); + + // write machine code to be emulated to memory + if (uc_mem_write(handle, 0, (uint8_t *)X86_CODE16, sizeof(X86_CODE64) - 1)) { + printf("Failed to write emulation code to memory, quit!\n"); + return; + } + + // initialize machine registers + uc_reg_write(handle, UC_X86_REG_EAX, &eax); + uc_reg_write(handle, UC_X86_REG_EBX, &ebx); + uc_reg_write(handle, UC_X86_REG_ESI, &esi); + + // emulate machine code in infinite time (last param = 0), or when + // finishing all the code. + err = uc_emu_start(handle, 0, sizeof(X86_CODE16) - 1, 0, 0); + if (err) { + printf("Failed on uc_emu_start() with error returned %u: %s\n", + err, uc_strerror(err)); + } + + // now print out some registers + printf(">>> Emulation done. Below is the CPU context\n"); + + // read from memory + if (!uc_mem_read(handle, 11, &tmp, 1)) + printf(">>> Read 1 bytes from [0x%x] = 0x%x\n", 11, tmp); + else + printf(">>> Failed to read 1 bytes from [0x%x]\n", 11); + + uc_close(&handle); +} int main(int argc, char **argv, char **envp) { if (argc == 2) { @@ -689,6 +742,10 @@ int main(int argc, char **argv, char **envp) test_x86_64(); } + if (!strcmp(argv[1], "-16")) { + test_x86_16(); + } + // test memleak if (!strcmp(argv[1], "-0")) { while(1) { @@ -697,7 +754,7 @@ int main(int argc, char **argv, char **envp) } } } else { - printf("Syntax: %s <-32|-64>\n", argv[0]); + printf("Syntax: %s <-16|-32|-64>\n", argv[0]); } return 0;