From 6fc1f274920165edb7f89c91848076b100b9e58e Mon Sep 17 00:00:00 2001 From: samothtronicien Date: Fri, 29 Jul 2016 18:52:53 +0200 Subject: [PATCH] completed the test The issue noticed before only occurs while we are in the hook_code (eflags is not correctly updated after the execution of the SHL instruction using CL). Once the emulation has finished executing the code the value of eflags is correct. --- tests/regress/test_x86_shl.cpp | 148 ++++++++++++++++++++++----------- 1 file changed, 99 insertions(+), 49 deletions(-) diff --git a/tests/regress/test_x86_shl.cpp b/tests/regress/test_x86_shl.cpp index 52642f8b..41955b61 100644 --- a/tests/regress/test_x86_shl.cpp +++ b/tests/regress/test_x86_shl.cpp @@ -1,55 +1,96 @@ #include #include +#include #include +#ifdef _WIN32 +# include +# define printf OutputDebugStringA +#endif + +char buffer[256]; void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) { - uint32_t eax = 0, eflags = 0; + uint32_t eax = 0, ebx = 0, eflags = 0; uc_reg_read(uc, UC_X86_REG_EAX, &eax); + uc_reg_read(uc, UC_X86_REG_EBX, &ebx); uc_reg_read(uc, UC_X86_REG_EFLAGS, &eflags); - printf("eip=%08x - eax=%08x - eflags=%08X\n", (uint32_t)address, eax, eflags); + sprintf(buffer, "eip=%08x - eax=%08x - ebx=%08x - eflags=%08X\n", (uint32_t)address, eax, ebx, eflags); + printf(buffer); } const char code32_prob[] = { - 0xB8, 0x3C, 0x00, 0x00, 0x00, //0x100000: mov eax, 3Ch + 0xBB, 0x3C, 0x00, 0x00, 0x00, //0x100000: mov ebx, 3Ch 0xB1, 0x02, //0x100005: mov cl, 2 - 0xD3, 0xE0, //0x100007: shl eax, cl <- do not set PF - 0x33, 0xC0 //0x100009: xor eax, eax + 0xD3, 0xE3, //0x100007: shl ebx, cl + 0x9F, //0x100009: lahf + 0xCC //0x10000A: int3 }; const char code32_ok[] = { - 0xB8, 0x3C, 0x00, 0x00, 0x00, //0x100000: mov eax, 3Ch - 0xC1, 0xE0, 0x02, //0x100005: shl eax, 2 <- set PF correctly - 0x33, 0xC0 //0x100007: xor eax, eax + 0xBB, 0x3C, 0x00, 0x00, 0x00, //0x100000: mov ebx, 3Ch + 0xC1, 0xE3, 0x02, //0x100005: shl ebx, 2 + 0x9F, //0x100008: lahf + 0xCC //0x100009: int3 }; const char code16_prob[] = { - 0x66, 0xB8, 0x3C, 0x00, //0x100000: mov ax, 3Ch + 0x66, 0xBB, 0x3C, 0x00, //0x100000: mov bx, 3Ch 0xB1, 0x02, //0x100004: mov cl, 2 - 0x66, 0xD3, 0xE0, //0x100006: shl ax, cl - 0x33, 0xC0 //0x100009: xor eax, eax + 0x66, 0xD3, 0xE3, //0x100006: shl bx, cl + 0x9F, //0x100009: lahf + 0xCC //0x10000A: int3 }; const char code16_ok[] = { - 0x66, 0xB8, 0x3C, 0x00, //0x100000: mov ax, 3Ch - 0x66, 0xC1, 0xE0, 0x02, //0x100004: shl ax, 2 - 0x33, 0xC0 //0x100008: xor eax, eax + 0x66, 0xBB, 0x3C, 0x00, //0x100000: mov bx, 3Ch + 0x66, 0xC1, 0xE3, 0x02, //0x100004: shl bx, 2 + 0x9F, //0x100008: lahf + 0xCC //0x10000A: int3 }; const char code8_prob[] = { - 0xB0, 0x3C, //0x100000: mov al, 3Ch + 0xB3, 0x3C, //0x100000: mov bl, 3Ch 0xB1, 0x02, //0x100002: mov cl, 2 - 0xD2, 0xE0, //0x100004: shl al, 2 - 0x33, 0xC0 //0x100006: xor eax, eax + 0xD2, 0xE3, //0x100004: shl bl, 2 + 0x9F, //0x100006: lahf + 0xCC //0x100007: int3 }; const char code8_ok[] = { - 0xB0, 0x3C, //0x100000: mov al, 3Ch - 0xC0, 0xE0, 0x02, //0x100002: shl al, 2 - 0x33, 0xC0 //0x100005: xor eax, eax + 0xB3, 0x3C, //0x100000: mov bl, 3Ch + 0xC0, 0xE3, 0x02, //0x100002: shl bl, 2 + 0x9F, //0x100005: lahf + 0xCC //0x100006: int3 }; +const char code_SHL_JP_CL[] = { + 0xB4, 0x00, //0x100000: mov ah, 0 + 0x9E, //0x100002: sahf + 0xB8, 0x3C, 0x00, 0x00, 0x00, //0x100003: mov eax, 3Ch + 0xB1, 0x02, //0x100008: mov cl, 2 + 0xD3, 0xE0, //0x10000A: shl eax, cl + 0x7A, 0x07, //0x10000C: jp +7 + 0xB8, 0x00, 0x00, 0x00, 0x00, //0x10000E: mov eax, 0 + 0xEB, 0x05, //0x100014: jmp +5 + 0xB8, 0x01, 0x00, 0x00, 0x00, //0x100016: mov eax, 1 + 0xCC //0x10001B: int3 +}; + +const char code_SHL_JP_NOCL[] = { + 0xB4, 0x00, //0x100000: mov ah, 0 + 0x9E, //0x100002: sahf + 0xB8, 0x3C, 0x00, 0x00, 0x00, //0x100003: mov eax, 3Ch + 0xC1, 0xE0, 0x02, //0x100008: shl eax, 2 + 0x7A, 0x07, //0x10000B: jp +7 + 0xB8, 0x00, 0x00, 0x00, 0x00, //0x10000D: mov eax, 0 + 0xEB, 0x05, //0x100014: + 0xB8, 0x01, 0x00, 0x00, 0x00, //0x100016: mov eax, 1 + 0xCC //0x100017: int3 +}; + + #define ADDR_START 0x100000 #define TEST(X) if((X) != UC_ERR_OK) { \ @@ -59,6 +100,7 @@ const char code8_ok[] = { int main() { + uint32_t eflags = 0, eax = 0; uc_engine * uc = NULL; TEST(uc_open(UC_ARCH_X86, UC_MODE_32, &uc)); @@ -67,47 +109,55 @@ int main() TEST(uc_hook_add(uc, &trace_hook_code, UC_HOOK_CODE, hook_code, NULL, 1, 0)); TEST(uc_mem_map(uc, ADDR_START, 0x1000, UC_PROT_READ | UC_PROT_EXEC)); +#define RUN_CODE(CODE) { \ + TEST(uc_mem_write(uc, ADDR_START, CODE, sizeof(CODE))); \ + printf("running " #CODE "...\n"); \ + eflags = 0; \ + uc_reg_write(uc, UC_X86_REG_EFLAGS, &eflags); \ + TEST(uc_emu_start(uc, ADDR_START, ADDR_START + sizeof(CODE) - 1, 0, 0)); \ + uc_reg_read(uc, UC_X86_REG_EFLAGS, &eflags); \ + uc_reg_read(uc, UC_X86_REG_EAX, &eax); \ + sprintf(buffer, "after uc_emu_start: eflags=%08X - ah=%08X - %s\n", eflags, (eax>>8) & 0xFF, eflags & 4 ? "success" : "failed"); \ + printf(buffer); \ +} + //32 bits - TEST(uc_mem_write(uc, ADDR_START, code32_prob, sizeof(code32_prob))); - printf("running code_prob\n"); - TEST(uc_emu_start(uc, ADDR_START, ADDR_START + sizeof(code32_prob) - 1, 0, 4)); - - uint32_t eflags = 0; - uc_reg_write(uc, UC_X86_REG_EFLAGS, &eflags); - - TEST(uc_mem_write(uc, ADDR_START, code32_ok, sizeof(code32_ok))); - printf("running code_ok\n"); - TEST(uc_emu_start(uc, ADDR_START, ADDR_START + sizeof(code32_ok) - 1, 0, 3)); + RUN_CODE(code32_prob); + RUN_CODE(code32_ok); //16 bits - eflags = 0; - uc_reg_write(uc, UC_X86_REG_EFLAGS, &eflags); - - TEST(uc_mem_write(uc, ADDR_START, code16_prob, sizeof(code16_prob))); - printf("running code16_prob\n"); - TEST(uc_emu_start(uc, ADDR_START, ADDR_START + sizeof(code16_prob) - 1, 0, 4)); - - eflags = 0; - uc_reg_write(uc, UC_X86_REG_EFLAGS, &eflags); - - TEST(uc_mem_write(uc, ADDR_START, code16_ok, sizeof(code16_ok))); - printf("running code16_ok\n"); - TEST(uc_emu_start(uc, ADDR_START, ADDR_START + sizeof(code16_ok) - 1, 0, 3)); + RUN_CODE(code16_prob); + RUN_CODE(code16_ok); //8 bits + RUN_CODE(code8_prob); + RUN_CODE(code8_ok); + + //test with JP-CL eflags = 0; uc_reg_write(uc, UC_X86_REG_EFLAGS, &eflags); - TEST(uc_mem_write(uc, ADDR_START, code8_prob, sizeof(code8_prob))); - printf("running code8_prob\n"); - TEST(uc_emu_start(uc, ADDR_START, ADDR_START + sizeof(code8_prob) - 1, 0, 4)); + TEST(uc_mem_write(uc, ADDR_START, code_SHL_JP_CL, sizeof(code_SHL_JP_CL))); + printf("running code_SHL_JP_CL ...\n"); + TEST(uc_emu_start(uc, ADDR_START, ADDR_START + sizeof(code_SHL_JP_CL) - 1, 0, 0)); + eax = 0; + uc_reg_read(uc, UC_X86_REG_EAX, &eax); + if (eax == 1) printf("success\n"); + else printf("failed\n"); + + //test with JP-NOCL eflags = 0; uc_reg_write(uc, UC_X86_REG_EFLAGS, &eflags); - TEST(uc_mem_write(uc, ADDR_START, code8_ok, sizeof(code8_ok))); - printf("running code8_ok\n"); - TEST(uc_emu_start(uc, ADDR_START, ADDR_START + sizeof(code8_ok) - 1, 0, 3)); + TEST(uc_mem_write(uc, ADDR_START, code_SHL_JP_NOCL, sizeof(code_SHL_JP_NOCL))); + printf("running code_SHL_JP_NOCL ...\n"); + TEST(uc_emu_start(uc, ADDR_START, ADDR_START + sizeof(code_SHL_JP_NOCL) - 1, 0, 0)); + + eax = 0; + uc_reg_read(uc, UC_X86_REG_EAX, &eax); + if (eax == 1) printf("success\n"); + else printf("failed\n"); TEST(uc_close(uc));