From 9f9d57e84f72e871dc96521c8d263f7474a9dc6e Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Thu, 3 Sep 2015 18:16:49 +0800 Subject: [PATCH] cleaning & indentation --- qemu/unicorn_common.h | 2 +- regress/ro_mem_test.c | 2 +- samples/mem_exec.c | 423 +++++++++++++++++++-------------------- samples/mem_protect.c | 446 ++++++++++++++++++++---------------------- samples/mem_unmap.c | 433 +++++++++++++++++++--------------------- uc.c | 21 +- 6 files changed, 633 insertions(+), 694 deletions(-) diff --git a/qemu/unicorn_common.h b/qemu/unicorn_common.h index 5ba74fac..adfb5f05 100644 --- a/qemu/unicorn_common.h +++ b/qemu/unicorn_common.h @@ -77,7 +77,7 @@ static inline void uc_common_init(struct uc_struct* uc) uc->readonly_mem = memory_region_set_readonly; uc->target_page_size = TARGET_PAGE_SIZE; - uc->target_page_align = TARGET_PAGE_SIZE - 1; + uc->target_page_align = TARGET_PAGE_SIZE - 1; if (!uc->release) uc->release = release_common; diff --git a/regress/ro_mem_test.c b/regress/ro_mem_test.c index 52534cd4..38fd913b 100644 --- a/regress/ro_mem_test.c +++ b/regress/ro_mem_test.c @@ -160,7 +160,7 @@ int main(int argc, char **argv, char **envp) uint32_t eax = 0x40002C; uc_reg_write(handle, UC_X86_REG_EAX, &eax); //resume execution at the mov dword [eax], 0x87654321 - //to test an aligned write as well + //to test an aligned write as well err = uc_emu_start(handle, 0x400015, 0x400000 + sizeof(PROGRAM), 0, 2); if (err) { printf("Expected failure on uc_emu_start() with error returned %u: %s\n", diff --git a/samples/mem_exec.c b/samples/mem_exec.c index 171022a7..370fd1ea 100644 --- a/samples/mem_exec.c +++ b/samples/mem_exec.c @@ -1,23 +1,22 @@ /* + Executable memory regions demo / unit test -Executable memory regions demo / unit test + Copyright(c) 2015 Chris Eagle -Copyright(c) 2015 Chris Eagle + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + version 2 as published by the Free Software Foundation. -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -version 2 as published by the Free Software Foundation. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -*/ + */ #define __STDC_FORMAT_MACROS #include @@ -30,47 +29,47 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include unsigned char PROGRAM[] = - "\xeb\x45\x5e\x81\xe6\x00\xf0\xff\xff\x40\x40\x40\x40\x40\x40\x40" - "\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40" - "\x40\x40\x40\x40\x40\x40\x40\x89\xf7\x81\xc7\x00\x00\x10\x00\xb9" - "\x4c\x00\x00\x00\x81\xff\x00\x00\x40\x00\x75\x01\xf4\xf3\xa4\x81" - "\xe7\x00\xf0\xff\xff\xff\xe7\xe8\xb6\xff\xff\xff"; -// total size: 76 bytes + "\xeb\x45\x5e\x81\xe6\x00\xf0\xff\xff\x40\x40\x40\x40\x40\x40\x40" + "\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40" + "\x40\x40\x40\x40\x40\x40\x40\x89\xf7\x81\xc7\x00\x00\x10\x00\xb9" + "\x4c\x00\x00\x00\x81\xff\x00\x00\x40\x00\x75\x01\xf4\xf3\xa4\x81" + "\xe7\x00\xf0\xff\xff\xff\xe7\xe8\xb6\xff\xff\xff"; + // total size: 76 bytes /* -bits 32 + bits 32 -; assumes r-x section at 0x100000 -; assumes rw- section at 0x200000 -; assumes r-- section at 0x300000 -; also needs an initialized stack + ; assumes r-x section at 0x100000 + ; assumes rw- section at 0x200000 + ; assumes r-- section at 0x300000 + ; also needs an initialized stack start: - jmp bottom +jmp bottom top: - pop esi - and esi, ~0xfff - times 30 inc eax - mov edi, esi - add edi, 0x100000 - mov ecx, end - start - rep movsb - and edi, ~0xfff - cmp edi, 0x400000 - jnz next_block - hlt +pop esi +and esi, ~0xfff +times 30 inc eax +mov edi, esi +add edi, 0x100000 +mov ecx, end - start +rep movsb +and edi, ~0xfff +cmp edi, 0x400000 +jnz next_block +hlt next_block: - jmp edi +jmp edi bottom: - call top +call top end: -*/ + */ int test_num = 0; uint32_t tests[] = { - 0x41414141, - 0x43434343, - 0x45454545 + 0x41414141, + 0x43434343, + 0x45454545 }; static int log_num = 1; @@ -81,216 +80,200 @@ static int log_num = 1; // callback for tracing instruction static void hook_code(uch handle, uint64_t addr, uint32_t size, void *user_data) { - uint8_t opcode; - if (uc_mem_read(handle, addr, &opcode, 1) != UC_ERR_OK) { - printf("not ok %d - uc_mem_read fail during hook_code callback, addr: 0x%" PRIx64 "\n", log_num++, addr); - } -// printf("ok %d - uc_mem_read for opcode at address 0x%" PRIx64 "\n", log_num++, addr); - switch (opcode) { - case 0xf4: //hlt - printf("# Handling HLT\n"); - if (uc_emu_stop(handle) != UC_ERR_OK) { - printf("not ok %d - uc_emu_stop fail during hook_code callback, addr: 0x%" PRIx64 "\n", log_num++, addr); - _exit(-1); - } - else { - printf("ok %d - hlt encountered, uc_emu_stop called\n", log_num++); - } - break; - default: //all others -// printf("# Handling OTHER\n"); - break; - } + uint8_t opcode; + + if (uc_mem_read(handle, addr, &opcode, 1) != UC_ERR_OK) { + printf("not ok %d - uc_mem_read fail during hook_code callback, addr: 0x%" PRIx64 "\n", log_num++, addr); + } + + // printf("ok %d - uc_mem_read for opcode at address 0x%" PRIx64 "\n", log_num++, addr); + switch (opcode) { + case 0xf4: //hlt + printf("# Handling HLT\n"); + if (uc_emu_stop(handle) != UC_ERR_OK) { + printf("not ok %d - uc_emu_stop fail during hook_code callback, addr: 0x%" PRIx64 "\n", log_num++, addr); + _exit(-1); + } else { + printf("ok %d - hlt encountered, uc_emu_stop called\n", log_num++); + } + break; + default: //all others + // printf("# Handling OTHER\n"); + break; + } } // callback for tracing memory access (READ or WRITE) static void hook_mem_write(uch handle, uc_mem_type type, uint64_t addr, int size, int64_t value, void *user_data) { - printf("# write to memory at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n", addr, size, value); + printf("# write to memory at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n", addr, size, value); } // callback for tracing invalid memory access (READ or WRITE) static bool hook_mem_invalid(uch handle, uc_mem_type type, uint64_t addr, int size, int64_t value, void *user_data) { - switch(type) { - default: - printf("not ok %d - UC_HOOK_MEM_INVALID type: %d at 0x%" PRIx64 "\n", log_num++, type, addr); - return false; - case UC_MEM_EXEC_PROT: - printf("# Fetch from non-executable memory at 0x%"PRIx64 "\n", addr); + switch(type) { + default: + printf("not ok %d - UC_HOOK_MEM_INVALID type: %d at 0x%" PRIx64 "\n", log_num++, type, addr); + return false; + case UC_MEM_EXEC_PROT: + printf("# Fetch from non-executable memory at 0x%"PRIx64 "\n", addr); - //make page executable - if (uc_mem_protect(handle, addr & ~0xfffL, 0x1000, UC_PROT_READ | UC_PROT_EXEC) != UC_ERR_OK) { - printf("not ok %d - uc_mem_protect fail for address: 0x%" PRIx64 "\n", log_num++, addr); - } - else { - printf("ok %d - uc_mem_protect success at 0x%" PRIx64 "\n", log_num++, addr); - } - return true; - case UC_MEM_WRITE_PROT: - printf("# write to non-writeable memory at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n", addr, size, value); + //make page executable + if (uc_mem_protect(handle, addr & ~0xfffL, 0x1000, UC_PROT_READ | UC_PROT_EXEC) != UC_ERR_OK) { + printf("not ok %d - uc_mem_protect fail for address: 0x%" PRIx64 "\n", log_num++, addr); + } else { + printf("ok %d - uc_mem_protect success at 0x%" PRIx64 "\n", log_num++, addr); + } + return true; + case UC_MEM_WRITE_PROT: + printf("# write to non-writeable memory at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n", addr, size, value); - if (uc_mem_protect(handle, addr & ~0xfffL, 0x1000, UC_PROT_READ | UC_PROT_WRITE) != UC_ERR_OK) { - printf("not ok %d - uc_mem_protect fail during hook_mem_invalid callback, addr: 0x%" PRIx64 "\n", log_num++, addr); - } - else { - printf("ok %d - uc_mem_protect success\n", log_num++); - } - return true; - } + if (uc_mem_protect(handle, addr & ~0xfffL, 0x1000, UC_PROT_READ | UC_PROT_WRITE) != UC_ERR_OK) { + printf("not ok %d - uc_mem_protect fail during hook_mem_invalid callback, addr: 0x%" PRIx64 "\n", log_num++, addr); + } else { + printf("ok %d - uc_mem_protect success\n", log_num++); + } + return true; + } } int main(int argc, char **argv, char **envp) { - uch handle, trace1, trace2; - uc_err err; - uint32_t esp, eip; - int32_t buf1[1024], buf2[1024], readbuf[1024]; - int i; - - //don't really care about quality of randomness - srand(time(NULL)); - for (i = 0; i < 1024; i++) { - buf1[i] = rand(); - buf2[i] = rand(); - } + uch handle, trace1, trace2; + uc_err err; + uint32_t esp, eip; + int32_t buf1[1024], buf2[1024], readbuf[1024]; + int i; - printf("# Memory protect test\n"); + //don't really care about quality of randomness + srand(time(NULL)); + for (i = 0; i < 1024; i++) { + buf1[i] = rand(); + buf2[i] = rand(); + } - // Initialize emulator in X86-32bit mode - err = uc_open(UC_ARCH_X86, UC_MODE_32, &handle); - if (err) { - printf("not ok %d - Failed on uc_open() with error returned: %u\n", log_num++, err); - return 1; - } - else { - printf("ok %d - uc_open() success\n", log_num++); - } + printf("# Memory protect test\n"); - uc_mem_map(handle, 0x100000, 0x1000, UC_PROT_READ | UC_PROT_EXEC); - uc_mem_map(handle, 0x1ff000, 0x2000, UC_PROT_READ | UC_PROT_WRITE); - uc_mem_map(handle, 0x300000, 0x2000, UC_PROT_READ); - uc_mem_map(handle, 0xf00000, 0x1000, UC_PROT_READ | UC_PROT_WRITE); + // Initialize emulator in X86-32bit mode + err = uc_open(UC_ARCH_X86, UC_MODE_32, &handle); + if (err) { + printf("not ok %d - Failed on uc_open() with error returned: %u\n", log_num++, err); + return 1; + } else { + printf("ok %d - uc_open() success\n", log_num++); + } - esp = 0xf00000 + 0x1000; + uc_mem_map(handle, 0x100000, 0x1000, UC_PROT_READ | UC_PROT_EXEC); + uc_mem_map(handle, 0x1ff000, 0x2000, UC_PROT_READ | UC_PROT_WRITE); + uc_mem_map(handle, 0x300000, 0x2000, UC_PROT_READ); + uc_mem_map(handle, 0xf00000, 0x1000, UC_PROT_READ | UC_PROT_WRITE); - // Setup stack pointer - if (uc_reg_write(handle, UC_X86_REG_ESP, &esp)) { - printf("not ok %d - Failed to set esp. quit!\n", log_num++); - return 2; - } - else { - printf("ok %d - ESP set\n", log_num++); - } + esp = 0xf00000 + 0x1000; - // fill in sections that shouldn't get touched - if (uc_mem_write(handle, 0x1ff000, (uint8_t*)buf1, 4096)) { - printf("not ok %d - Failed to write random buffer 1 to memory, quit!\n", log_num++); - return 3; - } - else { - printf("ok %d - Random buffer 1 written to memory\n", log_num++); - } + // Setup stack pointer + if (uc_reg_write(handle, UC_X86_REG_ESP, &esp)) { + printf("not ok %d - Failed to set esp. quit!\n", log_num++); + return 2; + } else { + printf("ok %d - ESP set\n", log_num++); + } - if (uc_mem_write(handle, 0x301000, (uint8_t*)buf2, 4096)) { - printf("not ok %d - Failed to write random buffer 2 to memory, quit!\n", log_num++); - return 4; - } - else { - printf("ok %d - Random buffer 2 written to memory\n", log_num++); - } + // fill in sections that shouldn't get touched + if (uc_mem_write(handle, 0x1ff000, (uint8_t*)buf1, 4096)) { + printf("not ok %d - Failed to write random buffer 1 to memory, quit!\n", log_num++); + return 3; + } else { + printf("ok %d - Random buffer 1 written to memory\n", log_num++); + } - // write machine code to be emulated to memory - if (uc_mem_write(handle, 0x100000, PROGRAM, sizeof(PROGRAM))) { - printf("not ok %d - Failed to write emulation code to memory, quit!\n", log_num++); - return 5; - } - else { - printf("ok %d - Program written to memory\n", log_num++); - } + if (uc_mem_write(handle, 0x301000, (uint8_t*)buf2, 4096)) { + printf("not ok %d - Failed to write random buffer 2 to memory, quit!\n", log_num++); + return 4; + } else { + printf("ok %d - Random buffer 2 written to memory\n", log_num++); + } - if (uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0) != UC_ERR_OK) { - printf("not ok %d - Failed to install UC_HOOK_CODE handler\n", log_num++); - return 6; - } - else { - printf("ok %d - UC_HOOK_CODE installed\n", log_num++); - } + // write machine code to be emulated to memory + if (uc_mem_write(handle, 0x100000, PROGRAM, sizeof(PROGRAM))) { + printf("not ok %d - Failed to write emulation code to memory, quit!\n", log_num++); + return 5; + } else { + printf("ok %d - Program written to memory\n", log_num++); + } - // intercept memory write events - if (uc_hook_add(handle, &trace1, UC_HOOK_MEM_WRITE, hook_mem_write, NULL) != UC_ERR_OK) { - printf("not ok %d - Failed to install UC_HOOK_MEM_WRITE handler\n", log_num++); - return 7; - } - else { - printf("ok %d - UC_HOOK_MEM_WRITE installed\n", log_num++); - } + if (uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0) != UC_ERR_OK) { + printf("not ok %d - Failed to install UC_HOOK_CODE handler\n", log_num++); + return 6; + } else { + printf("ok %d - UC_HOOK_CODE installed\n", log_num++); + } - // intercept invalid memory events - if (uc_hook_add(handle, &trace1, UC_HOOK_MEM_INVALID, hook_mem_invalid, NULL) != UC_ERR_OK) { - printf("not ok %d - Failed to install UC_HOOK_MEM_INVALID handler\n", log_num++); - return 8; - } - else { - printf("ok %d - UC_HOOK_MEM_INVALID installed\n", log_num++); - } + // intercept memory write events + if (uc_hook_add(handle, &trace1, UC_HOOK_MEM_WRITE, hook_mem_write, NULL) != UC_ERR_OK) { + printf("not ok %d - Failed to install UC_HOOK_MEM_WRITE handler\n", log_num++); + return 7; + } else { + printf("ok %d - UC_HOOK_MEM_WRITE installed\n", log_num++); + } - // emulate machine code until told to stop by hook_code - printf("# BEGIN execution\n"); - err = uc_emu_start(handle, 0x100000, 0x400000, 0, 0); - if (err != UC_ERR_OK) { - printf("not ok %d - Failure on uc_emu_start() with error %u:%s\n", log_num++, err, uc_strerror(err)); - return 9; - } - else { - printf("ok %d - uc_emu_start complete\n", log_num++); - } - printf("# END execution\n"); + // intercept invalid memory events + if (uc_hook_add(handle, &trace1, UC_HOOK_MEM_INVALID, hook_mem_invalid, NULL) != UC_ERR_OK) { + printf("not ok %d - Failed to install UC_HOOK_MEM_INVALID handler\n", log_num++); + return 8; + } else { + printf("ok %d - UC_HOOK_MEM_INVALID installed\n", log_num++); + } - // get ending EIP - if (uc_reg_read(handle, UC_X86_REG_EIP, &eip)) { - printf("not ok %d - Failed to read eip.\n", log_num++); - } - else { - printf("ok %d - Ending EIP 0x%x\n", log_num++, eip); - } + // emulate machine code until told to stop by hook_code + printf("# BEGIN execution\n"); + err = uc_emu_start(handle, 0x100000, 0x400000, 0, 0); + if (err != UC_ERR_OK) { + printf("not ok %d - Failure on uc_emu_start() with error %u:%s\n", log_num++, err, uc_strerror(err)); + return 9; + } else { + printf("ok %d - uc_emu_start complete\n", log_num++); + } + printf("# END execution\n"); - //make sure that random blocks didn't get nuked - // fill in sections that shouldn't get touched - if (uc_mem_read(handle, 0x1ff000, (uint8_t*)readbuf, 4096)) { - printf("not ok %d - Failed to read random buffer 1 from memory\n", log_num++); - } - else { - printf("ok %d - Random buffer 1 read from memory\n", log_num++); - if (memcmp(buf1, readbuf, 4096)) { - printf("not ok %d - Random buffer 1 contents are incorrect\n", log_num++); - } - else { - printf("ok %d - Random buffer 1 contents are correct\n", log_num++); - } - } + // get ending EIP + if (uc_reg_read(handle, UC_X86_REG_EIP, &eip)) { + printf("not ok %d - Failed to read eip.\n", log_num++); + } else { + printf("ok %d - Ending EIP 0x%x\n", log_num++, eip); + } - if (uc_mem_read(handle, 0x301000, (uint8_t*)readbuf, 4096)) { - printf("not ok %d - Failed to read random buffer 2 from memory\n", log_num++); - } - else { - printf("ok %d - Random buffer 2 read from memory\n", log_num++); - if (memcmp(buf2, readbuf, 4096)) { - printf("not ok %d - Random buffer 2 contents are incorrect\n", log_num++); - } - else { - printf("ok %d - Random buffer 2 contents are correct\n", log_num++); - } - } + //make sure that random blocks didn't get nuked + // fill in sections that shouldn't get touched + if (uc_mem_read(handle, 0x1ff000, (uint8_t*)readbuf, 4096)) { + printf("not ok %d - Failed to read random buffer 1 from memory\n", log_num++); + } else { + printf("ok %d - Random buffer 1 read from memory\n", log_num++); + if (memcmp(buf1, readbuf, 4096)) { + printf("not ok %d - Random buffer 1 contents are incorrect\n", log_num++); + } else { + printf("ok %d - Random buffer 1 contents are correct\n", log_num++); + } + } - if (uc_close(&handle) == UC_ERR_OK) { - printf("ok %d - uc_close complete\n", log_num++); - } - else { - printf("not ok %d - uc_close complete\n", log_num++); - } + if (uc_mem_read(handle, 0x301000, (uint8_t*)readbuf, 4096)) { + printf("not ok %d - Failed to read random buffer 2 from memory\n", log_num++); + } else { + printf("ok %d - Random buffer 2 read from memory\n", log_num++); + if (memcmp(buf2, readbuf, 4096)) { + printf("not ok %d - Random buffer 2 contents are incorrect\n", log_num++); + } else { + printf("ok %d - Random buffer 2 contents are correct\n", log_num++); + } + } - return 0; + if (uc_close(&handle) == UC_ERR_OK) { + printf("ok %d - uc_close complete\n", log_num++); + } else { + printf("not ok %d - uc_close complete\n", log_num++); + } + + return 0; } diff --git a/samples/mem_protect.c b/samples/mem_protect.c index 5d852ff5..5739563e 100644 --- a/samples/mem_protect.c +++ b/samples/mem_protect.c @@ -1,23 +1,22 @@ /* + uc_mem_protect demo / unit test -uc_mem_protect demo / unit test + Copyright(c) 2015 Chris Eagle -Copyright(c) 2015 Chris Eagle + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + version 2 as published by the Free Software Foundation. -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -version 2 as published by the Free Software Foundation. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -*/ + */ #define __STDC_FORMAT_MACROS #include @@ -30,23 +29,23 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include unsigned char PROGRAM[] = - "\xc7\x05\x00\x00\x20\x00\x41\x41\x41\x41\x90\xc7\x05\x00\x00\x20" - "\x00\x42\x42\x42\x42\xc7\x05\x00\x00\x30\x00\x43\x43\x43\x43\x90" - "\xc7\x05\x00\x00\x30\x00\x44\x44\x44\x44\xc7\x05\x00\x00\x40\x00" - "\x45\x45\x45\x45\x90\xc7\x05\x00\x00\x40\x00\x46\x46\x46\x46\xc7" - "\x05\x00\xf8\x3f\x00\x47\x47\x47\x47\xc7\x05\x00\x18\x40\x00\x48" - "\x48\x48\x48\xf4"; -// total size: 84 bytes + "\xc7\x05\x00\x00\x20\x00\x41\x41\x41\x41\x90\xc7\x05\x00\x00\x20" + "\x00\x42\x42\x42\x42\xc7\x05\x00\x00\x30\x00\x43\x43\x43\x43\x90" + "\xc7\x05\x00\x00\x30\x00\x44\x44\x44\x44\xc7\x05\x00\x00\x40\x00" + "\x45\x45\x45\x45\x90\xc7\x05\x00\x00\x40\x00\x46\x46\x46\x46\xc7" + "\x05\x00\xf8\x3f\x00\x47\x47\x47\x47\xc7\x05\x00\x18\x40\x00\x48" + "\x48\x48\x48\xf4"; + // total size: 84 bytes /* -bits 32 + bits 32 -; assumes code section at 0x100000 -; assumes data section at 0x200000, initially rw -; assumes data section at 0x300000, initially rw -; assumes data section at 0x400000, initially rw + ; assumes code section at 0x100000 + ; assumes data section at 0x200000, initially rw + ; assumes data section at 0x300000, initially rw + ; assumes data section at 0x400000, initially rw -; with installed hooks unmaps or maps on each nop + ; with installed hooks unmaps or maps on each nop mov dword [0x200000], 0x41414141 nop ; mark it RO @@ -63,13 +62,13 @@ bits 32 mov dword [0x401800], 0x48484848 ; make sure surrounding areas remained RW hlt ; tell hook function we are done -*/ + */ int test_num = 0; uint32_t tests[] = { - 0x41414141, - 0x43434343, - 0x45454545 + 0x41414141, + 0x43434343, + 0x45454545 }; static int log_num = 1; @@ -80,244 +79,223 @@ static int log_num = 1; // callback for tracing instruction static void hook_code(uch handle, uint64_t addr, uint32_t size, void *user_data) { - uint8_t opcode; - uint32_t testval; - if (uc_mem_read(handle, addr, &opcode, 1) != UC_ERR_OK) { - printf("not ok %d - uc_mem_read fail during hook_code callback, addr: 0x%" PRIx64 "\n", log_num++, addr); - } - printf("ok %d - uc_mem_read for opcode at address 0x%" PRIx64 "\n", log_num++, addr); - switch (opcode) { - case 0x90: //nop - printf("# Handling NOP\n"); - if (uc_mem_read(handle, 0x200000 + test_num * 0x100000, (uint8_t*)&testval, sizeof(testval)) != UC_ERR_OK) { - printf("not ok %d - uc_mem_read fail for address: 0x%x\n", log_num++, 0x200000 + test_num * 0x100000); - } - else { - printf("ok %d - good uc_mem_read for address: 0x%x\n", log_num++, 0x200000 + test_num * 0x100000); - printf("# uc_mem_read for test %d\n", test_num); + uint8_t opcode; + uint32_t testval; + if (uc_mem_read(handle, addr, &opcode, 1) != UC_ERR_OK) { + printf("not ok %d - uc_mem_read fail during hook_code callback, addr: 0x%" PRIx64 "\n", log_num++, addr); + } + printf("ok %d - uc_mem_read for opcode at address 0x%" PRIx64 "\n", log_num++, addr); + switch (opcode) { + case 0x90: //nop + printf("# Handling NOP\n"); + if (uc_mem_read(handle, 0x200000 + test_num * 0x100000, (uint8_t*)&testval, sizeof(testval)) != UC_ERR_OK) { + printf("not ok %d - uc_mem_read fail for address: 0x%x\n", log_num++, 0x200000 + test_num * 0x100000); + } else { + printf("ok %d - good uc_mem_read for address: 0x%x\n", log_num++, 0x200000 + test_num * 0x100000); + printf("# uc_mem_read for test %d\n", test_num); - if (testval == tests[test_num]) { - printf("ok %d - passed test %d\n", log_num++, test_num); + if (testval == tests[test_num]) { + printf("ok %d - passed test %d\n", log_num++, test_num); + } else { + printf("not ok %d - failed test %d\n", log_num++, test_num); + printf("# Expected: 0x%x\n",tests[test_num]); + printf("# Received: 0x%x\n", testval); + } } - else { - printf("not ok %d - failed test %d\n", log_num++, test_num); - printf("# Expected: 0x%x\n",tests[test_num]); - printf("# Received: 0x%x\n", testval); + if (uc_mem_protect(handle, 0x200000 + test_num * 0x100000, 0x1000, UC_PROT_READ) != UC_ERR_OK) { + printf("not ok %d - uc_mem_protect fail during hook_code callback, addr: 0x%x\n", log_num++, 0x200000 + test_num * 0x100000); + } else { + printf("ok %d - uc_mem_protect success\n", log_num++); } - } - if (uc_mem_protect(handle, 0x200000 + test_num * 0x100000, 0x1000, UC_PROT_READ) != UC_ERR_OK) { - printf("not ok %d - uc_mem_protect fail during hook_code callback, addr: 0x%x\n", log_num++, 0x200000 + test_num * 0x100000); - } - else { - printf("ok %d - uc_mem_protect success\n", log_num++); - } - test_num++; - break; - case 0xf4: //hlt - printf("# Handling HLT\n"); - if (uc_emu_stop(handle) != UC_ERR_OK) { - printf("not ok %d - uc_emu_stop fail during hook_code callback, addr: 0x%" PRIx64 "\n", log_num++, addr); - _exit(-1); - } - else { - printf("ok %d - hlt encountered, uc_emu_stop called\n", log_num++); - } - break; - default: //all others - printf("# Handling OTHER\n"); - break; - } + test_num++; + break; + case 0xf4: //hlt + printf("# Handling HLT\n"); + if (uc_emu_stop(handle) != UC_ERR_OK) { + printf("not ok %d - uc_emu_stop fail during hook_code callback, addr: 0x%" PRIx64 "\n", log_num++, addr); + _exit(-1); + } else { + printf("ok %d - hlt encountered, uc_emu_stop called\n", log_num++); + } + break; + default: //all others + printf("# Handling OTHER\n"); + break; + } } // callback for tracing memory access (READ or WRITE) static void hook_mem_write(uch handle, uc_mem_type type, uint64_t addr, int size, int64_t value, void *user_data) { - printf("# write to memory at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n", addr, size, value); + printf("# write to memory at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n", addr, size, value); } // callback for tracing invalid memory access (READ or WRITE) static bool hook_mem_invalid(uch handle, uc_mem_type type, uint64_t addr, int size, int64_t value, void *user_data) { - uint32_t testval; - switch(type) { - default: - printf("not ok %d - UC_HOOK_MEM_INVALID type: %d at 0x%" PRIx64 "\n", log_num++, type, addr); - return false; - case UC_MEM_WRITE_PROT: - printf("# write to non-writeable memory at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n", addr, size, value); + uint32_t testval; + switch(type) { + default: + printf("not ok %d - UC_HOOK_MEM_INVALID type: %d at 0x%" PRIx64 "\n", log_num++, type, addr); + return false; + case UC_MEM_WRITE_PROT: + printf("# write to non-writeable memory at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n", addr, size, value); - if (uc_mem_read(handle, addr, (uint8_t*)&testval, sizeof(testval)) != UC_ERR_OK) { - printf("not ok %d - uc_mem_read fail for address: 0x%" PRIx64 "\n", log_num++, addr); - } - else { - printf("ok %d - uc_mem_read success after mem_protect at test %d\n", log_num++, test_num - 1); - } + if (uc_mem_read(handle, addr, (uint8_t*)&testval, sizeof(testval)) != UC_ERR_OK) { + printf("not ok %d - uc_mem_read fail for address: 0x%" PRIx64 "\n", log_num++, addr); + } else { + printf("ok %d - uc_mem_read success after mem_protect at test %d\n", log_num++, test_num - 1); + } - if (uc_mem_protect(handle, addr & ~0xfffL, 0x1000, UC_PROT_READ | UC_PROT_WRITE) != UC_ERR_OK) { - printf("not ok %d - uc_mem_protect fail during hook_mem_invalid callback, addr: 0x%" PRIx64 "\n", log_num++, addr); - } - else { - printf("ok %d - uc_mem_protect success\n", log_num++); - } - return true; - } + if (uc_mem_protect(handle, addr & ~0xfffL, 0x1000, UC_PROT_READ | UC_PROT_WRITE) != UC_ERR_OK) { + printf("not ok %d - uc_mem_protect fail during hook_mem_invalid callback, addr: 0x%" PRIx64 "\n", log_num++, addr); + } else { + printf("ok %d - uc_mem_protect success\n", log_num++); + } + return true; + } } int main(int argc, char **argv, char **envp) { - uch handle, trace1, trace2; - uc_err err; - uint32_t addr, testval; - int32_t buf1[1024], buf2[1024], readbuf[1024]; - int i; - - //don't really care about quality of randomness - srand(time(NULL)); - for (i = 0; i < 1024; i++) { - buf1[i] = rand(); - buf2[i] = rand(); - } + uch handle, trace1, trace2; + uc_err err; + uint32_t addr, testval; + int32_t buf1[1024], buf2[1024], readbuf[1024]; + int i; - printf("# Memory protect test\n"); + //don't really care about quality of randomness + srand(time(NULL)); + for (i = 0; i < 1024; i++) { + buf1[i] = rand(); + buf2[i] = rand(); + } - // Initialize emulator in X86-32bit mode - err = uc_open(UC_ARCH_X86, UC_MODE_32, &handle); - if (err) { - printf("not ok %d - Failed on uc_open() with error returned: %u\n", log_num++, err); - return 1; - } - else { - printf("ok %d - uc_open() success\n", log_num++); - } + printf("# Memory protect test\n"); - uc_mem_map(handle, CODE_SECTION, CODE_SIZE, UC_PROT_READ | UC_PROT_EXEC); - uc_mem_map(handle, 0x200000, 0x1000, UC_PROT_READ | UC_PROT_WRITE); - uc_mem_map(handle, 0x300000, 0x1000, UC_PROT_READ | UC_PROT_WRITE); - uc_mem_map(handle, 0x3ff000, 0x3000, UC_PROT_READ | UC_PROT_WRITE); + // Initialize emulator in X86-32bit mode + err = uc_open(UC_ARCH_X86, UC_MODE_32, &handle); + if (err) { + printf("not ok %d - Failed on uc_open() with error returned: %u\n", log_num++, err); + return 1; + } else { + printf("ok %d - uc_open() success\n", log_num++); + } - // fill in sections that shouldn't get touched - if (uc_mem_write(handle, 0x3ff000, (uint8_t*)buf1, 4096)) { - printf("not ok %d - Failed to write random buffer 1 to memory, quit!\n", log_num++); - return 2; - } - else { - printf("ok %d - Random buffer 1 written to memory\n", log_num++); - } + uc_mem_map(handle, CODE_SECTION, CODE_SIZE, UC_PROT_READ | UC_PROT_EXEC); + uc_mem_map(handle, 0x200000, 0x1000, UC_PROT_READ | UC_PROT_WRITE); + uc_mem_map(handle, 0x300000, 0x1000, UC_PROT_READ | UC_PROT_WRITE); + uc_mem_map(handle, 0x3ff000, 0x3000, UC_PROT_READ | UC_PROT_WRITE); - if (uc_mem_write(handle, 0x401000, (uint8_t*)buf2, 4096)) { - printf("not ok %d - Failed to write random buffer 2 to memory, quit!\n", log_num++); - return 3; - } - else { - printf("ok %d - Random buffer 2 written to memory\n", log_num++); - } + // fill in sections that shouldn't get touched + if (uc_mem_write(handle, 0x3ff000, (uint8_t*)buf1, 4096)) { + printf("not ok %d - Failed to write random buffer 1 to memory, quit!\n", log_num++); + return 2; + } else { + printf("ok %d - Random buffer 1 written to memory\n", log_num++); + } - // write machine code to be emulated to memory - if (uc_mem_write(handle, CODE_SECTION, PROGRAM, sizeof(PROGRAM))) { - printf("not ok %d - Failed to write emulation code to memory, quit!\n", log_num++); - return 4; - } - else { - printf("ok %d - Program written to memory\n", log_num++); - } + if (uc_mem_write(handle, 0x401000, (uint8_t*)buf2, 4096)) { + printf("not ok %d - Failed to write random buffer 2 to memory, quit!\n", log_num++); + return 3; + } else { + printf("ok %d - Random buffer 2 written to memory\n", log_num++); + } - if (uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0) != UC_ERR_OK) { - printf("not ok %d - Failed to install UC_HOOK_CODE handler\n", log_num++); - return 5; - } - else { - printf("ok %d - UC_HOOK_CODE installed\n", log_num++); - } + // write machine code to be emulated to memory + if (uc_mem_write(handle, CODE_SECTION, PROGRAM, sizeof(PROGRAM))) { + printf("not ok %d - Failed to write emulation code to memory, quit!\n", log_num++); + return 4; + } else { + printf("ok %d - Program written to memory\n", log_num++); + } - // intercept memory write events - if (uc_hook_add(handle, &trace1, UC_HOOK_MEM_WRITE, hook_mem_write, NULL) != UC_ERR_OK) { - printf("not ok %d - Failed to install UC_HOOK_MEM_WRITE handler\n", log_num++); - return 6; - } - else { - printf("ok %d - UC_HOOK_MEM_WRITE installed\n", log_num++); - } + if (uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0) != UC_ERR_OK) { + printf("not ok %d - Failed to install UC_HOOK_CODE handler\n", log_num++); + return 5; + } else { + printf("ok %d - UC_HOOK_CODE installed\n", log_num++); + } - // intercept invalid memory events - if (uc_hook_add(handle, &trace1, UC_HOOK_MEM_INVALID, hook_mem_invalid, NULL) != UC_ERR_OK) { - printf("not ok %d - Failed to install UC_HOOK_MEM_INVALID handler\n", log_num++); - return 7; - } - else { - printf("ok %d - UC_HOOK_MEM_INVALID installed\n", log_num++); - } + // intercept memory write events + if (uc_hook_add(handle, &trace1, UC_HOOK_MEM_WRITE, hook_mem_write, NULL) != UC_ERR_OK) { + printf("not ok %d - Failed to install UC_HOOK_MEM_WRITE handler\n", log_num++); + return 6; + } else { + printf("ok %d - UC_HOOK_MEM_WRITE installed\n", log_num++); + } - // emulate machine code until told to stop by hook_code - printf("# BEGIN execution\n"); - err = uc_emu_start(handle, CODE_SECTION, CODE_SECTION + CODE_SIZE, 0, 0); - if (err != UC_ERR_OK) { - printf("not ok %d - Failure on uc_emu_start() with error %u:%s\n", log_num++, err, uc_strerror(err)); - return 8; - } - else { - printf("ok %d - uc_emu_start complete\n", log_num++); - } - printf("# END execution\n"); + // intercept invalid memory events + if (uc_hook_add(handle, &trace1, UC_HOOK_MEM_INVALID, hook_mem_invalid, NULL) != UC_ERR_OK) { + printf("not ok %d - Failed to install UC_HOOK_MEM_INVALID handler\n", log_num++); + return 7; + } else { + printf("ok %d - UC_HOOK_MEM_INVALID installed\n", log_num++); + } - //read from the remapped memory - testval = 0x42424242; - for (addr = 0x200000; addr <= 0x400000; addr += 0x100000) { - uint32_t val; - if (uc_mem_read(handle, addr, (uint8_t*)&val, sizeof(val)) != UC_ERR_OK) { - printf("not ok %d - Failed uc_mem_read for address 0x%x\n", log_num++, addr); - } - else { - printf("ok %d - Good uc_mem_read from 0x%x\n", log_num++, addr); - } - if (val != testval) { - printf("not ok %d - Read 0x%x, expected 0x%x\n", log_num++, val, testval); - } - else { - printf("ok %d - Correct value retrieved\n", log_num++); - } - testval += 0x02020202; - } + // emulate machine code until told to stop by hook_code + printf("# BEGIN execution\n"); + err = uc_emu_start(handle, CODE_SECTION, CODE_SECTION + CODE_SIZE, 0, 0); + if (err != UC_ERR_OK) { + printf("not ok %d - Failure on uc_emu_start() with error %u:%s\n", log_num++, err, uc_strerror(err)); + return 8; + } else { + printf("ok %d - uc_emu_start complete\n", log_num++); + } + printf("# END execution\n"); - //account for the two mods made by the machine code - buf1[512] = 0x47474747; - buf2[512] = 0x48484848; + //read from the remapped memory + testval = 0x42424242; + for (addr = 0x200000; addr <= 0x400000; addr += 0x100000) { + uint32_t val; + if (uc_mem_read(handle, addr, (uint8_t*)&val, sizeof(val)) != UC_ERR_OK) { + printf("not ok %d - Failed uc_mem_read for address 0x%x\n", log_num++, addr); + } else { + printf("ok %d - Good uc_mem_read from 0x%x\n", log_num++, addr); + } + if (val != testval) { + printf("not ok %d - Read 0x%x, expected 0x%x\n", log_num++, val, testval); + } else { + printf("ok %d - Correct value retrieved\n", log_num++); + } + testval += 0x02020202; + } - //make sure that random blocks didn't get nuked - // fill in sections that shouldn't get touched - if (uc_mem_read(handle, 0x3ff000, (uint8_t*)readbuf, 4096)) { - printf("not ok %d - Failed to read random buffer 1 from memory\n", log_num++); - } - else { - printf("ok %d - Random buffer 1 read from memory\n", log_num++); - if (memcmp(buf1, readbuf, 4096)) { - printf("not ok %d - Random buffer 1 contents are incorrect\n", log_num++); - } - else { - printf("ok %d - Random buffer 1 contents are correct\n", log_num++); - } - } + //account for the two mods made by the machine code + buf1[512] = 0x47474747; + buf2[512] = 0x48484848; - if (uc_mem_read(handle, 0x401000, (uint8_t*)readbuf, 4096)) { - printf("not ok %d - Failed to read random buffer 2 from memory\n", log_num++); - } - else { - printf("ok %d - Random buffer 2 read from memory\n", log_num++); - if (memcmp(buf2, readbuf, 4096)) { - printf("not ok %d - Random buffer 2 contents are incorrect\n", log_num++); - } - else { - printf("ok %d - Random buffer 2 contents are correct\n", log_num++); - } - } + //make sure that random blocks didn't get nuked + // fill in sections that shouldn't get touched + if (uc_mem_read(handle, 0x3ff000, (uint8_t*)readbuf, 4096)) { + printf("not ok %d - Failed to read random buffer 1 from memory\n", log_num++); + } else { + printf("ok %d - Random buffer 1 read from memory\n", log_num++); + if (memcmp(buf1, readbuf, 4096)) { + printf("not ok %d - Random buffer 1 contents are incorrect\n", log_num++); + } else { + printf("ok %d - Random buffer 1 contents are correct\n", log_num++); + } + } - if (uc_close(&handle) == UC_ERR_OK) { - printf("ok %d - uc_close complete\n", log_num++); - } - else { - printf("not ok %d - uc_close complete\n", log_num++); - } + if (uc_mem_read(handle, 0x401000, (uint8_t*)readbuf, 4096)) { + printf("not ok %d - Failed to read random buffer 2 from memory\n", log_num++); + } else { + printf("ok %d - Random buffer 2 read from memory\n", log_num++); + if (memcmp(buf2, readbuf, 4096)) { + printf("not ok %d - Random buffer 2 contents are incorrect\n", log_num++); + } else { + printf("ok %d - Random buffer 2 contents are correct\n", log_num++); + } + } - return 0; + if (uc_close(&handle) == UC_ERR_OK) { + printf("ok %d - uc_close complete\n", log_num++); + } else { + printf("not ok %d - uc_close complete\n", log_num++); + } + + return 0; } diff --git a/samples/mem_unmap.c b/samples/mem_unmap.c index 6f93673d..b31bf220 100644 --- a/samples/mem_unmap.c +++ b/samples/mem_unmap.c @@ -1,23 +1,23 @@ /* -uc_mem_unmap demo / unit test + uc_mem_unmap demo / unit test -Copyright(c) 2015 Chris Eagle + Copyright(c) 2015 Chris Eagle -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -version 2 as published by the Free Software Foundation. + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + version 2 as published by the Free Software Foundation. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ + */ #define __STDC_FORMAT_MACROS #include @@ -30,19 +30,19 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include unsigned char PROGRAM[] = - "\xc7\x05\x00\x00\x20\x00\x41\x41\x41\x41\x90\xc7\x05\x00\x00\x20" - "\x00\x42\x42\x42\x42\xc7\x05\x00\x00\x30\x00\x43\x43\x43\x43\x90" - "\xc7\x05\x00\x00\x30\x00\x44\x44\x44\x44\xc7\x05\x00\x00\x40\x00" - "\x45\x45\x45\x45\x90\xc7\x05\x00\x00\x40\x00\x46\x46\x46\x46\xf4"; -// total size: 64 bytes + "\xc7\x05\x00\x00\x20\x00\x41\x41\x41\x41\x90\xc7\x05\x00\x00\x20" + "\x00\x42\x42\x42\x42\xc7\x05\x00\x00\x30\x00\x43\x43\x43\x43\x90" + "\xc7\x05\x00\x00\x30\x00\x44\x44\x44\x44\xc7\x05\x00\x00\x40\x00" + "\x45\x45\x45\x45\x90\xc7\x05\x00\x00\x40\x00\x46\x46\x46\x46\xf4"; + // total size: 64 bytes /* -; assumes code section at 0x100000 -; assumes data section at 0x200000, initially rw -; assumes data section at 0x300000, initially rw -; assumes data section at 0x400000, initially rw + ; assumes code section at 0x100000 + ; assumes data section at 0x200000, initially rw + ; assumes data section at 0x300000, initially rw + ; assumes data section at 0x400000, initially rw -; with installed hooks unmaps or maps on each nop + ; with installed hooks unmaps or maps on each nop mov dword [0x200000], 0x41414141 nop ; unmap it @@ -57,13 +57,13 @@ unsigned char PROGRAM[] = mov dword [0x400000], 0x46464646 hlt ; tell hook function we are done -*/ + */ int test_num = 0; uint32_t tests[] = { - 0x41414141, - 0x43434343, - 0x45454545 + 0x41414141, + 0x43434343, + 0x45454545 }; static int log_num = 1; @@ -74,240 +74,219 @@ static int log_num = 1; // callback for tracing instruction static void hook_code(uch handle, uint64_t addr, uint32_t size, void *user_data) { - uint8_t opcode; - uint32_t testval; - if (uc_mem_read(handle, addr, &opcode, 1) != UC_ERR_OK) { - printf("not ok %d - uc_mem_read fail during hook_code callback, addr: 0x%" PRIx64 "\n", log_num++, addr); - } - printf("ok %d - uc_mem_read for opcode at address 0x%" PRIx64 "\n", log_num++, addr); - switch (opcode) { - case 0x90: //nop - printf("# Handling NOP\n"); - if (uc_mem_read(handle, 0x200000 + test_num * 0x100000, (uint8_t*)&testval, sizeof(testval)) != UC_ERR_OK) { - printf("not ok %d - uc_mem_read fail for address: 0x%x\n", log_num++, 0x200000 + test_num * 0x100000); - } - else { - printf("ok %d - good uc_mem_read for address: 0x%x\n", log_num++, 0x200000 + test_num * 0x100000); - printf("# uc_mem_read for test %d\n", test_num); + uint8_t opcode; + uint32_t testval; + if (uc_mem_read(handle, addr, &opcode, 1) != UC_ERR_OK) { + printf("not ok %d - uc_mem_read fail during hook_code callback, addr: 0x%" PRIx64 "\n", log_num++, addr); + } + printf("ok %d - uc_mem_read for opcode at address 0x%" PRIx64 "\n", log_num++, addr); + switch (opcode) { + case 0x90: //nop + printf("# Handling NOP\n"); + if (uc_mem_read(handle, 0x200000 + test_num * 0x100000, (uint8_t*)&testval, sizeof(testval)) != UC_ERR_OK) { + printf("not ok %d - uc_mem_read fail for address: 0x%x\n", log_num++, 0x200000 + test_num * 0x100000); + } else { + printf("ok %d - good uc_mem_read for address: 0x%x\n", log_num++, 0x200000 + test_num * 0x100000); + printf("# uc_mem_read for test %d\n", test_num); - if (testval == tests[test_num]) { - printf("ok %d - passed test %d\n", log_num++, test_num); + if (testval == tests[test_num]) { + printf("ok %d - passed test %d\n", log_num++, test_num); + } else { + printf("not ok %d - failed test %d\n", log_num++, test_num); + printf("# Expected: 0x%x\n",tests[test_num]); + printf("# Received: 0x%x\n", testval); + } } - else { - printf("not ok %d - failed test %d\n", log_num++, test_num); - printf("# Expected: 0x%x\n",tests[test_num]); - printf("# Received: 0x%x\n", testval); + if (uc_mem_unmap(handle, 0x200000 + test_num * 0x100000, 0x1000) != UC_ERR_OK) { + printf("not ok %d - uc_mem_unmap fail during hook_code callback, addr: 0x%x\n", log_num++, 0x200000 + test_num * 0x100000); + } else { + printf("ok %d - uc_mem_unmap success\n", log_num++); } - } - if (uc_mem_unmap(handle, 0x200000 + test_num * 0x100000, 0x1000) != UC_ERR_OK) { - printf("not ok %d - uc_mem_unmap fail during hook_code callback, addr: 0x%x\n", log_num++, 0x200000 + test_num * 0x100000); - } - else { - printf("ok %d - uc_mem_unmap success\n", log_num++); - } - test_num++; - break; - case 0xf4: //hlt - printf("# Handling HLT\n"); - if (uc_emu_stop(handle) != UC_ERR_OK) { - printf("not ok %d - uc_emu_stop fail during hook_code callback, addr: 0x%" PRIx64 "\n", log_num++, addr); - _exit(-1); - } - else { - printf("ok %d - hlt encountered, uc_emu_stop called\n", log_num++); - } - break; - default: //all others - printf("# Handling OTHER\n"); - break; - } + test_num++; + break; + case 0xf4: //hlt + printf("# Handling HLT\n"); + if (uc_emu_stop(handle) != UC_ERR_OK) { + printf("not ok %d - uc_emu_stop fail during hook_code callback, addr: 0x%" PRIx64 "\n", log_num++, addr); + _exit(-1); + } else { + printf("ok %d - hlt encountered, uc_emu_stop called\n", log_num++); + } + break; + default: //all others + printf("# Handling OTHER\n"); + break; + } } // callback for tracing memory access (READ or WRITE) static void hook_mem_write(uch handle, uc_mem_type type, uint64_t addr, int size, int64_t value, void *user_data) { - printf("# write to memory at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n", addr, size, value); + printf("# write to memory at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n", addr, size, value); } // callback for tracing invalid memory access (READ or WRITE) static bool hook_mem_invalid(uch handle, uc_mem_type type, uint64_t addr, int size, int64_t value, void *user_data) { - uint32_t testval; - switch(type) { - default: - printf("not ok %d - UC_HOOK_MEM_INVALID type: %d at 0x%" PRIx64 "\n", log_num++, type, addr); - return false; - case UC_MEM_WRITE: - printf("# write to invalid memory at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n", addr, size, value); + uint32_t testval; + switch(type) { + default: + printf("not ok %d - UC_HOOK_MEM_INVALID type: %d at 0x%" PRIx64 "\n", log_num++, type, addr); + return false; + case UC_MEM_WRITE: + printf("# write to invalid memory at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n", addr, size, value); - if (uc_mem_read(handle, addr, (uint8_t*)&testval, sizeof(testval)) != UC_ERR_OK) { - printf("ok %d - uc_mem_read fail for address: 0x%" PRIx64 "\n", log_num++, addr); - } - else { - printf("not ok %d - uc_mem_read success after unmap at test %d\n", log_num++, test_num - 1); - } + if (uc_mem_read(handle, addr, (uint8_t*)&testval, sizeof(testval)) != UC_ERR_OK) { + printf("ok %d - uc_mem_read fail for address: 0x%" PRIx64 "\n", log_num++, addr); + } else { + printf("not ok %d - uc_mem_read success after unmap at test %d\n", log_num++, test_num - 1); + } - if (uc_mem_map(handle, addr & ~0xfffL, 0x1000, UC_PROT_READ | UC_PROT_WRITE) != UC_ERR_OK) { - printf("not ok %d - uc_mem_map fail during hook_mem_invalid callback, addr: 0x%" PRIx64 "\n", log_num++, addr); - } - else { - printf("ok %d - uc_mem_map success\n", log_num++); - } - return true; - } + if (uc_mem_map(handle, addr & ~0xfffL, 0x1000, UC_PROT_READ | UC_PROT_WRITE) != UC_ERR_OK) { + printf("not ok %d - uc_mem_map fail during hook_mem_invalid callback, addr: 0x%" PRIx64 "\n", log_num++, addr); + } else { + printf("ok %d - uc_mem_map success\n", log_num++); + } + return true; + } } int main(int argc, char **argv, char **envp) { - uch handle, trace1, trace2; - uc_err err; - uint32_t addr, testval; - int32_t buf1[1024], buf2[1024], readbuf[1024]; - int i; - - //don't really care about quality of randomness - srand(time(NULL)); - for (i = 0; i < 1024; i++) { - buf1[i] = rand(); - buf2[i] = rand(); - } + uch handle, trace1, trace2; + uc_err err; + uint32_t addr, testval; + int32_t buf1[1024], buf2[1024], readbuf[1024]; + int i; - printf("# Memory unmapping test\n"); + //don't really care about quality of randomness + srand(time(NULL)); + for (i = 0; i < 1024; i++) { + buf1[i] = rand(); + buf2[i] = rand(); + } - // Initialize emulator in X86-32bit mode - err = uc_open(UC_ARCH_X86, UC_MODE_32, &handle); - if (err) { - printf("not ok %d - Failed on uc_open() with error returned: %u\n", log_num++, err); - return 1; - } - else { - printf("ok %d - uc_open() success\n", log_num++); - } + printf("# Memory unmapping test\n"); - uc_mem_map(handle, CODE_SECTION, CODE_SIZE, UC_PROT_READ | UC_PROT_EXEC); - uc_mem_map(handle, 0x200000, 0x1000, UC_PROT_READ | UC_PROT_WRITE); - uc_mem_map(handle, 0x300000, 0x1000, UC_PROT_READ | UC_PROT_WRITE); - uc_mem_map(handle, 0x3ff000, 0x3000, UC_PROT_READ | UC_PROT_WRITE); + // Initialize emulator in X86-32bit mode + err = uc_open(UC_ARCH_X86, UC_MODE_32, &handle); + if (err) { + printf("not ok %d - Failed on uc_open() with error returned: %u\n", log_num++, err); + return 1; + } else { + printf("ok %d - uc_open() success\n", log_num++); + } - // fill in sections that shouldn't get touched - if (uc_mem_write(handle, 0x3ff000, (uint8_t*)buf1, 4096)) { - printf("not ok %d - Failed to write random buffer 1 to memory, quit!\n", log_num++); - return 2; - } - else { - printf("ok %d - Random buffer 1 written to memory\n", log_num++); - } + uc_mem_map(handle, CODE_SECTION, CODE_SIZE, UC_PROT_READ | UC_PROT_EXEC); + uc_mem_map(handle, 0x200000, 0x1000, UC_PROT_READ | UC_PROT_WRITE); + uc_mem_map(handle, 0x300000, 0x1000, UC_PROT_READ | UC_PROT_WRITE); + uc_mem_map(handle, 0x3ff000, 0x3000, UC_PROT_READ | UC_PROT_WRITE); - if (uc_mem_write(handle, 0x401000, (uint8_t*)buf2, 4096)) { - printf("not ok %d - Failed to write random buffer 2 to memory, quit!\n", log_num++); - return 3; - } - else { - printf("ok %d - Random buffer 2 written to memory\n", log_num++); - } + // fill in sections that shouldn't get touched + if (uc_mem_write(handle, 0x3ff000, (uint8_t*)buf1, 4096)) { + printf("not ok %d - Failed to write random buffer 1 to memory, quit!\n", log_num++); + return 2; + } else { + printf("ok %d - Random buffer 1 written to memory\n", log_num++); + } - // write machine code to be emulated to memory - if (uc_mem_write(handle, CODE_SECTION, PROGRAM, sizeof(PROGRAM))) { - printf("not ok %d - Failed to write emulation code to memory, quit!\n", log_num++); - return 4; - } - else { - printf("ok %d - Program written to memory\n", log_num++); - } + if (uc_mem_write(handle, 0x401000, (uint8_t*)buf2, 4096)) { + printf("not ok %d - Failed to write random buffer 2 to memory, quit!\n", log_num++); + return 3; + } else { + printf("ok %d - Random buffer 2 written to memory\n", log_num++); + } - if (uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0) != UC_ERR_OK) { - printf("not ok %d - Failed to install UC_HOOK_CODE handler\n", log_num++); - return 5; - } - else { - printf("ok %d - UC_HOOK_CODE installed\n", log_num++); - } + // write machine code to be emulated to memory + if (uc_mem_write(handle, CODE_SECTION, PROGRAM, sizeof(PROGRAM))) { + printf("not ok %d - Failed to write emulation code to memory, quit!\n", log_num++); + return 4; + } else { + printf("ok %d - Program written to memory\n", log_num++); + } - // intercept memory write events - if (uc_hook_add(handle, &trace1, UC_HOOK_MEM_WRITE, hook_mem_write, NULL) != UC_ERR_OK) { - printf("not ok %d - Failed to install UC_HOOK_MEM_WRITE handler\n", log_num++); - return 6; - } - else { - printf("ok %d - UC_HOOK_MEM_WRITE installed\n", log_num++); - } + if (uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0) != UC_ERR_OK) { + printf("not ok %d - Failed to install UC_HOOK_CODE handler\n", log_num++); + return 5; + } else { + printf("ok %d - UC_HOOK_CODE installed\n", log_num++); + } - // intercept invalid memory events - if (uc_hook_add(handle, &trace1, UC_HOOK_MEM_INVALID, hook_mem_invalid, NULL) != UC_ERR_OK) { - printf("not ok %d - Failed to install UC_HOOK_MEM_INVALID handler\n", log_num++); - return 7; - } - else { - printf("ok %d - UC_HOOK_MEM_INVALID installed\n", log_num++); - } + // intercept memory write events + if (uc_hook_add(handle, &trace1, UC_HOOK_MEM_WRITE, hook_mem_write, NULL) != UC_ERR_OK) { + printf("not ok %d - Failed to install UC_HOOK_MEM_WRITE handler\n", log_num++); + return 6; + } else { + printf("ok %d - UC_HOOK_MEM_WRITE installed\n", log_num++); + } - // emulate machine code until told to stop by hook_code - printf("# BEGIN execution\n"); - err = uc_emu_start(handle, CODE_SECTION, CODE_SECTION + CODE_SIZE, 0, 0); - if (err != UC_ERR_OK) { - printf("not ok %d - Failure on uc_emu_start() with error %u:%s\n", log_num++, err, uc_strerror(err)); - return 8; - } - else { - printf("ok %d - uc_emu_start complete\n", log_num++); - } - printf("# END execution\n"); + // intercept invalid memory events + if (uc_hook_add(handle, &trace1, UC_HOOK_MEM_INVALID, hook_mem_invalid, NULL) != UC_ERR_OK) { + printf("not ok %d - Failed to install UC_HOOK_MEM_INVALID handler\n", log_num++); + return 7; + } else { + printf("ok %d - UC_HOOK_MEM_INVALID installed\n", log_num++); + } - //read from the remapped memory - testval = 0x42424242; - for (addr = 0x200000; addr <= 0x400000; addr += 0x100000) { - uint32_t val; - if (uc_mem_read(handle, addr, (uint8_t*)&val, sizeof(val)) != UC_ERR_OK) { - printf("not ok %d - Failed uc_mem_read for address 0x%x\n", log_num++, addr); - } - else { - printf("ok %d - Good uc_mem_read from 0x%x\n", log_num++, addr); - } - if (val != testval) { - printf("not ok %d - Read 0x%x, expected 0x%x\n", log_num++, val, testval); - } - else { - printf("ok %d - Correct value retrieved\n", log_num++); - } - testval += 0x02020202; - } + // emulate machine code until told to stop by hook_code + printf("# BEGIN execution\n"); + err = uc_emu_start(handle, CODE_SECTION, CODE_SECTION + CODE_SIZE, 0, 0); + if (err != UC_ERR_OK) { + printf("not ok %d - Failure on uc_emu_start() with error %u:%s\n", log_num++, err, uc_strerror(err)); + return 8; + } else { + printf("ok %d - uc_emu_start complete\n", log_num++); + } + printf("# END execution\n"); - //make sure that random blocks didn't get nuked - // fill in sections that shouldn't get touched - if (uc_mem_read(handle, 0x3ff000, (uint8_t*)readbuf, 4096)) { - printf("not ok %d - Failed to read random buffer 1 from memory\n", log_num++); - } - else { - printf("ok %d - Random buffer 1 read from memory\n", log_num++); - if (memcmp(buf1, readbuf, 4096)) { - printf("not ok %d - Random buffer 1 contents are incorrect\n", log_num++); - } - else { - printf("ok %d - Random buffer 1 contents are correct\n", log_num++); - } - } + //read from the remapped memory + testval = 0x42424242; + for (addr = 0x200000; addr <= 0x400000; addr += 0x100000) { + uint32_t val; + if (uc_mem_read(handle, addr, (uint8_t*)&val, sizeof(val)) != UC_ERR_OK) { + printf("not ok %d - Failed uc_mem_read for address 0x%x\n", log_num++, addr); + } else { + printf("ok %d - Good uc_mem_read from 0x%x\n", log_num++, addr); + } + if (val != testval) { + printf("not ok %d - Read 0x%x, expected 0x%x\n", log_num++, val, testval); + } else { + printf("ok %d - Correct value retrieved\n", log_num++); + } + testval += 0x02020202; + } - if (uc_mem_read(handle, 0x401000, (uint8_t*)readbuf, 4096)) { - printf("not ok %d - Failed to read random buffer 2 from memory\n", log_num++); - } - else { - printf("ok %d - Random buffer 2 read from memory\n", log_num++); - if (memcmp(buf2, readbuf, 4096)) { - printf("not ok %d - Random buffer 2 contents are incorrect\n", log_num++); - } - else { - printf("ok %d - Random buffer 2 contents are correct\n", log_num++); - } - } + //make sure that random blocks didn't get nuked + // fill in sections that shouldn't get touched + if (uc_mem_read(handle, 0x3ff000, (uint8_t*)readbuf, 4096)) { + printf("not ok %d - Failed to read random buffer 1 from memory\n", log_num++); + } else { + printf("ok %d - Random buffer 1 read from memory\n", log_num++); + if (memcmp(buf1, readbuf, 4096)) { + printf("not ok %d - Random buffer 1 contents are incorrect\n", log_num++); + } else { + printf("ok %d - Random buffer 1 contents are correct\n", log_num++); + } + } - if (uc_close(&handle) == UC_ERR_OK) { - printf("ok %d - uc_close complete\n", log_num++); - } - else { - printf("not ok %d - uc_close complete\n", log_num++); - } + if (uc_mem_read(handle, 0x401000, (uint8_t*)readbuf, 4096)) { + printf("not ok %d - Failed to read random buffer 2 from memory\n", log_num++); + } else { + printf("ok %d - Random buffer 2 read from memory\n", log_num++); + if (memcmp(buf2, readbuf, 4096)) { + printf("not ok %d - Random buffer 2 contents are incorrect\n", log_num++); + } else { + printf("ok %d - Random buffer 2 contents are correct\n", log_num++); + } + } - return 0; + if (uc_close(&handle) == UC_ERR_OK) { + printf("ok %d - uc_close complete\n", log_num++); + } else { + printf("not ok %d - uc_close complete\n", log_num++); + } + + return 0; } diff --git a/uc.c b/uc.c index 622de423..3db40db3 100644 --- a/uc.c +++ b/uc.c @@ -670,14 +670,14 @@ static uint8_t *copy_region(uch handle, MemoryRegion *mr) } /* -Split the given MemoryRegion at the indicated address for the indicated size -this may result in the create of up to 3 spanning sections. If the delete -parameter is true, the no new section will be created to replace the indicate -range. This functions exists to support uc_mem_protect and uc_mem_unmap. + Split the given MemoryRegion at the indicated address for the indicated size + this may result in the create of up to 3 spanning sections. If the delete + parameter is true, the no new section will be created to replace the indicate + range. This functions exists to support uc_mem_protect and uc_mem_unmap. -This is a static function and callers have already done some preliminary -parameter validation. -*/ + This is a static function and callers have already done some preliminary + parameter validation. + */ //TODO: investigate whether qemu region manipulation functions already offer this capability static bool split_region(uch handle, MemoryRegion *mr, uint64_t address, size_t size, bool do_delete) { @@ -709,7 +709,7 @@ static bool split_region(uch handle, MemoryRegion *mr, uint64_t address, size_t perms = mr->perms; begin = mr->addr; end = mr->end; - + if (uc_mem_unmap(handle, mr->addr, int128_get64(mr->size)) != UC_ERR_OK) goto error; @@ -784,7 +784,7 @@ uc_err uc_mem_protect(uch handle, uint64_t address, size_t size, uint32_t perms) // check for only valid permissions if ((perms & ~UC_PROT_ALL) != 0) return UC_ERR_INVAL; - + //check that user's entire requested block is mapped if (!check_mem_area(uc, address, size)) return UC_ERR_NOMEM; @@ -860,8 +860,7 @@ uc_err uc_mem_unmap(uch handle, uint64_t address, size_t size) break; } } - } - else { + } else { //ouch, we are going to need to subdivide blocks size_t count = 0, len; while(count < size) {