31
tests/regress/001-bad_condition_code_0xe.c
Normal file
31
tests/regress/001-bad_condition_code_0xe.c
Normal file
@ -0,0 +1,31 @@
|
||||
#include <unicorn/unicorn.h>
|
||||
|
||||
#define HARDWARE_ARCHITECTURE UC_ARCH_ARM
|
||||
#define HARDWARE_MODE 16
|
||||
#define MEMORY_STARTING_ADDRESS 8192
|
||||
#define MEMORY_SIZE 4096
|
||||
#define MEMORY_PERMISSIONS 6
|
||||
#define BINARY_CODE "\x56\xe8\x46\x46\x80\xf6\x8c\x56\xff\xbf\xcd\x90\xda\xa0\xed\xe8\x46\x43\x45\xe5\x80\x90\x44\x46\x04"
|
||||
|
||||
static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) {
|
||||
printf("hook_code(…) called\n");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv, char **envp) {
|
||||
uc_engine *uc;
|
||||
if (uc_open(HARDWARE_ARCHITECTURE, HARDWARE_MODE, &uc)) {
|
||||
printf("uc_open(…) failed\n");
|
||||
return 1;
|
||||
}
|
||||
uc_mem_map(uc, MEMORY_STARTING_ADDRESS, MEMORY_SIZE, MEMORY_PERMISSIONS);
|
||||
if (uc_mem_write(uc, MEMORY_STARTING_ADDRESS, BINARY_CODE, sizeof(BINARY_CODE) - 1)) {
|
||||
printf("uc_mem_write(…) failed\n");
|
||||
return 1;
|
||||
}
|
||||
uc_hook trace;
|
||||
uc_hook_add(uc, &trace, UC_HOOK_CODE, hook_code, NULL, (uint64_t)MEMORY_STARTING_ADDRESS, (uint64_t)(MEMORY_STARTING_ADDRESS + 1));
|
||||
printf("uc_emu_start(…)\n");
|
||||
uc_emu_start(uc, MEMORY_STARTING_ADDRESS, MEMORY_STARTING_ADDRESS + sizeof(BINARY_CODE) - 1, 0, 0);
|
||||
printf("done\n");
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
#include <unicorn/unicorn.h>
|
||||
|
||||
#define HARDWARE_ARCHITECTURE UC_ARCH_M68K
|
||||
#define HARDWARE_MODE 1073741824
|
||||
#define MEMORY_STARTING_ADDRESS 8388608
|
||||
#define MEMORY_SIZE 2097152
|
||||
#define MEMORY_PERMISSIONS 7
|
||||
#define BINARY_CODE "\xaf\x80\x4e\x7b\xff\xfb\x80\x4e\x3e\x80"
|
||||
|
||||
static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) {
|
||||
printf("hook_code(…) called\n");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv, char **envp) {
|
||||
uc_engine *uc;
|
||||
if (uc_open(HARDWARE_ARCHITECTURE, HARDWARE_MODE, &uc)) {
|
||||
printf("uc_open(…) failed\n");
|
||||
return 1;
|
||||
}
|
||||
uc_mem_map(uc, MEMORY_STARTING_ADDRESS, MEMORY_SIZE, MEMORY_PERMISSIONS);
|
||||
if (uc_mem_write(uc, MEMORY_STARTING_ADDRESS, BINARY_CODE, sizeof(BINARY_CODE) - 1)) {
|
||||
printf("uc_mem_write(…) failed\n");
|
||||
return 1;
|
||||
}
|
||||
uc_hook trace;
|
||||
uc_hook_add(uc, &trace, UC_HOOK_CODE, hook_code, NULL, (uint64_t)MEMORY_STARTING_ADDRESS, (uint64_t)(MEMORY_STARTING_ADDRESS + 1));
|
||||
printf("uc_emu_start(…)\n");
|
||||
uc_emu_start(uc, MEMORY_STARTING_ADDRESS, MEMORY_STARTING_ADDRESS + sizeof(BINARY_CODE) - 1, 0, 0);
|
||||
printf("done\n");
|
||||
return 0;
|
||||
}
|
31
tests/regress/003-qemu__fatal__wdebug_not_implemented.c
Normal file
31
tests/regress/003-qemu__fatal__wdebug_not_implemented.c
Normal file
@ -0,0 +1,31 @@
|
||||
#include <unicorn/unicorn.h>
|
||||
|
||||
#define HARDWARE_ARCHITECTURE UC_ARCH_M68K
|
||||
#define HARDWARE_MODE 1073741824
|
||||
#define MEMORY_STARTING_ADDRESS 1048576
|
||||
#define MEMORY_SIZE 403456
|
||||
#define MEMORY_PERMISSIONS 7
|
||||
#define BINARY_CODE "\x42\xc7\xfb\xfb\x54\x36"
|
||||
|
||||
static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) {
|
||||
printf("hook_code(…) called\n");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv, char **envp) {
|
||||
uc_engine *uc;
|
||||
if (uc_open(HARDWARE_ARCHITECTURE, HARDWARE_MODE, &uc)) {
|
||||
printf("uc_open(…) failed\n");
|
||||
return 1;
|
||||
}
|
||||
uc_mem_map(uc, MEMORY_STARTING_ADDRESS, MEMORY_SIZE, MEMORY_PERMISSIONS);
|
||||
if (uc_mem_write(uc, MEMORY_STARTING_ADDRESS, BINARY_CODE, sizeof(BINARY_CODE) - 1)) {
|
||||
printf("uc_mem_write(…) failed\n");
|
||||
return 1;
|
||||
}
|
||||
uc_hook trace;
|
||||
uc_hook_add(uc, &trace, UC_HOOK_CODE, hook_code, NULL, (uint64_t)MEMORY_STARTING_ADDRESS, (uint64_t)(MEMORY_STARTING_ADDRESS + 1));
|
||||
printf("uc_emu_start(…)\n");
|
||||
uc_emu_start(uc, MEMORY_STARTING_ADDRESS, MEMORY_STARTING_ADDRESS + sizeof(BINARY_CODE) - 1, 0, 0);
|
||||
printf("done\n");
|
||||
return 0;
|
||||
}
|
31
tests/regress/004-segmentation_fault_1.c
Normal file
31
tests/regress/004-segmentation_fault_1.c
Normal file
@ -0,0 +1,31 @@
|
||||
#include <unicorn/unicorn.h>
|
||||
|
||||
#define HARDWARE_ARCHITECTURE UC_ARCH_ARM
|
||||
#define HARDWARE_MODE 16
|
||||
#define MEMORY_STARTING_ADDRESS 1024
|
||||
#define MEMORY_SIZE 1796096
|
||||
#define MEMORY_PERMISSIONS 7
|
||||
#define BINARY_CODE "\x20\xbf\xbf\xbf\xbf\xdd\x5d\x74\x5e\x66\x72\x10"
|
||||
|
||||
static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) {
|
||||
printf("hook_code(…) called\n");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv, char **envp) {
|
||||
uc_engine *uc;
|
||||
if (uc_open(HARDWARE_ARCHITECTURE, HARDWARE_MODE, &uc)) {
|
||||
printf("uc_open(…) failed\n");
|
||||
return 1;
|
||||
}
|
||||
uc_mem_map(uc, MEMORY_STARTING_ADDRESS, MEMORY_SIZE, MEMORY_PERMISSIONS);
|
||||
if (uc_mem_write(uc, MEMORY_STARTING_ADDRESS, BINARY_CODE, sizeof(BINARY_CODE) - 1)) {
|
||||
printf("uc_mem_write(…) failed\n");
|
||||
return 1;
|
||||
}
|
||||
uc_hook trace;
|
||||
uc_hook_add(uc, &trace, UC_HOOK_CODE, hook_code, NULL, (uint64_t)MEMORY_STARTING_ADDRESS, (uint64_t)(MEMORY_STARTING_ADDRESS + 1));
|
||||
printf("uc_emu_start(…)\n");
|
||||
uc_emu_start(uc, MEMORY_STARTING_ADDRESS, MEMORY_STARTING_ADDRESS + sizeof(BINARY_CODE) - 1, 0, 0);
|
||||
printf("done\n");
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
#include <unicorn/unicorn.h>
|
||||
|
||||
#define HARDWARE_ARCHITECTURE UC_ARCH_M68K
|
||||
#define HARDWARE_MODE 1073741824
|
||||
#define MEMORY_STARTING_ADDRESS 1024
|
||||
#define MEMORY_SIZE 1044480
|
||||
#define MEMORY_PERMISSIONS 5
|
||||
#define BINARY_CODE "\x4c\x4c"
|
||||
|
||||
static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) {
|
||||
printf("hook_code(…) called\n");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv, char **envp) {
|
||||
uc_engine *uc;
|
||||
if (uc_open(HARDWARE_ARCHITECTURE, HARDWARE_MODE, &uc)) {
|
||||
printf("uc_open(…) failed\n");
|
||||
return 1;
|
||||
}
|
||||
uc_mem_map(uc, MEMORY_STARTING_ADDRESS, MEMORY_SIZE, MEMORY_PERMISSIONS);
|
||||
if (uc_mem_write(uc, MEMORY_STARTING_ADDRESS, BINARY_CODE, sizeof(BINARY_CODE) - 1)) {
|
||||
printf("uc_mem_write(…) failed\n");
|
||||
return 1;
|
||||
}
|
||||
uc_hook trace;
|
||||
uc_hook_add(uc, &trace, UC_HOOK_CODE, hook_code, NULL, (uint64_t)MEMORY_STARTING_ADDRESS, (uint64_t)(MEMORY_STARTING_ADDRESS + 1));
|
||||
printf("uc_emu_start(…)\n");
|
||||
uc_emu_start(uc, MEMORY_STARTING_ADDRESS, MEMORY_STARTING_ADDRESS + sizeof(BINARY_CODE) - 1, 0, 0);
|
||||
printf("done\n");
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
#include <unicorn/unicorn.h>
|
||||
|
||||
#define HARDWARE_ARCHITECTURE UC_ARCH_M68K
|
||||
#define HARDWARE_MODE 1073741824
|
||||
#define MEMORY_STARTING_ADDRESS 262144
|
||||
#define MEMORY_SIZE 403456
|
||||
#define MEMORY_PERMISSIONS 7
|
||||
#define BINARY_CODE "\xe2\x86\x09\xbc\xf2\x17\x09\xca\xca\xca\xca\x09\x09\x09\xf2\x17\x09\x20\x09\x09\xf2\x08\x09\x03\x09\xca\x6b\x6b\x6b\x1e\xca\xca\x86\x09\x09\xf2\x17\x09\x04\x21\x09\x09\xf4\xf4\xf4\xf4\xf4\xf4\xf4\xf4\xf4\xf4\xf4\xf4\xf4\xf4\xf4\xf4\xf4\xf4\xf4\xf4\xf2"
|
||||
|
||||
static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) {
|
||||
printf("hook_code(…) called\n");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv, char **envp) {
|
||||
uc_engine *uc;
|
||||
if (uc_open(HARDWARE_ARCHITECTURE, HARDWARE_MODE, &uc)) {
|
||||
printf("uc_open(…) failed\n");
|
||||
return 1;
|
||||
}
|
||||
uc_mem_map(uc, MEMORY_STARTING_ADDRESS, MEMORY_SIZE, MEMORY_PERMISSIONS);
|
||||
if (uc_mem_write(uc, MEMORY_STARTING_ADDRESS, BINARY_CODE, sizeof(BINARY_CODE) - 1)) {
|
||||
printf("uc_mem_write(…) failed\n");
|
||||
return 1;
|
||||
}
|
||||
uc_hook trace;
|
||||
uc_hook_add(uc, &trace, UC_HOOK_CODE, hook_code, NULL, (uint64_t)MEMORY_STARTING_ADDRESS, (uint64_t)(MEMORY_STARTING_ADDRESS + 1));
|
||||
printf("uc_emu_start(…)\n");
|
||||
uc_emu_start(uc, MEMORY_STARTING_ADDRESS, MEMORY_STARTING_ADDRESS + sizeof(BINARY_CODE) - 1, 0, 0);
|
||||
printf("done\n");
|
||||
return 0;
|
||||
}
|
30
tests/regress/LICENSE
Normal file
30
tests/regress/LICENSE
Normal file
@ -0,0 +1,30 @@
|
||||
This is the software license for Unicorn regression tests. The regression tests
|
||||
are written by several Unicorn contributors (See CREDITS.TXT) and maintained by
|
||||
Hoang-Vu Dang <dang.hvu@gmail.com>
|
||||
|
||||
Copyright (c) 2015, Unicorn contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of the developer(s) nor the names of its
|
||||
contributors may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
@ -38,6 +38,20 @@ TESTS += hook_extrainvoke
|
||||
TESTS += sysenter_hook_x86
|
||||
TESTS += emu_clear_errors
|
||||
TESTS += mem_fuzz
|
||||
TESTS += 001-bad_condition_code_0xe
|
||||
TESTS += 002-qemu__fatal__unimplemented_control_register_write_0xffb___0x0
|
||||
TESTS += 003-qemu__fatal__wdebug_not_implemented
|
||||
TESTS += 004-segmentation_fault_1
|
||||
TESTS += 005-qemu__fatal__illegal_instruction__0000___00000404
|
||||
TESTS += 006-qemu__fatal__illegal_instruction__0421___00040026
|
||||
TESTS += mem_64_c
|
||||
|
||||
TESTS += memleak_x86
|
||||
TESTS += memleak_arm
|
||||
TESTS += memleak_arm64
|
||||
TESTS += memleak_mips
|
||||
TESTS += memleak_m68k
|
||||
TESTS += memleak_sparc
|
||||
|
||||
all: $(TESTS)
|
||||
|
||||
|
@ -65,7 +65,7 @@ int main() {
|
||||
|
||||
uc_hook h1, h2;
|
||||
|
||||
err = uc_hook_add(uc, &h1, UC_HOOK_BLOCK, cb_hookblock, NULL, (uint64_t)1, (uint64_t)0);
|
||||
err = uc_hook_add(uc, &h1, UC_HOOK_BLOCK, cb_hookblock, NULL, 1, 0);
|
||||
if (err != UC_ERR_OK) {
|
||||
fprintf(stderr, "not ok %d - %s\n", count++, uc_strerror(err));
|
||||
exit(0);
|
||||
|
@ -120,10 +120,10 @@ static void VM_exec()
|
||||
uc_reg_write(uc, UC_X86_REG_EDI, &r_edi);
|
||||
uc_reg_write(uc, UC_X86_REG_EFLAGS, &eflags);
|
||||
|
||||
uc_hook_add(uc, &trace1, UC_HOOK_MEM_READ_UNMAPPED | UC_HOOK_MEM_WRITE_UNMAPPED, (void *)hook_invalid_mem, NULL);
|
||||
uc_hook_add(uc, &trace1, UC_HOOK_MEM_READ_UNMAPPED | UC_HOOK_MEM_WRITE_UNMAPPED, (void *)hook_invalid_mem, NULL, 1, 0);
|
||||
|
||||
// tracing all instruction by having @begin > @end
|
||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, (void *)hook_ins, NULL, (uint64_t)1, (uint64_t)0);
|
||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, (void *)hook_ins, NULL, 1, 0);
|
||||
|
||||
// emulate machine code in infinite time
|
||||
err = uc_emu_start(uc, ADDRESS, ADDRESS + (sizeof(X86_CODE32) - 1), 0, 0);
|
||||
|
@ -112,7 +112,7 @@ int main() {
|
||||
|
||||
uc_hook h1;
|
||||
|
||||
err = uc_hook_add(uc, &h1, UC_HOOK_MEM_UNMAPPED, cb_hookunmapped, NULL);
|
||||
err = uc_hook_add(uc, &h1, UC_HOOK_MEM_UNMAPPED, cb_hookunmapped, NULL, 1, 0);
|
||||
if (err != UC_ERR_OK) {
|
||||
fprintf(stderr, "not ok %d - %s\n", count++, uc_strerror(err));
|
||||
exit(0);
|
||||
|
@ -47,10 +47,10 @@ bool test_passed_ok = false;
|
||||
// This hook is used to show that code is executing in the emulator.
|
||||
static void mips_codehook(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
|
||||
{
|
||||
printf("Executing: %llX\n", address);
|
||||
printf("Executing: %"PRIx64"\n", address);
|
||||
if( address == 0x100008 )
|
||||
{
|
||||
printf("Stopping at: %llX\n", address);
|
||||
printf("Stopping at: %"PRIx64"\n", address);
|
||||
uc_emu_stop(uc);
|
||||
}
|
||||
}
|
||||
@ -98,7 +98,7 @@ int main(int argc, char **argv, char **envp)
|
||||
|
||||
// hook all instructions by having @begin > @end
|
||||
printf("uc_hook_add()\n");
|
||||
uc_hook_add(uc, &hhc, UC_HOOK_CODE, mips_codehook, NULL, (uint64_t)1, (uint64_t)0);
|
||||
uc_hook_add(uc, &hhc, UC_HOOK_CODE, mips_codehook, NULL, 1, 0);
|
||||
if( err )
|
||||
{
|
||||
printf("Failed on uc_hook_add(code) with error returned: %u\n", err);
|
||||
|
@ -58,7 +58,7 @@ static void VM_exec()
|
||||
uc_reg_write(uc, UC_X86_REG_ESP, &r_esp); //make stack pointer point to already mapped memory so we don't need to hook.
|
||||
uc_reg_write(uc, UC_X86_REG_EFLAGS, &eflags);
|
||||
|
||||
uc_hook_add(uc, &trace, UC_HOOK_CODE, (void *)hook_ins, NULL, (uint64_t)1, (uint64_t)0);
|
||||
uc_hook_add(uc, &trace, UC_HOOK_CODE, (void *)hook_ins, NULL, 1, 0);
|
||||
|
||||
// emulate machine code in infinite time
|
||||
err = uc_emu_start(uc, ADDRESS, ADDRESS + (sizeof(X86_CODE32) - 1), 0, 0);
|
||||
|
@ -25,7 +25,7 @@ int main(int argc, char **argv, char **envp) {
|
||||
return 1;
|
||||
}
|
||||
uc_hook hook;
|
||||
uc_hook_add(uc, &hook, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
||||
uc_hook_add(uc, &hook, UC_HOOK_BLOCK, hook_block, NULL, 1, 0);
|
||||
printf("uc_emu_start(…)\n");
|
||||
uc_emu_start(uc, STARTING_ADDRESS, STARTING_ADDRESS + sizeof(BINARY) - 1, 0, 20);
|
||||
printf("done\n");
|
||||
|
39
tests/regress/mem_64_c.c
Normal file
39
tests/regress/mem_64_c.c
Normal file
@ -0,0 +1,39 @@
|
||||
#include <stdio.h>
|
||||
#include <unicorn/unicorn.h>
|
||||
|
||||
uint64_t starts[] = {0x10000000, 0x110004000ll};
|
||||
|
||||
int main(int argc, char **argv, char **envp) {
|
||||
uc_engine *uc;
|
||||
uc_err err;
|
||||
int i;
|
||||
// Initialize emulator in X86-64bit mode
|
||||
err = uc_open(UC_ARCH_X86, UC_MODE_64, &uc);
|
||||
if (err) {
|
||||
printf("Failed on uc_open() with error returned: %u\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < (sizeof(starts) / sizeof(uint64_t)); i++) {
|
||||
uc_mem_map(uc, starts[i], 4096, UC_PROT_ALL);
|
||||
}
|
||||
|
||||
uint32_t count;
|
||||
uc_mem_region *regions;
|
||||
int err_count = 0;
|
||||
err = uc_mem_regions(uc, ®ions, &count);
|
||||
if (err == UC_ERR_OK) {
|
||||
for (i = 0; i < count; i++) {
|
||||
fprintf(stderr, "region %d: 0x%llx-0x%llx (%d)\n", i, regions[i].begin, regions[i].end - 1, regions[i].perms);
|
||||
if (regions[i].begin != starts[i]) {
|
||||
err_count++;
|
||||
fprintf(stderr, " ERROR: region start does not match requested start address, expected 0x%llx, found 0x%llx\n",
|
||||
starts[i], regions[i].begin);
|
||||
}
|
||||
}
|
||||
free(regions);
|
||||
}
|
||||
|
||||
uc_close(uc);
|
||||
return err_count;
|
||||
}
|
@ -205,7 +205,7 @@ int main(int argc, char **argv, char **envp)
|
||||
printf("ok %d - Program written to memory\n", log_num++);
|
||||
}
|
||||
|
||||
if (uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) {
|
||||
if (uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0) != UC_ERR_OK) {
|
||||
printf("not ok %d - Failed to install UC_HOOK_CODE ucr\n", log_num++);
|
||||
return 6;
|
||||
} else {
|
||||
@ -213,7 +213,7 @@ int main(int argc, char **argv, char **envp)
|
||||
}
|
||||
|
||||
// intercept memory write events
|
||||
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE, hook_mem_write, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) {
|
||||
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE, hook_mem_write, NULL, 1, 0) != UC_ERR_OK) {
|
||||
printf("not ok %d - Failed to install UC_HOOK_MEM_WRITE ucr\n", log_num++);
|
||||
return 7;
|
||||
} else {
|
||||
@ -221,7 +221,7 @@ int main(int argc, char **argv, char **envp)
|
||||
}
|
||||
|
||||
// intercept invalid memory events
|
||||
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE_PROT | UC_HOOK_MEM_FETCH_PROT, hook_mem_invalid, NULL) != UC_ERR_OK) {
|
||||
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE_PROT | UC_HOOK_MEM_FETCH_PROT, hook_mem_invalid, NULL, 1, 0) != UC_ERR_OK) {
|
||||
printf("not ok %d - Failed to install memory invalid handler\n", log_num++);
|
||||
return 8;
|
||||
} else {
|
||||
|
@ -213,7 +213,7 @@ int main(int argc, char **argv, char **envp)
|
||||
printf("ok %d - Program written to memory\n", log_num++);
|
||||
}
|
||||
|
||||
if (uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) {
|
||||
if (uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0) != UC_ERR_OK) {
|
||||
printf("not ok %d - Failed to install UC_HOOK_CODE ucr\n", log_num++);
|
||||
return 5;
|
||||
} else {
|
||||
@ -221,7 +221,7 @@ int main(int argc, char **argv, char **envp)
|
||||
}
|
||||
|
||||
// intercept memory write events
|
||||
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE, hook_mem_write, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) {
|
||||
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE, hook_mem_write, NULL, 1, 0) != UC_ERR_OK) {
|
||||
printf("not ok %d - Failed to install UC_HOOK_MEM_WRITE ucr\n", log_num++);
|
||||
return 6;
|
||||
} else {
|
||||
@ -229,7 +229,7 @@ int main(int argc, char **argv, char **envp)
|
||||
}
|
||||
|
||||
// intercept invalid memory events
|
||||
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE_PROT, hook_mem_invalid, NULL) != UC_ERR_OK) {
|
||||
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE_PROT, hook_mem_invalid, NULL, 1, 0) != UC_ERR_OK) {
|
||||
printf("not ok %d - Failed to install memory invalid handler\n", log_num++);
|
||||
return 7;
|
||||
} else {
|
||||
|
@ -208,7 +208,7 @@ int main(int argc, char **argv, char **envp)
|
||||
printf("ok %d - Program written to memory\n", log_num++);
|
||||
}
|
||||
|
||||
if (uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) {
|
||||
if (uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0) != UC_ERR_OK) {
|
||||
printf("not ok %d - Failed to install UC_HOOK_CODE ucr\n", log_num++);
|
||||
return 5;
|
||||
} else {
|
||||
@ -216,7 +216,7 @@ int main(int argc, char **argv, char **envp)
|
||||
}
|
||||
|
||||
// intercept memory write events
|
||||
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE, hook_mem_write, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) {
|
||||
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE, hook_mem_write, NULL, 1, 0) != UC_ERR_OK) {
|
||||
printf("not ok %d - Failed to install UC_HOOK_MEM_WRITE ucr\n", log_num++);
|
||||
return 6;
|
||||
} else {
|
||||
@ -224,7 +224,7 @@ int main(int argc, char **argv, char **envp)
|
||||
}
|
||||
|
||||
// intercept invalid memory events
|
||||
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE_UNMAPPED, hook_mem_invalid, NULL) != UC_ERR_OK) {
|
||||
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE_UNMAPPED, hook_mem_invalid, NULL, 1, 0) != UC_ERR_OK) {
|
||||
printf("not ok %d - Failed to install memory invalid handler\n", log_num++);
|
||||
return 7;
|
||||
} else {
|
||||
|
178
tests/regress/memleak_arm.c
Normal file
178
tests/regress/memleak_arm.c
Normal file
@ -0,0 +1,178 @@
|
||||
/* Unicorn Emulator Engine */
|
||||
/* By Nguyen Anh Quynh, 2015 */
|
||||
|
||||
/* Sample code to demonstrate how to emulate ARM code */
|
||||
|
||||
// windows specific
|
||||
#ifdef _MSC_VER
|
||||
#include <io.h>
|
||||
#include <windows.h>
|
||||
#define PRIx64 "llX"
|
||||
#ifdef DYNLOAD
|
||||
#include "unicorn_dynload.h"
|
||||
#else // DYNLOAD
|
||||
#include <unicorn/unicorn.h>
|
||||
#ifdef _WIN64
|
||||
#pragma comment(lib, "unicorn_staload64.lib")
|
||||
#else // _WIN64
|
||||
#pragma comment(lib, "unicorn_staload.lib")
|
||||
#endif // _WIN64
|
||||
#endif // DYNLOAD
|
||||
|
||||
// posix specific
|
||||
#else // _MSC_VER
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include <unicorn/unicorn.h>
|
||||
#endif // _MSC_VER
|
||||
|
||||
|
||||
// code to be emulated
|
||||
#define ARM_CODE "\x37\x00\xa0\xe3\x03\x10\x42\xe0" // mov r0, #0x37; sub r1, r2, r3
|
||||
#define THUMB_CODE "\x83\xb0" // sub sp, #0xc
|
||||
|
||||
// memory address where emulation starts
|
||||
#define ADDRESS 0x10000
|
||||
|
||||
static void hook_block(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
|
||||
{
|
||||
printf(">>> Tracing basic block at 0x%"PRIx64 ", block size = 0x%x\n", address, size);
|
||||
}
|
||||
|
||||
static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
|
||||
{
|
||||
printf(">>> Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size);
|
||||
}
|
||||
|
||||
static void test_arm(void)
|
||||
{
|
||||
uc_engine *uc;
|
||||
uc_err err;
|
||||
uc_hook trace1, trace2;
|
||||
|
||||
int r0 = 0x1234; // R0 register
|
||||
int r2 = 0x6789; // R1 register
|
||||
int r3 = 0x3333; // R2 register
|
||||
int r1; // R1 register
|
||||
|
||||
printf("Emulate ARM code\n");
|
||||
|
||||
// Initialize emulator in ARM mode
|
||||
err = uc_open(UC_ARCH_ARM, UC_MODE_ARM, &uc);
|
||||
if (err) {
|
||||
printf("Failed on uc_open() with error returned: %u (%s)\n",
|
||||
err, uc_strerror(err));
|
||||
return;
|
||||
}
|
||||
|
||||
// map 2MB memory for this emulation
|
||||
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
|
||||
|
||||
// write machine code to be emulated to memory
|
||||
uc_mem_write(uc, ADDRESS, ARM_CODE, sizeof(ARM_CODE) - 1);
|
||||
|
||||
// initialize machine registers
|
||||
uc_reg_write(uc, UC_ARM_REG_R0, &r0);
|
||||
uc_reg_write(uc, UC_ARM_REG_R2, &r2);
|
||||
uc_reg_write(uc, UC_ARM_REG_R3, &r3);
|
||||
|
||||
// tracing all basic blocks with customized callback
|
||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
||||
|
||||
// tracing one instruction at ADDRESS with customized callback
|
||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
|
||||
|
||||
// emulate machine code in infinite time (last param = 0), or when
|
||||
// finishing all the code.
|
||||
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(ARM_CODE) -1, 0, 0);
|
||||
if (err) {
|
||||
printf("Failed on uc_emu_start() with error returned: %u\n", err);
|
||||
}
|
||||
|
||||
// now print out some registers
|
||||
printf(">>> Emulation done. Below is the CPU context\n");
|
||||
|
||||
uc_reg_read(uc, UC_ARM_REG_R0, &r0);
|
||||
uc_reg_read(uc, UC_ARM_REG_R1, &r1);
|
||||
printf(">>> R0 = 0x%x\n", r0);
|
||||
printf(">>> R1 = 0x%x\n", r1);
|
||||
|
||||
uc_close(uc);
|
||||
}
|
||||
|
||||
static void test_thumb(void)
|
||||
{
|
||||
uc_engine *uc;
|
||||
uc_err err;
|
||||
uc_hook trace1, trace2;
|
||||
|
||||
int sp = 0x1234; // R0 register
|
||||
|
||||
printf("Emulate THUMB code\n");
|
||||
|
||||
// Initialize emulator in ARM mode
|
||||
err = uc_open(UC_ARCH_ARM, UC_MODE_THUMB, &uc);
|
||||
if (err) {
|
||||
printf("Failed on uc_open() with error returned: %u (%s)\n",
|
||||
err, uc_strerror(err));
|
||||
return;
|
||||
}
|
||||
|
||||
// map 2MB memory for this emulation
|
||||
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
|
||||
|
||||
// write machine code to be emulated to memory
|
||||
uc_mem_write(uc, ADDRESS, THUMB_CODE, sizeof(THUMB_CODE) - 1);
|
||||
|
||||
// initialize machine registers
|
||||
uc_reg_write(uc, UC_ARM_REG_SP, &sp);
|
||||
|
||||
// tracing all basic blocks with customized callback
|
||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
||||
|
||||
// tracing one instruction at ADDRESS with customized callback
|
||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
|
||||
|
||||
// emulate machine code in infinite time (last param = 0), or when
|
||||
// finishing all the code.
|
||||
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(THUMB_CODE) -1, 0, 0);
|
||||
if (err) {
|
||||
printf("Failed on uc_emu_start() with error returned: %u\n", err);
|
||||
}
|
||||
|
||||
// now print out some registers
|
||||
printf(">>> Emulation done. Below is the CPU context\n");
|
||||
|
||||
uc_reg_read(uc, UC_ARM_REG_SP, &sp);
|
||||
printf(">>> SP = 0x%x\n", sp);
|
||||
|
||||
uc_close(uc);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv, char **envp)
|
||||
{
|
||||
// dynamically load shared library
|
||||
#ifdef DYNLOAD
|
||||
if (!uc_dyn_load(NULL, 0)) {
|
||||
printf("Error dynamically loading shared library.\n");
|
||||
printf("Please check that unicorn.dll/unicorn.so is available as well as\n");
|
||||
printf("any other dependent dll/so files.\n");
|
||||
printf("The easiest way is to place them in the same directory as this app.\n");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
// test memleak
|
||||
while(1) {
|
||||
test_arm();
|
||||
printf("==========================\n");
|
||||
test_thumb();
|
||||
}
|
||||
|
||||
// dynamically free shared library
|
||||
#ifdef DYNLOAD
|
||||
uc_dyn_free();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
122
tests/regress/memleak_arm64.c
Normal file
122
tests/regress/memleak_arm64.c
Normal file
@ -0,0 +1,122 @@
|
||||
/* Unicorn Emulator Engine */
|
||||
/* By Nguyen Anh Quynh, 2015 */
|
||||
|
||||
/* Sample code to demonstrate how to emulate ARM64 code */
|
||||
|
||||
// windows specific
|
||||
#ifdef _MSC_VER
|
||||
#include <io.h>
|
||||
#include <windows.h>
|
||||
#define PRIx64 "llX"
|
||||
#ifdef DYNLOAD
|
||||
#include "unicorn_dynload.h"
|
||||
#else // DYNLOAD
|
||||
#include <unicorn/unicorn.h>
|
||||
#ifdef _WIN64
|
||||
#pragma comment(lib, "unicorn_staload64.lib")
|
||||
#else // _WIN64
|
||||
#pragma comment(lib, "unicorn_staload.lib")
|
||||
#endif // _WIN64
|
||||
#endif // DYNLOAD
|
||||
|
||||
// posix specific
|
||||
#else // _MSC_VER
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include <unicorn/unicorn.h>
|
||||
#endif // _MSC_VER
|
||||
|
||||
|
||||
// code to be emulated
|
||||
#define ARM_CODE "\xab\x01\x0f\x8b" // add x11, x13, x15
|
||||
|
||||
// memory address where emulation starts
|
||||
#define ADDRESS 0x10000
|
||||
|
||||
static void hook_block(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
|
||||
{
|
||||
printf(">>> Tracing basic block at 0x%"PRIx64 ", block size = 0x%x\n", address, size);
|
||||
}
|
||||
|
||||
static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
|
||||
{
|
||||
printf(">>> Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size);
|
||||
}
|
||||
|
||||
static void test_arm64(void)
|
||||
{
|
||||
uc_engine *uc;
|
||||
uc_err err;
|
||||
uc_hook trace1, trace2;
|
||||
|
||||
int64_t x11 = 0x1234; // X11 register
|
||||
int64_t x13 = 0x6789; // X13 register
|
||||
int64_t x15 = 0x3333; // X15 register
|
||||
|
||||
printf("Emulate ARM64 code\n");
|
||||
|
||||
// Initialize emulator in ARM mode
|
||||
err = uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc);
|
||||
if (err) {
|
||||
printf("Failed on uc_open() with error returned: %u (%s)\n",
|
||||
err, uc_strerror(err));
|
||||
return;
|
||||
}
|
||||
|
||||
// map 2MB memory for this emulation
|
||||
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
|
||||
|
||||
// write machine code to be emulated to memory
|
||||
uc_mem_write(uc, ADDRESS, ARM_CODE, sizeof(ARM_CODE) - 1);
|
||||
|
||||
// initialize machine registers
|
||||
uc_reg_write(uc, UC_ARM64_REG_X11, &x11);
|
||||
uc_reg_write(uc, UC_ARM64_REG_X13, &x13);
|
||||
uc_reg_write(uc, UC_ARM64_REG_X15, &x15);
|
||||
|
||||
// tracing all basic blocks with customized callback
|
||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
||||
|
||||
// tracing one instruction at ADDRESS with customized callback
|
||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
|
||||
|
||||
// emulate machine code in infinite time (last param = 0), or when
|
||||
// finishing all the code.
|
||||
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(ARM_CODE) -1, 0, 0);
|
||||
if (err) {
|
||||
printf("Failed on uc_emu_start() with error returned: %u\n", err);
|
||||
}
|
||||
|
||||
// now print out some registers
|
||||
printf(">>> Emulation done. Below is the CPU context\n");
|
||||
|
||||
uc_reg_read(uc, UC_ARM64_REG_X11, &x11);
|
||||
printf(">>> X11 = 0x%" PRIx64 "\n", x11);
|
||||
|
||||
uc_close(uc);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv, char **envp)
|
||||
{
|
||||
// dynamically load shared library
|
||||
#ifdef DYNLOAD
|
||||
if (!uc_dyn_load(NULL, 0)) {
|
||||
printf("Error dynamically loading shared library.\n");
|
||||
printf("Please check that unicorn.dll/unicorn.so is available as well as\n");
|
||||
printf("any other dependent dll/so files.\n");
|
||||
printf("The easiest way is to place them in the same directory as this app.\n");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
while(1) {
|
||||
test_arm64();
|
||||
}
|
||||
|
||||
// dynamically free shared library
|
||||
#ifdef DYNLOAD
|
||||
uc_dyn_free();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
185
tests/regress/memleak_m68k.c
Normal file
185
tests/regress/memleak_m68k.c
Normal file
@ -0,0 +1,185 @@
|
||||
/* Unicorn Emulator Engine */
|
||||
/* By Loi Anh Tuan, 2015 */
|
||||
|
||||
/* Sample code to demonstrate how to emulate m68k code */
|
||||
|
||||
// windows specific
|
||||
#ifdef _MSC_VER
|
||||
#include <io.h>
|
||||
#include <windows.h>
|
||||
#define PRIx64 "llX"
|
||||
#ifdef DYNLOAD
|
||||
#include "unicorn_dynload.h"
|
||||
#else // DYNLOAD
|
||||
#include <unicorn/unicorn.h>
|
||||
#ifdef _WIN64
|
||||
#pragma comment(lib, "unicorn_staload64.lib")
|
||||
#else // _WIN64
|
||||
#pragma comment(lib, "unicorn_staload.lib")
|
||||
#endif // _WIN64
|
||||
#endif // DYNLOAD
|
||||
|
||||
// posix specific
|
||||
#else // _MSC_VER
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include <unicorn/unicorn.h>
|
||||
#endif // _MSC_VER
|
||||
|
||||
// code to be emulated
|
||||
#define M68K_CODE "\x76\xed" // movq #-19, %d3
|
||||
|
||||
// memory address where emulation starts
|
||||
#define ADDRESS 0x10000
|
||||
|
||||
static void hook_block(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
|
||||
{
|
||||
printf(">>> Tracing basic block at 0x%"PRIx64 ", block size = 0x%x\n", address, size);
|
||||
}
|
||||
|
||||
static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
|
||||
{
|
||||
printf(">>> Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size);
|
||||
}
|
||||
|
||||
static void test_m68k(void)
|
||||
{
|
||||
uc_engine *uc;
|
||||
uc_hook trace1, trace2;
|
||||
uc_err err;
|
||||
|
||||
int d0 = 0x0000; // d0 data register
|
||||
int d1 = 0x0000; // d1 data register
|
||||
int d2 = 0x0000; // d2 data register
|
||||
int d3 = 0x0000; // d3 data register
|
||||
int d4 = 0x0000; // d4 data register
|
||||
int d5 = 0x0000; // d5 data register
|
||||
int d6 = 0x0000; // d6 data register
|
||||
int d7 = 0x0000; // d7 data register
|
||||
|
||||
int a0 = 0x0000; // a0 address register
|
||||
int a1 = 0x0000; // a1 address register
|
||||
int a2 = 0x0000; // a2 address register
|
||||
int a3 = 0x0000; // a3 address register
|
||||
int a4 = 0x0000; // a4 address register
|
||||
int a5 = 0x0000; // a5 address register
|
||||
int a6 = 0x0000; // a6 address register
|
||||
int a7 = 0x0000; // a6 address register
|
||||
|
||||
int pc = 0x0000; // program counter
|
||||
int sr = 0x0000; // status register
|
||||
|
||||
printf("Emulate M68K code\n");
|
||||
|
||||
// Initialize emulator in M68K mode
|
||||
err = uc_open(UC_ARCH_M68K, UC_MODE_BIG_ENDIAN, &uc);
|
||||
if (err) {
|
||||
printf("Failed on uc_open() with error returned: %u (%s)\n",
|
||||
err, uc_strerror(err));
|
||||
return;
|
||||
}
|
||||
|
||||
// map 2MB memory for this emulation
|
||||
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
|
||||
|
||||
// write machine code to be emulated to memory
|
||||
uc_mem_write(uc, ADDRESS, M68K_CODE, sizeof(M68K_CODE) - 1);
|
||||
|
||||
// initialize machine registers
|
||||
uc_reg_write(uc, UC_M68K_REG_D0, &d0);
|
||||
uc_reg_write(uc, UC_M68K_REG_D1, &d1);
|
||||
uc_reg_write(uc, UC_M68K_REG_D2, &d2);
|
||||
uc_reg_write(uc, UC_M68K_REG_D3, &d3);
|
||||
uc_reg_write(uc, UC_M68K_REG_D4, &d4);
|
||||
uc_reg_write(uc, UC_M68K_REG_D5, &d5);
|
||||
uc_reg_write(uc, UC_M68K_REG_D6, &d6);
|
||||
uc_reg_write(uc, UC_M68K_REG_D7, &d7);
|
||||
|
||||
uc_reg_write(uc, UC_M68K_REG_A0, &a0);
|
||||
uc_reg_write(uc, UC_M68K_REG_A1, &a1);
|
||||
uc_reg_write(uc, UC_M68K_REG_A2, &a2);
|
||||
uc_reg_write(uc, UC_M68K_REG_A3, &a3);
|
||||
uc_reg_write(uc, UC_M68K_REG_A4, &a4);
|
||||
uc_reg_write(uc, UC_M68K_REG_A5, &a5);
|
||||
uc_reg_write(uc, UC_M68K_REG_A6, &a6);
|
||||
uc_reg_write(uc, UC_M68K_REG_A7, &a7);
|
||||
|
||||
uc_reg_write(uc, UC_M68K_REG_PC, &pc);
|
||||
uc_reg_write(uc, UC_M68K_REG_SR, &sr);
|
||||
|
||||
// tracing all basic blocks with customized callback
|
||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
||||
|
||||
// tracing all instruction
|
||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
|
||||
|
||||
// emulate machine code in infinite time (last param = 0), or when
|
||||
// finishing all the code.
|
||||
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(M68K_CODE)-1, 0, 0);
|
||||
if (err) {
|
||||
printf("Failed on uc_emu_start() with error returned: %u\n", err);
|
||||
}
|
||||
|
||||
// now print out some registers
|
||||
printf(">>> Emulation done. Below is the CPU context\n");
|
||||
|
||||
uc_reg_read(uc, UC_M68K_REG_D0, &d0);
|
||||
uc_reg_read(uc, UC_M68K_REG_D1, &d1);
|
||||
uc_reg_read(uc, UC_M68K_REG_D2, &d2);
|
||||
uc_reg_read(uc, UC_M68K_REG_D3, &d3);
|
||||
uc_reg_read(uc, UC_M68K_REG_D4, &d4);
|
||||
uc_reg_read(uc, UC_M68K_REG_D5, &d5);
|
||||
uc_reg_read(uc, UC_M68K_REG_D6, &d6);
|
||||
uc_reg_read(uc, UC_M68K_REG_D7, &d7);
|
||||
|
||||
uc_reg_read(uc, UC_M68K_REG_A0, &a0);
|
||||
uc_reg_read(uc, UC_M68K_REG_A1, &a1);
|
||||
uc_reg_read(uc, UC_M68K_REG_A2, &a2);
|
||||
uc_reg_read(uc, UC_M68K_REG_A3, &a3);
|
||||
uc_reg_read(uc, UC_M68K_REG_A4, &a4);
|
||||
uc_reg_read(uc, UC_M68K_REG_A5, &a5);
|
||||
uc_reg_read(uc, UC_M68K_REG_A6, &a6);
|
||||
uc_reg_read(uc, UC_M68K_REG_A7, &a7);
|
||||
|
||||
uc_reg_read(uc, UC_M68K_REG_PC, &pc);
|
||||
uc_reg_read(uc, UC_M68K_REG_SR, &sr);
|
||||
|
||||
printf(">>> A0 = 0x%x\t\t>>> D0 = 0x%x\n", a0, d0);
|
||||
printf(">>> A1 = 0x%x\t\t>>> D1 = 0x%x\n", a1, d1);
|
||||
printf(">>> A2 = 0x%x\t\t>>> D2 = 0x%x\n", a2, d2);
|
||||
printf(">>> A3 = 0x%x\t\t>>> D3 = 0x%x\n", a3, d3);
|
||||
printf(">>> A4 = 0x%x\t\t>>> D4 = 0x%x\n", a4, d4);
|
||||
printf(">>> A5 = 0x%x\t\t>>> D5 = 0x%x\n", a5, d5);
|
||||
printf(">>> A6 = 0x%x\t\t>>> D6 = 0x%x\n", a6, d6);
|
||||
printf(">>> A7 = 0x%x\t\t>>> D7 = 0x%x\n", a7, d7);
|
||||
printf(">>> PC = 0x%x\n", pc);
|
||||
printf(">>> SR = 0x%x\n", sr);
|
||||
|
||||
uc_close(uc);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv, char **envp)
|
||||
{
|
||||
// dynamically load shared library
|
||||
#ifdef DYNLOAD
|
||||
if (!uc_dyn_load(NULL, 0)) {
|
||||
printf("Error dynamically loading shared library.\n");
|
||||
printf("Please check that unicorn.dll/unicorn.so is available as well as\n");
|
||||
printf("any other dependent dll/so files.\n");
|
||||
printf("The easiest way is to place them in the same directory as this app.\n");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
// test memleak
|
||||
while(1) {
|
||||
test_m68k();
|
||||
}
|
||||
|
||||
// dynamically free shared library
|
||||
#ifdef DYNLOAD
|
||||
uc_dyn_free();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
171
tests/regress/memleak_mips.c
Normal file
171
tests/regress/memleak_mips.c
Normal file
@ -0,0 +1,171 @@
|
||||
/* Unicorn Emulator Engine */
|
||||
/* By Nguyen Anh Quynh, 2015 */
|
||||
|
||||
/* Sample code to demonstrate how to emulate Mips code (big endian) */
|
||||
|
||||
// windows specific
|
||||
#ifdef _MSC_VER
|
||||
#include <io.h>
|
||||
#include <windows.h>
|
||||
#define PRIx64 "llX"
|
||||
#ifdef DYNLOAD
|
||||
#include "unicorn_dynload.h"
|
||||
#else // DYNLOAD
|
||||
#include <unicorn/unicorn.h>
|
||||
#ifdef _WIN64
|
||||
#pragma comment(lib, "unicorn_staload64.lib")
|
||||
#else // _WIN64
|
||||
#pragma comment(lib, "unicorn_staload.lib")
|
||||
#endif // _WIN64
|
||||
#endif // DYNLOAD
|
||||
|
||||
// posix specific
|
||||
#else // _MSC_VER
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include <unicorn/unicorn.h>
|
||||
#endif // _MSC_VER
|
||||
|
||||
|
||||
// code to be emulated
|
||||
#define MIPS_CODE_EB "\x34\x21\x34\x56" // ori $at, $at, 0x3456;
|
||||
#define MIPS_CODE_EL "\x56\x34\x21\x34" // ori $at, $at, 0x3456;
|
||||
|
||||
// memory address where emulation starts
|
||||
#define ADDRESS 0x10000
|
||||
|
||||
static void hook_block(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
|
||||
{
|
||||
printf(">>> Tracing basic block at 0x%"PRIx64 ", block size = 0x%x\n", address, size);
|
||||
}
|
||||
|
||||
static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
|
||||
{
|
||||
printf(">>> Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size);
|
||||
}
|
||||
|
||||
static void test_mips_eb(void)
|
||||
{
|
||||
uc_engine *uc;
|
||||
uc_err err;
|
||||
uc_hook trace1, trace2;
|
||||
|
||||
int r1 = 0x6789; // R1 register
|
||||
|
||||
printf("Emulate MIPS code (big-endian)\n");
|
||||
|
||||
// Initialize emulator in MIPS mode
|
||||
err = uc_open(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_BIG_ENDIAN, &uc);
|
||||
if (err) {
|
||||
printf("Failed on uc_open() with error returned: %u (%s)\n",
|
||||
err, uc_strerror(err));
|
||||
return;
|
||||
}
|
||||
|
||||
// map 2MB memory for this emulation
|
||||
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
|
||||
|
||||
// write machine code to be emulated to memory
|
||||
uc_mem_write(uc, ADDRESS, MIPS_CODE_EB, sizeof(MIPS_CODE_EB) - 1);
|
||||
|
||||
// initialize machine registers
|
||||
uc_reg_write(uc, UC_MIPS_REG_1, &r1);
|
||||
|
||||
// tracing all basic blocks with customized callback
|
||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
||||
|
||||
// tracing one instruction at ADDRESS with customized callback
|
||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
|
||||
|
||||
// emulate machine code in infinite time (last param = 0), or when
|
||||
// finishing all the code.
|
||||
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(MIPS_CODE_EB) - 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");
|
||||
|
||||
uc_reg_read(uc, UC_MIPS_REG_1, &r1);
|
||||
printf(">>> R1 = 0x%x\n", r1);
|
||||
|
||||
uc_close(uc);
|
||||
}
|
||||
|
||||
static void test_mips_el(void)
|
||||
{
|
||||
uc_engine *uc;
|
||||
uc_err err;
|
||||
uc_hook trace1, trace2;
|
||||
|
||||
int r1 = 0x6789; // R1 register
|
||||
|
||||
printf("===========================\n");
|
||||
printf("Emulate MIPS code (little-endian)\n");
|
||||
|
||||
// Initialize emulator in MIPS mode
|
||||
err = uc_open(UC_ARCH_MIPS, UC_MODE_MIPS32, &uc);
|
||||
if (err) {
|
||||
printf("Failed on uc_open() with error returned: %u (%s)\n",
|
||||
err, uc_strerror(err));
|
||||
return;
|
||||
}
|
||||
|
||||
// map 2MB memory for this emulation
|
||||
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
|
||||
|
||||
// write machine code to be emulated to memory
|
||||
uc_mem_write(uc, ADDRESS, MIPS_CODE_EL, sizeof(MIPS_CODE_EL) - 1);
|
||||
|
||||
// initialize machine registers
|
||||
uc_reg_write(uc, UC_MIPS_REG_1, &r1);
|
||||
|
||||
// tracing all basic blocks with customized callback
|
||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
||||
|
||||
// tracing one instruction at ADDRESS with customized callback
|
||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
|
||||
|
||||
// emulate machine code in infinite time (last param = 0), or when
|
||||
// finishing all the code.
|
||||
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(MIPS_CODE_EL) - 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");
|
||||
|
||||
uc_reg_read(uc, UC_MIPS_REG_1, &r1);
|
||||
printf(">>> R1 = 0x%x\n", r1);
|
||||
|
||||
uc_close(uc);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv, char **envp)
|
||||
{
|
||||
// dynamically load shared library
|
||||
#ifdef DYNLOAD
|
||||
if (!uc_dyn_load(NULL, 0)) {
|
||||
printf("Error dynamically loading shared library.\n");
|
||||
printf("Please check that unicorn.dll/unicorn.so is available as well as\n");
|
||||
printf("any other dependent dll/so files.\n");
|
||||
printf("The easiest way is to place them in the same directory as this app.\n");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
// test memleak
|
||||
while(1) {
|
||||
test_mips_eb();
|
||||
test_mips_el();
|
||||
}
|
||||
|
||||
// dynamically free shared library
|
||||
#ifdef DYNLOAD
|
||||
uc_dyn_free();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
125
tests/regress/memleak_sparc.c
Normal file
125
tests/regress/memleak_sparc.c
Normal file
@ -0,0 +1,125 @@
|
||||
/* Unicorn Emulator Engine */
|
||||
/* By Nguyen Anh Quynh, 2015 */
|
||||
|
||||
/* Sample code to demonstrate how to emulate Sparc code */
|
||||
|
||||
// windows specific
|
||||
#ifdef _MSC_VER
|
||||
#include <io.h>
|
||||
#include <windows.h>
|
||||
#define PRIx64 "llX"
|
||||
#ifdef DYNLOAD
|
||||
#include "unicorn_dynload.h"
|
||||
#else // DYNLOAD
|
||||
#include <unicorn/unicorn.h>
|
||||
#ifdef _WIN64
|
||||
#pragma comment(lib, "unicorn_staload64.lib")
|
||||
#else // _WIN64
|
||||
#pragma comment(lib, "unicorn_staload.lib")
|
||||
#endif // _WIN64
|
||||
#endif // DYNLOAD
|
||||
|
||||
// posix specific
|
||||
#else // _MSC_VER
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include <unicorn/unicorn.h>
|
||||
#endif // _MSC_VER
|
||||
|
||||
|
||||
// code to be emulated
|
||||
#define SPARC_CODE "\x86\x00\x40\x02" // add %g1, %g2, %g3;
|
||||
//#define SPARC_CODE "\xbb\x70\x00\x00" // illegal code
|
||||
|
||||
// memory address where emulation starts
|
||||
#define ADDRESS 0x10000
|
||||
|
||||
static void hook_block(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
|
||||
{
|
||||
printf(">>> Tracing basic block at 0x%"PRIx64 ", block size = 0x%x\n", address, size);
|
||||
}
|
||||
|
||||
static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
|
||||
{
|
||||
printf(">>> Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size);
|
||||
}
|
||||
|
||||
static void test_sparc(void)
|
||||
{
|
||||
uc_engine *uc;
|
||||
uc_err err;
|
||||
uc_hook trace1, trace2;
|
||||
|
||||
int g1 = 0x1230; // G1 register
|
||||
int g2 = 0x6789; // G2 register
|
||||
int g3 = 0x5555; // G3 register
|
||||
|
||||
printf("Emulate SPARC code\n");
|
||||
|
||||
// Initialize emulator in Sparc mode
|
||||
err = uc_open(UC_ARCH_SPARC, UC_MODE_32, &uc);
|
||||
if (err) {
|
||||
printf("Failed on uc_open() with error returned: %u (%s)\n",
|
||||
err, uc_strerror(err));
|
||||
return;
|
||||
}
|
||||
|
||||
// map 2MB memory for this emulation
|
||||
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
|
||||
|
||||
// write machine code to be emulated to memory
|
||||
uc_mem_write(uc, ADDRESS, SPARC_CODE, sizeof(SPARC_CODE) - 1);
|
||||
|
||||
// initialize machine registers
|
||||
uc_reg_write(uc, UC_SPARC_REG_G1, &g1);
|
||||
uc_reg_write(uc, UC_SPARC_REG_G2, &g2);
|
||||
uc_reg_write(uc, UC_SPARC_REG_G3, &g3);
|
||||
|
||||
// tracing all basic blocks with customized callback
|
||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
||||
|
||||
// tracing all instructions with customized callback
|
||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
|
||||
|
||||
// emulate machine code in infinite time (last param = 0), or when
|
||||
// finishing all the code.
|
||||
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(SPARC_CODE) - 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");
|
||||
|
||||
uc_reg_read(uc, UC_SPARC_REG_G3, &g3);
|
||||
printf(">>> G3 = 0x%x\n", g3);
|
||||
|
||||
uc_close(uc);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv, char **envp)
|
||||
{
|
||||
// dynamically load shared library
|
||||
#ifdef DYNLOAD
|
||||
if (!uc_dyn_load(NULL, 0)) {
|
||||
printf("Error dynamically loading shared library.\n");
|
||||
printf("Please check that unicorn.dll/unicorn.so is available as well as\n");
|
||||
printf("any other dependent dll/so files.\n");
|
||||
printf("The easiest way is to place them in the same directory as this app.\n");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
// test memleak
|
||||
while(1) {
|
||||
test_sparc();
|
||||
}
|
||||
|
||||
// dynamically free shared library
|
||||
#ifdef DYNLOAD
|
||||
uc_dyn_free();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
306
tests/regress/memleak_x86.c
Normal file
306
tests/regress/memleak_x86.c
Normal file
@ -0,0 +1,306 @@
|
||||
/* Unicorn Emulator Engine */
|
||||
/* By Nguyen Anh Quynh & Dang Hoang Vu, 2015 */
|
||||
|
||||
/* Sample code to demonstrate how to emulate X86 code */
|
||||
|
||||
// windows specific
|
||||
#ifdef _MSC_VER
|
||||
#include <io.h>
|
||||
#include <windows.h>
|
||||
#define PRIx64 "llX"
|
||||
#ifdef DYNLOAD
|
||||
#include "unicorn_dynload.h"
|
||||
#else // DYNLOAD
|
||||
#include <unicorn/unicorn.h>
|
||||
#ifdef _WIN64
|
||||
#pragma comment(lib, "unicorn_staload64.lib")
|
||||
#else // _WIN64
|
||||
#pragma comment(lib, "unicorn_staload.lib")
|
||||
#endif // _WIN64
|
||||
#endif // DYNLOAD
|
||||
|
||||
// posix specific
|
||||
#else // _MSC_VER
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include <unicorn/unicorn.h>
|
||||
#endif // _MSC_VER
|
||||
|
||||
// common includes
|
||||
#include <string.h>
|
||||
|
||||
|
||||
// code to be emulated
|
||||
#define X86_CODE32 "\x41\x4a" // INC ecx; DEC edx
|
||||
#define X86_CODE32_JUMP "\xeb\x02\x90\x90\x90\x90\x90\x90" // jmp 4; nop; nop; nop; nop; nop; nop
|
||||
// #define X86_CODE32_SELF "\xeb\x1c\x5a\x89\xd6\x8b\x02\x66\x3d\xca\x7d\x75\x06\x66\x05\x03\x03\x89\x02\xfe\xc2\x3d\x41\x41\x41\x41\x75\xe9\xff\xe6\xe8\xdf\xff\xff\xff\x31\xd2\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xca\x7d\x41\x41\x41\x41"
|
||||
//#define X86_CODE32 "\x51\x51\x51\x51" // PUSH ecx;
|
||||
#define X86_CODE32_LOOP "\x41\x4a\xeb\xfe" // INC ecx; DEC edx; JMP self-loop
|
||||
#define X86_CODE32_MEM_WRITE "\x89\x0D\xAA\xAA\xAA\xAA\x41\x4a" // mov [0xaaaaaaaa], ecx; INC ecx; DEC edx
|
||||
#define X86_CODE32_MEM_READ "\x8B\x0D\xAA\xAA\xAA\xAA\x41\x4a" // mov ecx,[0xaaaaaaaa]; INC ecx; DEC edx
|
||||
|
||||
#define X86_CODE32_JMP_INVALID "\xe9\xe9\xee\xee\xee\x41\x4a" // JMP outside; INC ecx; DEC edx
|
||||
#define X86_CODE32_INOUT "\x41\xE4\x3F\x4a\xE6\x46\x43" // INC ecx; IN AL, 0x3f; DEC edx; OUT 0x46, AL; INC ebx
|
||||
|
||||
//#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"
|
||||
#define X86_CODE16 "\x00\x00" // add byte ptr [bx + si], al
|
||||
#define X86_CODE64_SYSCALL "\x0f\x05" // SYSCALL
|
||||
|
||||
// memory address where emulation starts
|
||||
#define ADDRESS 0x1000000
|
||||
|
||||
// callback for tracing basic blocks
|
||||
static void hook_block(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
|
||||
{
|
||||
printf(">>> Tracing basic block at 0x%"PRIx64 ", block size = 0x%x\n", address, size);
|
||||
}
|
||||
|
||||
// callback for tracing instruction
|
||||
static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
|
||||
{
|
||||
int eflags;
|
||||
printf(">>> Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size);
|
||||
|
||||
uc_reg_read(uc, UC_X86_REG_EFLAGS, &eflags);
|
||||
printf(">>> --- EFLAGS is 0x%x\n", eflags);
|
||||
|
||||
// Uncomment below code to stop the emulation using uc_emu_stop()
|
||||
// if (address == 0x1000009)
|
||||
// uc_emu_stop(uc);
|
||||
}
|
||||
|
||||
// callback for tracing instruction
|
||||
static void hook_code64(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
|
||||
{
|
||||
uint64_t rip;
|
||||
|
||||
uc_reg_read(uc, UC_X86_REG_RIP, &rip);
|
||||
printf(">>> Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size);
|
||||
printf(">>> RIP is 0x%"PRIx64 "\n", rip);
|
||||
|
||||
// Uncomment below code to stop the emulation using uc_emu_stop()
|
||||
// if (address == 0x1000009)
|
||||
// uc_emu_stop(uc);
|
||||
}
|
||||
|
||||
static void hook_mem64(uc_engine *uc, uc_mem_type type,
|
||||
uint64_t address, int size, int64_t value, void *user_data)
|
||||
{
|
||||
switch(type) {
|
||||
default: break;
|
||||
case UC_MEM_READ:
|
||||
printf(">>> Memory is being READ at 0x%"PRIx64 ", data size = %u\n",
|
||||
address, size);
|
||||
break;
|
||||
case UC_MEM_WRITE:
|
||||
printf(">>> Memory is being WRITE at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n",
|
||||
address, size, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_i386(void)
|
||||
{
|
||||
uc_engine *uc;
|
||||
uc_err err;
|
||||
uint32_t tmp;
|
||||
uc_hook trace1, trace2;
|
||||
|
||||
int r_ecx = 0x1234; // ECX register
|
||||
int r_edx = 0x7890; // EDX register
|
||||
|
||||
printf("Emulate i386 code\n");
|
||||
|
||||
// Initialize emulator in X86-32bit mode
|
||||
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
|
||||
if (err) {
|
||||
printf("Failed on uc_open() with error returned: %u\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
// map 2MB memory for this emulation
|
||||
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
|
||||
|
||||
// write machine code to be emulated to memory
|
||||
if (uc_mem_write(uc, ADDRESS, X86_CODE32, sizeof(X86_CODE32) - 1)) {
|
||||
printf("Failed to write emulation code to memory, quit!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// initialize machine registers
|
||||
uc_reg_write(uc, UC_X86_REG_ECX, &r_ecx);
|
||||
uc_reg_write(uc, UC_X86_REG_EDX, &r_edx);
|
||||
|
||||
// tracing all basic blocks with customized callback
|
||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
||||
|
||||
// tracing all instruction by having @begin > @end
|
||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
|
||||
|
||||
// emulate machine code in infinite time
|
||||
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32) - 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");
|
||||
|
||||
uc_reg_read(uc, UC_X86_REG_ECX, &r_ecx);
|
||||
uc_reg_read(uc, UC_X86_REG_EDX, &r_edx);
|
||||
printf(">>> ECX = 0x%x\n", r_ecx);
|
||||
printf(">>> EDX = 0x%x\n", r_edx);
|
||||
|
||||
// read from memory
|
||||
if (!uc_mem_read(uc, ADDRESS, &tmp, sizeof(tmp)))
|
||||
printf(">>> Read 4 bytes from [0x%x] = 0x%x\n", ADDRESS, tmp);
|
||||
else
|
||||
printf(">>> Failed to read 4 bytes from [0x%x]\n", ADDRESS);
|
||||
|
||||
uc_close(uc);
|
||||
}
|
||||
|
||||
static void test_x86_64(void)
|
||||
{
|
||||
uc_engine *uc;
|
||||
uc_err err;
|
||||
uc_hook trace1, trace2, trace3, trace4;
|
||||
|
||||
int64_t rax = 0x71f3029efd49d41d;
|
||||
int64_t rbx = 0xd87b45277f133ddb;
|
||||
int64_t rcx = 0xab40d1ffd8afc461;
|
||||
int64_t rdx = 0x919317b4a733f01;
|
||||
int64_t rsi = 0x4c24e753a17ea358;
|
||||
int64_t rdi = 0xe509a57d2571ce96;
|
||||
int64_t r8 = 0xea5b108cc2b9ab1f;
|
||||
int64_t r9 = 0x19ec097c8eb618c1;
|
||||
int64_t r10 = 0xec45774f00c5f682;
|
||||
int64_t r11 = 0xe17e9dbec8c074aa;
|
||||
int64_t r12 = 0x80f86a8dc0f6d457;
|
||||
int64_t r13 = 0x48288ca5671c5492;
|
||||
int64_t r14 = 0x595f72f6e4017f6e;
|
||||
int64_t r15 = 0x1efd97aea331cccc;
|
||||
|
||||
int64_t rsp = ADDRESS + 0x200000;
|
||||
|
||||
|
||||
printf("Emulate x86_64 code\n");
|
||||
|
||||
// Initialize emulator in X86-64bit mode
|
||||
err = uc_open(UC_ARCH_X86, UC_MODE_64, &uc);
|
||||
if (err) {
|
||||
printf("Failed on uc_open() with error returned: %u\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
// map 2MB memory for this emulation
|
||||
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
|
||||
|
||||
// write machine code to be emulated to memory
|
||||
if (uc_mem_write(uc, ADDRESS, X86_CODE64, sizeof(X86_CODE64) - 1)) {
|
||||
printf("Failed to write emulation code to memory, quit!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// initialize machine registers
|
||||
uc_reg_write(uc, UC_X86_REG_RSP, &rsp);
|
||||
|
||||
uc_reg_write(uc, UC_X86_REG_RAX, &rax);
|
||||
uc_reg_write(uc, UC_X86_REG_RBX, &rbx);
|
||||
uc_reg_write(uc, UC_X86_REG_RCX, &rcx);
|
||||
uc_reg_write(uc, UC_X86_REG_RDX, &rdx);
|
||||
uc_reg_write(uc, UC_X86_REG_RSI, &rsi);
|
||||
uc_reg_write(uc, UC_X86_REG_RDI, &rdi);
|
||||
uc_reg_write(uc, UC_X86_REG_R8, &r8);
|
||||
uc_reg_write(uc, UC_X86_REG_R9, &r9);
|
||||
uc_reg_write(uc, UC_X86_REG_R10, &r10);
|
||||
uc_reg_write(uc, UC_X86_REG_R11, &r11);
|
||||
uc_reg_write(uc, UC_X86_REG_R12, &r12);
|
||||
uc_reg_write(uc, UC_X86_REG_R13, &r13);
|
||||
uc_reg_write(uc, UC_X86_REG_R14, &r14);
|
||||
uc_reg_write(uc, UC_X86_REG_R15, &r15);
|
||||
|
||||
// tracing all basic blocks with customized callback
|
||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
||||
|
||||
// tracing all instructions in the range [ADDRESS, ADDRESS+20]
|
||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code64, NULL, (uint64_t)ADDRESS, (uint64_t)(ADDRESS+20));
|
||||
|
||||
// tracing all memory WRITE access (with @begin > @end)
|
||||
uc_hook_add(uc, &trace3, UC_HOOK_MEM_WRITE, hook_mem64, NULL, (uint64_t)1, (uint64_t)0);
|
||||
|
||||
// tracing all memory READ access (with @begin > @end)
|
||||
uc_hook_add(uc, &trace4, UC_HOOK_MEM_READ, hook_mem64, NULL, (uint64_t)1, (uint64_t)0);
|
||||
|
||||
// emulate machine code in infinite time (last param = 0), or when
|
||||
// finishing all the code.
|
||||
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE64) - 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");
|
||||
|
||||
uc_reg_read(uc, UC_X86_REG_RAX, &rax);
|
||||
uc_reg_read(uc, UC_X86_REG_RBX, &rbx);
|
||||
uc_reg_read(uc, UC_X86_REG_RCX, &rcx);
|
||||
uc_reg_read(uc, UC_X86_REG_RDX, &rdx);
|
||||
uc_reg_read(uc, UC_X86_REG_RSI, &rsi);
|
||||
uc_reg_read(uc, UC_X86_REG_RDI, &rdi);
|
||||
uc_reg_read(uc, UC_X86_REG_R8, &r8);
|
||||
uc_reg_read(uc, UC_X86_REG_R9, &r9);
|
||||
uc_reg_read(uc, UC_X86_REG_R10, &r10);
|
||||
uc_reg_read(uc, UC_X86_REG_R11, &r11);
|
||||
uc_reg_read(uc, UC_X86_REG_R12, &r12);
|
||||
uc_reg_read(uc, UC_X86_REG_R13, &r13);
|
||||
uc_reg_read(uc, UC_X86_REG_R14, &r14);
|
||||
uc_reg_read(uc, UC_X86_REG_R15, &r15);
|
||||
|
||||
printf(">>> RAX = 0x%" PRIx64 "\n", rax);
|
||||
printf(">>> RBX = 0x%" PRIx64 "\n", rbx);
|
||||
printf(">>> RCX = 0x%" PRIx64 "\n", rcx);
|
||||
printf(">>> RDX = 0x%" PRIx64 "\n", rdx);
|
||||
printf(">>> RSI = 0x%" PRIx64 "\n", rsi);
|
||||
printf(">>> RDI = 0x%" PRIx64 "\n", rdi);
|
||||
printf(">>> R8 = 0x%" PRIx64 "\n", r8);
|
||||
printf(">>> R9 = 0x%" PRIx64 "\n", r9);
|
||||
printf(">>> R10 = 0x%" PRIx64 "\n", r10);
|
||||
printf(">>> R11 = 0x%" PRIx64 "\n", r11);
|
||||
printf(">>> R12 = 0x%" PRIx64 "\n", r12);
|
||||
printf(">>> R13 = 0x%" PRIx64 "\n", r13);
|
||||
printf(">>> R14 = 0x%" PRIx64 "\n", r14);
|
||||
printf(">>> R15 = 0x%" PRIx64 "\n", r15);
|
||||
|
||||
uc_close(uc);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv, char **envp)
|
||||
{
|
||||
// dynamically load shared library
|
||||
#ifdef DYNLOAD
|
||||
if (!uc_dyn_load(NULL, 0)) {
|
||||
printf("Error dynamically loading shared library.\n");
|
||||
printf("Please check that unicorn.dll/unicorn.so is available as well as\n");
|
||||
printf("any other dependent dll/so files.\n");
|
||||
printf("The easiest way is to place them in the same directory as this app.\n");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
while(1) {
|
||||
test_i386();
|
||||
test_x86_64();
|
||||
}
|
||||
|
||||
// dynamically free shared library
|
||||
#ifdef DYNLOAD
|
||||
uc_dyn_free();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
@ -61,7 +61,7 @@ bool test2_delayslot_hooked = false;
|
||||
// This hook is used to show that code is executing in the emulator.
|
||||
static void mips_codehook(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
|
||||
{
|
||||
printf("Test %d Executing: %llX\n", test_num, address);
|
||||
printf("Test %d Executing: %"PRIx64"\n", test_num, address);
|
||||
if( test_num == 1 && address == 0x100010 )
|
||||
{
|
||||
printf("Delay slot hook called!\n");
|
||||
@ -107,7 +107,7 @@ int main(int argc, char **argv, char **envp)
|
||||
|
||||
// hook all instructions by having @begin > @end
|
||||
printf("uc_hook_add()\n");
|
||||
uc_hook_add(uc, &hhc, UC_HOOK_CODE, mips_codehook, NULL, (uint64_t)1, (uint64_t)0);
|
||||
uc_hook_add(uc, &hhc, UC_HOOK_CODE, mips_codehook, NULL, 1, 0);
|
||||
if( err )
|
||||
{
|
||||
printf("Failed on uc_hook_add(code) with error returned: %u\n", err);
|
||||
|
@ -59,7 +59,7 @@ static void mips_codehook(uc_engine *uc, uint64_t address, uint32_t size, void *
|
||||
printf("\nloop %d:\n", loop_count);
|
||||
loop_count++;
|
||||
}
|
||||
printf("Code: %llX\n", address);
|
||||
printf("Code: %"PRIx64"\n", address);
|
||||
}
|
||||
|
||||
|
||||
@ -100,7 +100,7 @@ int main(int argc, char **argv, char **envp)
|
||||
}
|
||||
|
||||
// hook all instructions by having @begin > @end
|
||||
uc_hook_add(uc, &hhc, UC_HOOK_CODE, mips_codehook, NULL, (uint64_t)1, (uint64_t)0);
|
||||
uc_hook_add(uc, &hhc, UC_HOOK_CODE, mips_codehook, NULL, 1, 0);
|
||||
if( err )
|
||||
{
|
||||
printf("Failed on uc_hook_add(code) with error returned: %u\n", err);
|
||||
|
@ -25,7 +25,7 @@ int main(int argc, char **argv, char **envp) {
|
||||
return 1;
|
||||
}
|
||||
uc_hook trace;
|
||||
uc_hook_add(uc, &trace, UC_HOOK_CODE, hook_code, NULL, (uint64_t)MEMORY_STARTING_ADDRESS, (uint64_t)(MEMORY_STARTING_ADDRESS + 1));
|
||||
uc_hook_add(uc, &trace, UC_HOOK_CODE, hook_code, NULL, MEMORY_STARTING_ADDRESS, MEMORY_STARTING_ADDRESS + 1);
|
||||
printf("uc_emu_start(…)\n");
|
||||
uc_emu_start(uc, MEMORY_STARTING_ADDRESS, MEMORY_STARTING_ADDRESS + sizeof(BINARY_CODE) - 1, 0, 0);
|
||||
printf("done\n");
|
||||
|
@ -83,10 +83,10 @@ int main(int argc, char **argv, char **envp)
|
||||
uc_mem_write(uc, 0x300000, (const uint8_t*)"\x41\x41\x41\x41", 4);
|
||||
uc_mem_write(uc, 0x400000, (const uint8_t*)"\x42\x42\x42\x42", 4);
|
||||
|
||||
//uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)0x400000, (uint64_t)0x400fff);
|
||||
//uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, 0x400000, 0x400fff);
|
||||
|
||||
// intercept invalid memory events
|
||||
uc_hook_add(uc, &trace1, UC_MEM_READ_PROT, hook_mem_invalid, NULL);
|
||||
uc_hook_add(uc, &trace1, UC_MEM_READ_PROT, hook_mem_invalid, NULL, 1, 0);
|
||||
|
||||
// emulate machine code in infinite time
|
||||
printf("BEGIN execution\n");
|
||||
|
@ -129,7 +129,7 @@ int main(int argc, char **argv, char **envp)
|
||||
printf("ok %d - Program written to memory\n", log_num++);
|
||||
}
|
||||
|
||||
if (uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) {
|
||||
if (uc_hook_add(uc, &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;
|
||||
}
|
||||
@ -138,7 +138,7 @@ int main(int argc, char **argv, char **envp)
|
||||
}
|
||||
|
||||
// intercept memory write events only, NOT read events
|
||||
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE, hook_mem_write, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) {
|
||||
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE, hook_mem_write, NULL, 1, 0) != UC_ERR_OK) {
|
||||
printf("not ok %d - Failed to install UC_HOOK_MEM_WRITE handler\n", log_num++);
|
||||
return 6;
|
||||
}
|
||||
|
@ -139,10 +139,10 @@ int main(int argc, char **argv, char **envp)
|
||||
printf("Allowed to write to read only memory via uc_mem_write\n");
|
||||
}
|
||||
|
||||
//uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)0x400000, (uint64_t)0x400fff);
|
||||
//uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, 0x400000, 0x400fff);
|
||||
|
||||
// intercept invalid memory events
|
||||
uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE_UNMAPPED | UC_HOOK_MEM_WRITE_PROT, hook_mem_invalid, NULL);
|
||||
uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE_UNMAPPED | UC_HOOK_MEM_WRITE_PROT, hook_mem_invalid, NULL, 1, 0);
|
||||
|
||||
// emulate machine code in infinite time
|
||||
printf("BEGIN execution - 1\n");
|
||||
|
@ -78,7 +78,7 @@ loop:
|
||||
}
|
||||
|
||||
|
||||
uc_hook_add(uc, &trace, UC_HOOK_MEM_WRITE | UC_HOOK_MEM_READ, (void *)hook_mem_rw, NULL);
|
||||
uc_hook_add(uc, &trace, UC_HOOK_MEM_WRITE | UC_HOOK_MEM_READ, (void *)hook_mem_rw, NULL, 1, 0);
|
||||
|
||||
uc_reg_write(uc, UC_X86_REG_EAX, &EAX);
|
||||
uc_reg_write(uc, UC_X86_REG_ESP, &ESP);
|
||||
|
@ -38,7 +38,7 @@ int main()
|
||||
uc_mem_write(uc, UC_BUG_WRITE_ADDR,
|
||||
(const uint8_t*)"\xff\xff\xff\xff\xff\xff\xff\xff", 8);
|
||||
}
|
||||
uc_hook_add(uc, &uh_trap, UC_HOOK_INTR, _interrupt, NULL);
|
||||
uc_hook_add(uc, &uh_trap, UC_HOOK_INTR, _interrupt, NULL, 1, 0);
|
||||
uc_emu_start(uc, UC_BUG_WRITE_ADDR, UC_BUG_WRITE_ADDR+8, 0, 1);
|
||||
uc_close(uc);
|
||||
printf ("Correct: %s\n", got_sigill? "YES": "NO");
|
||||
|
@ -36,7 +36,7 @@ int main(int argc, char **argv, char **envp)
|
||||
}
|
||||
|
||||
// Hook the SYSENTER instructions
|
||||
if (uc_hook_add (uc, &sysenterHook, UC_HOOK_INSN, sysenter, NULL, UC_X86_INS_SYSENTER) != UC_ERR_OK) {
|
||||
if (uc_hook_add (uc, &sysenterHook, UC_HOOK_INSN, sysenter, NULL, UC_X86_INS_SYSENTER, 1, 0) != UC_ERR_OK) {
|
||||
printf ("Cannot hook SYSENTER instruction\n.");
|
||||
return -1;
|
||||
}
|
||||
@ -57,4 +57,4 @@ int main(int argc, char **argv, char **envp)
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
0
tests/regress/tcg_liveness_analysis_bug_issue-287.py
Normal file → Executable file
0
tests/regress/tcg_liveness_analysis_bug_issue-287.py
Normal file → Executable file
@ -65,7 +65,7 @@ int loop_count = 0;
|
||||
// This hook is used to show that code is executing in the emulator.
|
||||
static void mips_codehook(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
|
||||
{
|
||||
printf("Code: %llX\n", address);
|
||||
printf("Code: %"PRIx64"\n", address);
|
||||
}
|
||||
|
||||
|
||||
@ -164,7 +164,7 @@ int main(int argc, char **argv, char **envp)
|
||||
|
||||
// hook all instructions by having @begin > @end
|
||||
printf("uc_hook_add()\n");
|
||||
uc_hook_add(uc, &hhc, UC_HOOK_CODE, mips_codehook, NULL, (uint64_t)1, (uint64_t)0);
|
||||
uc_hook_add(uc, &hhc, UC_HOOK_CODE, mips_codehook, NULL, 1, 0);
|
||||
if( err )
|
||||
{
|
||||
printf("Failed on uc_hook_add(code) with error returned: %u\n", err);
|
||||
|
@ -67,10 +67,10 @@ static void test_arm(void)
|
||||
uc_reg_write(uc, UC_ARM_REG_R3, &r3);
|
||||
|
||||
// tracing all basic blocks with customized callback
|
||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, 1, 0);
|
||||
|
||||
// tracing one instruction at ADDRESS with customized callback
|
||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
|
||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, ADDRESS, ADDRESS);
|
||||
|
||||
// emulate machine code in infinite time (last param = 0), or when
|
||||
// finishing all the code.
|
||||
@ -118,10 +118,10 @@ static void test_thumb(void)
|
||||
uc_reg_write(uc, UC_ARM_REG_SP, &sp);
|
||||
|
||||
// tracing all basic blocks with customized callback
|
||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, 1, 0);
|
||||
|
||||
// tracing one instruction at ADDRESS with customized callback
|
||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
|
||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, ADDRESS, ADDRESS);
|
||||
|
||||
// emulate machine code in infinite time (last param = 0), or when
|
||||
// finishing all the code.
|
||||
|
78
tests/regress/translator_buffer.py
Executable file
78
tests/regress/translator_buffer.py
Executable file
@ -0,0 +1,78 @@
|
||||
#!/usr/bin/python
|
||||
# By Mariano Graziano
|
||||
|
||||
from unicorn import *
|
||||
from unicorn.x86_const import *
|
||||
|
||||
import regress, struct
|
||||
|
||||
|
||||
class Emulator:
|
||||
def __init__(self, code, stack):
|
||||
self.mask = 0xFFFFFFFFFFFFF000
|
||||
self.unicorn_code = code
|
||||
self.unicorn_stack = stack
|
||||
self.mu = Uc(UC_ARCH_X86, UC_MODE_64)
|
||||
size = 1 * 4096
|
||||
self.mu.mem_map(code & self.mask, size)
|
||||
size = 1 * 4096
|
||||
self.mu.mem_map(stack & self.mask, size)
|
||||
self.set_hooks()
|
||||
|
||||
def set_hooks(self):
|
||||
self.mu.hook_add(UC_HOOK_MEM_WRITE, self.hook_mem_access)
|
||||
self.mu.hook_add(UC_HOOK_MEM_READ_UNMAPPED | UC_HOOK_MEM_WRITE_UNMAPPED, self.hook_mem_invalid)
|
||||
self.mu.hook_add(UC_HOOK_MEM_FETCH_UNMAPPED, self.hook_mem_fetch_unmapped)
|
||||
|
||||
def hook_mem_fetch_unmapped(self, uc, access, address, size, value, user_data):
|
||||
next_ip = self.unicorn_code + size
|
||||
self.mu.reg_write(UC_X86_REG_RIP, next_ip)
|
||||
self.mu.mem_write(next_ip, "\x90")
|
||||
self.mu.reg_write(UC_X86_REG_RIP, address)
|
||||
return True
|
||||
|
||||
def hook_mem_invalid(self, uc, access, address, size, value, user_data):
|
||||
return True
|
||||
|
||||
def hook_mem_access(self, uc, access, address, size, value, user_data):
|
||||
return True
|
||||
|
||||
def emu(self, size):
|
||||
ip = self.mu.reg_read(UC_X86_REG_RIP)
|
||||
try:
|
||||
self.mu.emu_start(ip, ip + size, timeout=10000, count=1)
|
||||
except UcError as e:
|
||||
print("Error %s" % e)
|
||||
|
||||
def write_data(self, address, content):
|
||||
self.mu.mem_write(address, content)
|
||||
|
||||
|
||||
class Init(regress.RegressTest):
|
||||
def init_unicorn(self, ip, sp, counter):
|
||||
print "[+] Emulating IP: %x SP: %x - Counter: %x" % (ip, sp, counter)
|
||||
E = Emulator(ip, sp)
|
||||
E.write_data(ip, "\x90")
|
||||
E.write_data(sp, self.generate_value(counter))
|
||||
E.mu.reg_write(UC_X86_REG_RSP, sp)
|
||||
E.mu.reg_write(UC_X86_REG_RIP, ip)
|
||||
E.emu(1)
|
||||
|
||||
def generate_value(self, counter):
|
||||
start = 0xffff880026f02000
|
||||
offset = counter * 8
|
||||
address = start + offset
|
||||
return struct.pack("<Q", address)
|
||||
|
||||
def runTest(self):
|
||||
global mu
|
||||
ips = list(range(0xffffffff816a9000, 0xffffffff816af000, 0x1))
|
||||
sps = list(range(0xffff88001b800000, 0xffff88001b801000, 0x1))
|
||||
j = 0
|
||||
for i in ips:
|
||||
j += 1
|
||||
index = ips.index(i)
|
||||
self.init_unicorn(i, sps[index], j)
|
||||
|
||||
if __name__ == '__main__':
|
||||
regress.main()
|
25
tests/regress/write_before_map.py
Executable file
25
tests/regress/write_before_map.py
Executable file
@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from __future__ import print_function
|
||||
from unicorn import *
|
||||
from unicorn.x86_const import *
|
||||
|
||||
import regress
|
||||
|
||||
X86_CODE64 = "\x90" # NOP
|
||||
|
||||
|
||||
class WriteBeforeMap(regress.RegressTest):
|
||||
def runTest(self):
|
||||
# Initialize emulator in X86-32bit mode
|
||||
mu = Uc(UC_ARCH_X86, UC_MODE_64)
|
||||
|
||||
# memory address where emulation starts
|
||||
ADDRESS = 0x1000000
|
||||
|
||||
# write machine code to be emulated to memory
|
||||
mu.mem_write(ADDRESS, X86_CODE64)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
regress.main()
|
39
tests/regress/x86_64_conditional_jump.py
Executable file
39
tests/regress/x86_64_conditional_jump.py
Executable file
@ -0,0 +1,39 @@
|
||||
#!/usr/bin/python
|
||||
import regress
|
||||
import unicorn as U
|
||||
|
||||
class WrongConditionalPath(regress.RegressTest):
|
||||
def test_eflags(self):
|
||||
# 0: 4d 31 f6 xor r14, r14
|
||||
# 3: 45 85 f6 test r14d, r14d
|
||||
# 6: 75 fe jne 0x6
|
||||
# 8: f4 hlt
|
||||
CODE = 'M1\xf6E\x85\xf6u\xfe\xf4'
|
||||
|
||||
uc = U.Uc(U.UC_ARCH_X86, U.UC_MODE_64)
|
||||
uc.reg_write(U.x86_const.UC_X86_REG_RIP, 0x6000b0)
|
||||
uc.reg_write(U.x86_const.UC_X86_REG_EFLAGS, 0x246)
|
||||
|
||||
uc.mem_map(0x600000, 0x1000)
|
||||
uc.mem_write(0x6000b0, CODE)
|
||||
|
||||
uc.emu_start(0x6000b0 + 6, 0, count=1)
|
||||
|
||||
# Here's the original execution trace for this on qemu-user.
|
||||
#
|
||||
# $ SC='xor r14,r14; test r14d, r14d; jne $; hlt'
|
||||
# $ asm --context amd64 --format elf $SC > example
|
||||
# $ qemu-x86_64-static -d cpu,in_asm -singlestep ./test \
|
||||
# | grep -E 'RFL|^0x'
|
||||
# 0x00000000006000b0: xor %r14,%r14
|
||||
# RIP=00000000006000b0 RFL=00000202 [-------] CPL=3 II=0 A20=1 SMM=0 HLT=0
|
||||
# 0x00000000006000b3: test %r14d,%r14d
|
||||
# RIP=00000000006000b3 RFL=00000246 [---Z-P-] CPL=3 II=0 A20=1 SMM=0 HLT=0
|
||||
# 0x00000000006000b6: jne 0x6000b6
|
||||
# RIP=00000000006000b6 RFL=00000246 [---Z-P-] CPL=3 II=0 A20=1 SMM=0 HLT=0
|
||||
# 0x00000000006000b8: hlt
|
||||
# RIP=00000000006000b8 RFL=00000246 [---Z-P-] CPL=3 II=0 A20=1 SMM=0 HLT=0
|
||||
self.assertEqual(0x6000b0 + 8, uc.reg_read(U.x86_const.UC_X86_REG_RIP))
|
||||
|
||||
if __name__ == '__main__':
|
||||
regress.main()
|
38
tests/regress/x86_64_eflags.py
Executable file
38
tests/regress/x86_64_eflags.py
Executable file
@ -0,0 +1,38 @@
|
||||
#!/usr/bin/python
|
||||
import regress
|
||||
import unicorn as U
|
||||
|
||||
class WrongEFLAGS(regress.RegressTest):
|
||||
def test_eflags(self):
|
||||
# xor r14,r14
|
||||
CODE = 'M1\xf6'
|
||||
|
||||
uc = U.Uc(U.UC_ARCH_X86, U.UC_MODE_64)
|
||||
uc.reg_write(U.x86_const.UC_X86_REG_RIP, 0x6000b0)
|
||||
uc.reg_write(U.x86_const.UC_X86_REG_EFLAGS, 0x200)
|
||||
|
||||
uc.mem_map(0x600000, 0x1000)
|
||||
uc.mem_write(0x6000b0, CODE)
|
||||
uc.emu_start(0x6000b0, 0, count=1)
|
||||
|
||||
|
||||
# Here's the original execution trace for this on actual hardware.
|
||||
#
|
||||
# (gdb) x/i $pc
|
||||
# => 0x6000b0: xor %r14,%r14
|
||||
# (gdb) p/x $eflags
|
||||
# $1 = 0x200
|
||||
# (gdb) p $eflags
|
||||
# $2 = [ IF ]
|
||||
# (gdb) si
|
||||
# 0x00000000006000b3 in ?? ()
|
||||
# (gdb) p/x $eflags
|
||||
# $3 = 0x246
|
||||
# (gdb) p $eflags
|
||||
# $4 = [ PF ZF IF ]
|
||||
|
||||
self.assertEqual(0x6000b3, uc.reg_read(U.x86_const.UC_X86_REG_RIP))
|
||||
self.assertEqual(0x246, uc.reg_read(U.x86_const.UC_X86_REG_EFLAGS))
|
||||
|
||||
if __name__ == '__main__':
|
||||
regress.main()
|
94
tests/regress/x86_gdt.py
Executable file
94
tests/regress/x86_gdt.py
Executable file
@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env python
|
||||
from unicorn import *
|
||||
from unicorn.x86_const import *
|
||||
from struct import pack
|
||||
|
||||
import regress
|
||||
|
||||
F_GRANULARITY = 0x8
|
||||
F_PROT_32 = 0x4
|
||||
F_LONG = 0x2
|
||||
F_AVAILABLE = 0x1
|
||||
|
||||
A_PRESENT = 0x80
|
||||
|
||||
A_PRIV_3 = 0x60
|
||||
A_PRIV_2 = 0x40
|
||||
A_PRIV_1 = 0x20
|
||||
A_PRIV_0 = 0x0
|
||||
|
||||
A_CODE = 0x10
|
||||
A_DATA = 0x10
|
||||
A_TSS = 0x0
|
||||
A_GATE = 0x0
|
||||
|
||||
A_DATA_WRITABLE = 0x2
|
||||
A_CODE_READABLE = 0x2
|
||||
|
||||
A_DIR_CON_BIT = 0x4
|
||||
|
||||
S_GDT = 0x0
|
||||
S_LDT = 0x4
|
||||
S_PRIV_3 = 0x3
|
||||
S_PRIV_2 = 0x2
|
||||
S_PRIV_1 = 0x1
|
||||
S_PRIV_0 = 0x0
|
||||
|
||||
CODE = '65330d18000000'.decode('hex') # xor ecx, dword ptr gs:[0x18]
|
||||
|
||||
def create_selector(idx, flags):
|
||||
to_ret = flags
|
||||
to_ret |= idx << 3
|
||||
return to_ret
|
||||
|
||||
def create_gdt_entry(base, limit, access, flags):
|
||||
|
||||
to_ret = limit & 0xffff;
|
||||
to_ret |= (base & 0xffffff) << 16;
|
||||
to_ret |= (access & 0xff) << 40;
|
||||
to_ret |= ((limit >> 16) & 0xf) << 48;
|
||||
to_ret |= (flags & 0xff) << 52;
|
||||
to_ret |= ((base >> 24) & 0xff) << 56;
|
||||
return pack('<Q',to_ret)
|
||||
|
||||
def hook_mem_read(uc, type, addr,*args):
|
||||
print(hex(addr))
|
||||
return False
|
||||
|
||||
CODE_ADDR = 0x40000
|
||||
CODE_SIZE = 0x1000
|
||||
|
||||
GDT_ADDR = 0x3000
|
||||
GDT_LIMIT = 0x1000
|
||||
GDT_ENTRY_SIZE = 0x8
|
||||
|
||||
SEGMENT_ADDR = 0x5000
|
||||
SEGMENT_SIZE = 0x1000
|
||||
|
||||
class GdtRead(regress.RegressTest):
|
||||
|
||||
def test_gdt(self):
|
||||
uc = Uc(UC_ARCH_X86, UC_MODE_32)
|
||||
uc.hook_add(UC_HOOK_MEM_READ_UNMAPPED, hook_mem_read)
|
||||
|
||||
uc.mem_map(GDT_ADDR, GDT_LIMIT)
|
||||
uc.mem_map(SEGMENT_ADDR, SEGMENT_SIZE)
|
||||
uc.mem_map(CODE_ADDR, CODE_SIZE)
|
||||
|
||||
uc.mem_write(CODE_ADDR, CODE)
|
||||
uc.mem_write(SEGMENT_ADDR+0x18, 'AAAA')
|
||||
|
||||
gdt_entry = create_gdt_entry(SEGMENT_ADDR, SEGMENT_SIZE, A_PRESENT | A_DATA | A_DATA_WRITABLE | A_PRIV_3 | A_DIR_CON_BIT, F_PROT_32)
|
||||
uc.mem_write(GDT_ADDR + 8, gdt_entry)
|
||||
|
||||
uc.reg_write(UC_X86_REG_GDTR, (0, GDT_ADDR, GDT_LIMIT, 0x0))
|
||||
|
||||
selector = create_selector(1, S_GDT | S_PRIV_3)
|
||||
uc.reg_write(UC_X86_REG_GS, selector)
|
||||
|
||||
uc.emu_start(CODE_ADDR, CODE_ADDR+len(CODE))
|
||||
|
||||
self.assertEqual(uc.reg_read(UC_X86_REG_ECX), 0x41414141)
|
||||
|
||||
if __name__ == '__main__':
|
||||
regress.main()
|
@ -4,8 +4,16 @@ CFLAGS += -L ../../
|
||||
CFLAGS += -lcmocka -lunicorn
|
||||
CFLAGS += -I ../../include
|
||||
|
||||
ifeq ($(UNICORN_ASAN),yes)
|
||||
CC = clang -fsanitize=address -fno-omit-frame-pointer
|
||||
CXX = clang++ -fsanitize=address -fno-omit-frame-pointer
|
||||
AR = llvm-ar
|
||||
LDFLAGS := -fsanitize=address ${LDFLAGS}
|
||||
endif
|
||||
|
||||
ALL_TESTS = test_sanity test_x86 test_mem_map test_mem_high test_mem_map_ptr \
|
||||
test_tb_x86 test_multihook test_pc_change test_x86_soft_paging
|
||||
test_tb_x86 test_multihook test_pc_change test_x86_soft_paging \
|
||||
test_hookcounts
|
||||
|
||||
.PHONY: all
|
||||
all: ${ALL_TESTS}
|
||||
@ -26,6 +34,7 @@ test: ${ALL_TESTS}
|
||||
./test_multihook
|
||||
./test_pc_change
|
||||
./test_x86_soft_paging
|
||||
./test_hookcounts
|
||||
|
||||
test_sanity: test_sanity.c
|
||||
test_x86: test_x86.c
|
||||
@ -36,6 +45,7 @@ test_tb_x86: test_tb_x86.c
|
||||
test_multihook: test_multihook.c
|
||||
test_pc_change: test_pc_change.c
|
||||
test_x86_soft_paging: test_x86_soft_paging.c
|
||||
test_hookcounts: test_hookcounts.c
|
||||
|
||||
${ALL_TESTS}:
|
||||
${CC} ${CFLAGS} -o $@ $^
|
||||
|
281
tests/unit/test_hookcounts.c
Normal file
281
tests/unit/test_hookcounts.c
Normal file
@ -0,0 +1,281 @@
|
||||
// Test hook evocation count
|
||||
//
|
||||
// Objective is to demonstrate finer duration control of
|
||||
// emulation by counts of instruction code
|
||||
//
|
||||
#include "unicorn_test.h"
|
||||
#include <inttypes.h>
|
||||
|
||||
#define DEBUG 1
|
||||
|
||||
#define OK(x) uc_assert_success(x)
|
||||
|
||||
volatile int expected_instructions = 0;
|
||||
volatile int total_instructions = 0;
|
||||
|
||||
|
||||
// NOTE: It would appear that this UC_HOOK_CODE is being done before the
|
||||
// uc_count_fb hook.
|
||||
// So, termination by uc->emu_count has not been done yet here...
|
||||
static void test_code_hook(uc_engine *uc,
|
||||
uint64_t address,
|
||||
uint32_t size,
|
||||
void *user_data)
|
||||
{
|
||||
|
||||
++total_instructions;
|
||||
if (total_instructions == expected_instructions)
|
||||
{
|
||||
uc_emu_stop(uc);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("instruction at 0x%"PRIx64": ", address);
|
||||
uint8_t tmp[256];
|
||||
if (!uc_mem_read(uc, address, tmp, size)) {
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
printf("0x%x ", tmp[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif // DEBUG
|
||||
}
|
||||
|
||||
|
||||
/* Called before every test to set up a new instance */
|
||||
static int setup32(void **state)
|
||||
{
|
||||
uc_hook trace1;
|
||||
uc_engine *uc;
|
||||
|
||||
OK(uc_open(UC_ARCH_X86, UC_MODE_32, &uc));
|
||||
|
||||
*state = uc;
|
||||
|
||||
// trace all instructions
|
||||
OK(uc_hook_add(uc, &trace1, UC_HOOK_CODE, test_code_hook, NULL, 1, 0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Called after every test to clean up */
|
||||
static int teardown(void **state)
|
||||
{
|
||||
uc_engine *uc = *state;
|
||||
|
||||
OK(uc_close(uc));
|
||||
|
||||
*state = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static void
|
||||
test_hook_count(uc_engine *uc,
|
||||
const uint8_t *code,
|
||||
int start_offset,
|
||||
int code_length,
|
||||
int count)
|
||||
{
|
||||
|
||||
#define BASEADDR 0x1000000
|
||||
#define MEMSIZE (2 * 1024 * 1024)
|
||||
|
||||
uint64_t address = BASEADDR + (count * MEMSIZE);
|
||||
total_instructions = 0;
|
||||
|
||||
#undef BASEADDR
|
||||
|
||||
// map a new 2MB memory for this emulation
|
||||
OK(uc_mem_map(uc, address, MEMSIZE, UC_PROT_ALL));
|
||||
|
||||
// write machine code to be emulated to memory
|
||||
OK(uc_mem_write(uc, address, code, code_length));
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Address: %"PRIx64"\n", address);
|
||||
printf("Start : %"PRIx64"\n", address + start_offset);
|
||||
printf("End : %"PRIx64"\n", address + code_length - 1);
|
||||
printf("Count : %d\n", count);
|
||||
#endif
|
||||
expected_instructions = count;
|
||||
OK(uc_emu_start(uc,
|
||||
address+start_offset,
|
||||
address+code_length,
|
||||
0,
|
||||
count));
|
||||
|
||||
assert_int_equal(expected_instructions, total_instructions);
|
||||
|
||||
// map 2MB memory for this emulation
|
||||
OK(uc_mem_unmap(uc, address, MEMSIZE));
|
||||
}
|
||||
|
||||
|
||||
/* Perform fine-grain emulation control of exactly 1 instruction */
|
||||
/* of 1-opcode code space*/
|
||||
static void test_hook_count_1_begin(void **state)
|
||||
{
|
||||
uc_engine *uc = *state;
|
||||
const uint8_t code[] = {
|
||||
0x41, // inc ECX @0x1000000
|
||||
};
|
||||
int code_length = sizeof(code);
|
||||
int start_offset = 0;
|
||||
int ins_count = 1;
|
||||
|
||||
test_hook_count(uc, code, start_offset, code_length, ins_count);
|
||||
}
|
||||
|
||||
|
||||
/* Perform fine-grain emulation control of exactly 1 instruction */
|
||||
static void test_hook_count_1_midpoint(void **state)
|
||||
{
|
||||
uc_engine *uc = *state;
|
||||
const uint8_t code[] = {
|
||||
0x41, // inc ECX @0x1000000
|
||||
0x41, // inc ECX
|
||||
0x41, // inc ECX
|
||||
0x41, // inc ECX @0x1000003
|
||||
0x41, // inc ECX
|
||||
0x41, // inc ECX
|
||||
0x42, // inc EDX @0x1000006
|
||||
0x42, // inc EDX
|
||||
};
|
||||
int code_length = sizeof(code);
|
||||
int start_offset = code_length/2;
|
||||
int ins_count = 1;
|
||||
|
||||
test_hook_count(uc, code, start_offset, code_length, ins_count);
|
||||
}
|
||||
|
||||
|
||||
/* Perform fine-grain emulation control of exactly 1 instruction */
|
||||
static void test_hook_count_1_end(void **state)
|
||||
{
|
||||
uc_engine *uc = *state;
|
||||
const uint8_t code[] = {
|
||||
0x41, // inc ECX @0x1000000
|
||||
0x41, // inc ECX
|
||||
0x41, // inc ECX
|
||||
0x41, // inc ECX @0x1000003
|
||||
0x41, // inc ECX
|
||||
0x41, // inc ECX
|
||||
0x42, // inc EDX @0x1000006
|
||||
0x42, // inc EDX
|
||||
};
|
||||
int code_length = sizeof(code);
|
||||
int start_offset = code_length - 1;
|
||||
int ins_count = 1;
|
||||
|
||||
test_hook_count(uc, code, start_offset, code_length, ins_count);
|
||||
}
|
||||
|
||||
|
||||
/* Perform fine-grain emulation control over a range of */
|
||||
/* varied instruction steps. */
|
||||
static void test_hook_count_range(void **state)
|
||||
{
|
||||
uc_engine *uc = *state;
|
||||
const uint8_t code[] = {
|
||||
0x41, // inc ECX @0x1000000
|
||||
0x41, // inc ECX
|
||||
0x41, // inc ECX
|
||||
0x41, // inc ECX @0x1000003
|
||||
0x41, // inc ECX
|
||||
0x41, // inc ECX
|
||||
0x42, // inc EDX @0x1000006
|
||||
0x42, // inc EDX
|
||||
};
|
||||
int code_length = sizeof(code);
|
||||
int start_offset;
|
||||
int ins_count = 2;
|
||||
|
||||
for (start_offset = 2; start_offset < (code_length - ins_count); start_offset++)
|
||||
{
|
||||
printf("Iteration %d\n", start_offset);
|
||||
test_hook_count(uc, code, start_offset, code_length, ins_count);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void test_hook_count_end(void **state)
|
||||
{
|
||||
uc_engine *uc = *state;
|
||||
const uint8_t code[] = {
|
||||
0x41, // inc ECX @0x1000000
|
||||
0x41, // inc ECX
|
||||
0x41, // inc ECX
|
||||
0x41, // inc ECX @0x1000003
|
||||
0x41, // inc ECX
|
||||
0x41, // inc ECX
|
||||
0x42, // inc EDX @0x1000006
|
||||
0x42, // inc EDX
|
||||
};
|
||||
int code_length = sizeof(code);
|
||||
int ins_count = 3;
|
||||
int start_offset = sizeof(code) - ins_count;
|
||||
|
||||
test_hook_count(uc, code, start_offset, code_length, ins_count);
|
||||
}
|
||||
|
||||
|
||||
static void test_hook_count_begins(void **state)
|
||||
{
|
||||
uc_engine *uc = *state;
|
||||
const uint8_t code[] = {
|
||||
0x41, // inc ECX @0x1000000
|
||||
0x41, // inc ECX
|
||||
0x41, // inc ECX
|
||||
0x41, // inc ECX @0x1000003
|
||||
0x41, // inc ECX
|
||||
0x41, // inc ECX
|
||||
0x42, // inc EDX @0x1000006
|
||||
0x42, // inc EDX
|
||||
};
|
||||
int code_length = sizeof(code);
|
||||
int ins_count = 3;
|
||||
int start_offset = 0;
|
||||
|
||||
test_hook_count(uc, code, start_offset, code_length, ins_count);
|
||||
}
|
||||
|
||||
|
||||
static void test_hook_count_midpoint(void **state)
|
||||
{
|
||||
uc_engine *uc = *state;
|
||||
const uint8_t code[] = {
|
||||
0x41, // inc ECX @0x1000000
|
||||
0x41, // inc ECX
|
||||
0x41, // inc ECX
|
||||
0x41, // inc ECX @0x1000003
|
||||
0x41, // inc ECX
|
||||
0x41, // inc ECX
|
||||
0x42, // inc EDX @0x1000006
|
||||
0x42, // inc EDX
|
||||
};
|
||||
int code_length = sizeof(code);
|
||||
int ins_count = 3;
|
||||
int start_offset = 2;
|
||||
|
||||
test_hook_count(uc, code, start_offset, code_length, ins_count);
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
const struct CMUnitTest tests[] = {
|
||||
cmocka_unit_test_setup_teardown(test_hook_count_1_begin, setup32, teardown),
|
||||
cmocka_unit_test_setup_teardown(test_hook_count_1_midpoint, setup32, teardown),
|
||||
cmocka_unit_test_setup_teardown(test_hook_count_1_end, setup32, teardown),
|
||||
cmocka_unit_test_setup_teardown(test_hook_count_begins, setup32, teardown),
|
||||
cmocka_unit_test_setup_teardown(test_hook_count_range, setup32, teardown),
|
||||
cmocka_unit_test_setup_teardown(test_hook_count_midpoint, setup32, teardown),
|
||||
cmocka_unit_test_setup_teardown(test_hook_count_end, setup32, teardown),
|
||||
};
|
||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||
}
|
||||
|
@ -158,6 +158,15 @@ static void test_strange_map(void **state)
|
||||
uc_mem_unmap(uc, 0x0,0x1000);
|
||||
}
|
||||
|
||||
static void test_query_page_size(void **state)
|
||||
{
|
||||
uc_engine *uc = *state;
|
||||
|
||||
size_t page_size;
|
||||
uc_assert_success(uc_query(uc, UC_QUERY_PAGE_SIZE, &page_size));
|
||||
assert_int_equal(4096, page_size);
|
||||
}
|
||||
|
||||
void write(uc_engine* uc, uint64_t addr, uint64_t len){
|
||||
uint8_t* buff = alloca(len);
|
||||
memset(buff,0,len);
|
||||
@ -220,6 +229,7 @@ int main(void) {
|
||||
test(test_unmap_double_map),
|
||||
test(test_overlap_unmap_double_map),
|
||||
test(test_strange_map),
|
||||
test(test_query_page_size),
|
||||
};
|
||||
#undef test
|
||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||
|
Reference in New Issue
Block a user