bring new code and samples up-to-date with API changes

This commit is contained in:
Jonathon Reinhart 2015-09-03 22:15:49 -04:00
parent 5e9d07a40a
commit da46071c7d
6 changed files with 108 additions and 117 deletions

View File

@ -433,7 +433,7 @@ uc_err uc_mem_map(ucengine *uc, uint64_t address, size_t size, uint32_t perms);
for detailed error).
*/
UNICORN_EXPORT
uc_err uc_mem_unmap(uch handle, uint64_t address, size_t size);
uc_err uc_mem_unmap(ucengine *uc, uint64_t address, size_t size);
/*
Set memory permissions for emulation memory.
@ -452,7 +452,7 @@ uc_err uc_mem_unmap(uch handle, uint64_t address, size_t size);
for detailed error).
*/
UNICORN_EXPORT
uc_err uc_mem_protect(uch handle, uint64_t address, size_t size, uint32_t perms);
uc_err uc_mem_protect(ucengine *uc, uint64_t address, size_t size, uint32_t perms);
#ifdef __cplusplus
}

View File

@ -185,7 +185,7 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
// Unicorn: callback on fetch from NX
if (mr != NULL && !(mr->perms & UC_PROT_EXEC)) { //non-executable
if (uc->hook_mem_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)(
(uch)uc, UC_MEM_EXEC_PROT, addr, DATA_SIZE, 0,
uc, UC_MEM_EXEC_PROT, addr, DATA_SIZE, 0,
uc->hook_callbacks[uc->hook_mem_idx].user_data)) {
env->invalid_error = UC_ERR_OK;
} else {
@ -343,7 +343,7 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
// Unicorn: callback on fetch from NX
if (mr != NULL && !(mr->perms & UC_PROT_EXEC)) { //non-executable
if (uc->hook_mem_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)(
(uch)uc, UC_MEM_EXEC_PROT, addr, DATA_SIZE, 0,
uc, UC_MEM_EXEC_PROT, addr, DATA_SIZE, 0,
uc->hook_callbacks[uc->hook_mem_idx].user_data)) {
env->invalid_error = UC_ERR_OK;
} else {

View File

@ -78,11 +78,11 @@ static int log_num = 1;
#define CODE_SIZE 0x1000
// callback for tracing instruction
static void hook_code(uch handle, uint64_t addr, uint32_t size, void *user_data)
static void hook_code(ucengine *uc, uint64_t addr, uint32_t size, void *user_data)
{
uint8_t opcode;
if (uc_mem_read(handle, addr, &opcode, 1) != UC_ERR_OK) {
if (uc_mem_read(uc, 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);
}
@ -90,7 +90,7 @@ static void hook_code(uch handle, uint64_t addr, uint32_t size, void *user_data)
switch (opcode) {
case 0xf4: //hlt
printf("# Handling HLT\n");
if (uc_emu_stop(handle) != UC_ERR_OK) {
if (uc_emu_stop(uc) != 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 {
@ -104,14 +104,14 @@ static void hook_code(uch handle, uint64_t addr, uint32_t size, void *user_data)
}
// callback for tracing memory access (READ or WRITE)
static void hook_mem_write(uch handle, uc_mem_type type,
static void hook_mem_write(ucengine *uc, 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);
}
// callback for tracing invalid memory access (READ or WRITE)
static bool hook_mem_invalid(uch handle, uc_mem_type type,
static bool hook_mem_invalid(ucengine *uc, uc_mem_type type,
uint64_t addr, int size, int64_t value, void *user_data)
{
switch(type) {
@ -122,7 +122,7 @@ static bool hook_mem_invalid(uch handle, uc_mem_type type,
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) {
if (uc_mem_protect(uc, 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);
@ -131,7 +131,7 @@ static bool hook_mem_invalid(uch handle, uc_mem_type type,
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) {
if (uc_mem_protect(uc, 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++);
@ -142,7 +142,8 @@ static bool hook_mem_invalid(uch handle, uc_mem_type type,
int main(int argc, char **argv, char **envp)
{
uch handle, trace1, trace2;
ucengine *uc;
uc_hook_h trace1, trace2;
uc_err err;
uint32_t esp, eip;
int32_t buf1[1024], buf2[1024], readbuf[1024];
@ -158,7 +159,7 @@ int main(int argc, char **argv, char **envp)
printf("# Memory protect test\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &handle);
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
if (err) {
printf("not ok %d - Failed on uc_open() with error returned: %u\n", log_num++, err);
return 1;
@ -166,15 +167,15 @@ int main(int argc, char **argv, char **envp)
printf("ok %d - uc_open() success\n", log_num++);
}
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);
uc_mem_map(uc, 0x100000, 0x1000, UC_PROT_READ | UC_PROT_EXEC);
uc_mem_map(uc, 0x1ff000, 0x2000, UC_PROT_READ | UC_PROT_WRITE);
uc_mem_map(uc, 0x300000, 0x2000, UC_PROT_READ);
uc_mem_map(uc, 0xf00000, 0x1000, UC_PROT_READ | UC_PROT_WRITE);
esp = 0xf00000 + 0x1000;
// Setup stack pointer
if (uc_reg_write(handle, UC_X86_REG_ESP, &esp)) {
if (uc_reg_write(uc, UC_X86_REG_ESP, &esp)) {
printf("not ok %d - Failed to set esp. quit!\n", log_num++);
return 2;
} else {
@ -182,14 +183,14 @@ int main(int argc, char **argv, char **envp)
}
// fill in sections that shouldn't get touched
if (uc_mem_write(handle, 0x1ff000, (uint8_t*)buf1, 4096)) {
if (uc_mem_write(uc, 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++);
}
if (uc_mem_write(handle, 0x301000, (uint8_t*)buf2, 4096)) {
if (uc_mem_write(uc, 0x301000, (uint8_t*)buf2, 4096)) {
printf("not ok %d - Failed to write random buffer 2 to memory, quit!\n", log_num++);
return 4;
} else {
@ -197,31 +198,31 @@ int main(int argc, char **argv, char **envp)
}
// write machine code to be emulated to memory
if (uc_mem_write(handle, 0x100000, PROGRAM, sizeof(PROGRAM))) {
if (uc_mem_write(uc, 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_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) {
printf("not ok %d - Failed to install UC_HOOK_CODE handler\n", log_num++);
if (uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) {
printf("not ok %d - Failed to install UC_HOOK_CODE ucr\n", log_num++);
return 6;
} else {
printf("ok %d - UC_HOOK_CODE installed\n", log_num++);
}
// intercept memory write events
if (uc_hook_add(handle, &trace1, UC_HOOK_MEM_WRITE, hook_mem_write, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) {
printf("not ok %d - Failed to install UC_HOOK_MEM_WRITE handler\n", log_num++);
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE, hook_mem_write, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) {
printf("not ok %d - Failed to install UC_HOOK_MEM_WRITE ucr\n", log_num++);
return 7;
} else {
printf("ok %d - UC_HOOK_MEM_WRITE 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++);
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_INVALID, hook_mem_invalid, NULL) != UC_ERR_OK) {
printf("not ok %d - Failed to install UC_HOOK_MEM_INVALID ucr\n", log_num++);
return 8;
} else {
printf("ok %d - UC_HOOK_MEM_INVALID installed\n", log_num++);
@ -229,7 +230,7 @@ int main(int argc, char **argv, char **envp)
// emulate machine code until told to stop by hook_code
printf("# BEGIN execution\n");
err = uc_emu_start(handle, 0x100000, 0x400000, 0, 0);
err = uc_emu_start(uc, 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;
@ -239,7 +240,7 @@ int main(int argc, char **argv, char **envp)
printf("# END execution\n");
// get ending EIP
if (uc_reg_read(handle, UC_X86_REG_EIP, &eip)) {
if (uc_reg_read(uc, 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);
@ -247,7 +248,7 @@ int main(int argc, char **argv, char **envp)
//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)) {
if (uc_mem_read(uc, 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++);
@ -258,7 +259,7 @@ int main(int argc, char **argv, char **envp)
}
}
if (uc_mem_read(handle, 0x301000, (uint8_t*)readbuf, 4096)) {
if (uc_mem_read(uc, 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++);
@ -269,7 +270,7 @@ int main(int argc, char **argv, char **envp)
}
}
if (uc_close(&handle) == UC_ERR_OK) {
if (uc_close(uc) == UC_ERR_OK) {
printf("ok %d - uc_close complete\n", log_num++);
} else {
printf("not ok %d - uc_close complete\n", log_num++);

View File

@ -77,18 +77,18 @@ static int log_num = 1;
#define CODE_SIZE 0x1000
// callback for tracing instruction
static void hook_code(uch handle, uint64_t addr, uint32_t size, void *user_data)
static void hook_code(ucengine *uc, 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) {
if (uc_mem_read(uc, 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) {
if (uc_mem_read(uc, 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);
@ -102,7 +102,7 @@ static void hook_code(uch handle, uint64_t addr, uint32_t size, void *user_data)
printf("# Received: 0x%x\n", testval);
}
}
if (uc_mem_protect(handle, 0x200000 + test_num * 0x100000, 0x1000, UC_PROT_READ) != UC_ERR_OK) {
if (uc_mem_protect(uc, 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++);
@ -111,7 +111,7 @@ static void hook_code(uch handle, uint64_t addr, uint32_t size, void *user_data)
break;
case 0xf4: //hlt
printf("# Handling HLT\n");
if (uc_emu_stop(handle) != UC_ERR_OK) {
if (uc_emu_stop(uc) != 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 {
@ -125,14 +125,14 @@ static void hook_code(uch handle, uint64_t addr, uint32_t size, void *user_data)
}
// callback for tracing memory access (READ or WRITE)
static void hook_mem_write(uch handle, uc_mem_type type,
static void hook_mem_write(ucengine *uc, 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);
}
// callback for tracing invalid memory access (READ or WRITE)
static bool hook_mem_invalid(uch handle, uc_mem_type type,
static bool hook_mem_invalid(ucengine *uc, uc_mem_type type,
uint64_t addr, int size, int64_t value, void *user_data)
{
uint32_t testval;
@ -143,13 +143,13 @@ static bool hook_mem_invalid(uch handle, uc_mem_type type,
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) {
if (uc_mem_read(uc, 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) {
if (uc_mem_protect(uc, 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++);
@ -160,7 +160,8 @@ static bool hook_mem_invalid(uch handle, uc_mem_type type,
int main(int argc, char **argv, char **envp)
{
uch handle, trace1, trace2;
ucengine *uc;
uc_hook_h trace1, trace2;
uc_err err;
uint32_t addr, testval;
int32_t buf1[1024], buf2[1024], readbuf[1024];
@ -176,7 +177,7 @@ int main(int argc, char **argv, char **envp)
printf("# Memory protect test\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &handle);
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
if (err) {
printf("not ok %d - Failed on uc_open() with error returned: %u\n", log_num++, err);
return 1;
@ -184,20 +185,20 @@ int main(int argc, char **argv, char **envp)
printf("ok %d - uc_open() success\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);
uc_mem_map(uc, CODE_SECTION, CODE_SIZE, UC_PROT_READ | UC_PROT_EXEC);
uc_mem_map(uc, 0x200000, 0x1000, UC_PROT_READ | UC_PROT_WRITE);
uc_mem_map(uc, 0x300000, 0x1000, UC_PROT_READ | UC_PROT_WRITE);
uc_mem_map(uc, 0x3ff000, 0x3000, UC_PROT_READ | UC_PROT_WRITE);
// fill in sections that shouldn't get touched
if (uc_mem_write(handle, 0x3ff000, (uint8_t*)buf1, 4096)) {
if (uc_mem_write(uc, 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++);
}
if (uc_mem_write(handle, 0x401000, (uint8_t*)buf2, 4096)) {
if (uc_mem_write(uc, 0x401000, (uint8_t*)buf2, 4096)) {
printf("not ok %d - Failed to write random buffer 2 to memory, quit!\n", log_num++);
return 3;
} else {
@ -205,31 +206,31 @@ int main(int argc, char **argv, char **envp)
}
// write machine code to be emulated to memory
if (uc_mem_write(handle, CODE_SECTION, PROGRAM, sizeof(PROGRAM))) {
if (uc_mem_write(uc, 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_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) {
printf("not ok %d - Failed to install UC_HOOK_CODE handler\n", log_num++);
if (uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) {
printf("not ok %d - Failed to install UC_HOOK_CODE ucr\n", log_num++);
return 5;
} else {
printf("ok %d - UC_HOOK_CODE installed\n", log_num++);
}
// intercept memory write events
if (uc_hook_add(handle, &trace1, UC_HOOK_MEM_WRITE, hook_mem_write, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) {
printf("not ok %d - Failed to install UC_HOOK_MEM_WRITE handler\n", log_num++);
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE, hook_mem_write, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) {
printf("not ok %d - Failed to install UC_HOOK_MEM_WRITE ucr\n", log_num++);
return 6;
} else {
printf("ok %d - UC_HOOK_MEM_WRITE 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++);
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_INVALID, hook_mem_invalid, NULL) != UC_ERR_OK) {
printf("not ok %d - Failed to install UC_HOOK_MEM_INVALID ucr\n", log_num++);
return 7;
} else {
printf("ok %d - UC_HOOK_MEM_INVALID installed\n", log_num++);
@ -237,7 +238,7 @@ int main(int argc, char **argv, char **envp)
// 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);
err = uc_emu_start(uc, 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;
@ -250,7 +251,7 @@ int main(int argc, char **argv, char **envp)
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) {
if (uc_mem_read(uc, 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);
@ -269,7 +270,7 @@ int main(int argc, char **argv, char **envp)
//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)) {
if (uc_mem_read(uc, 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++);
@ -280,7 +281,7 @@ int main(int argc, char **argv, char **envp)
}
}
if (uc_mem_read(handle, 0x401000, (uint8_t*)readbuf, 4096)) {
if (uc_mem_read(uc, 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++);
@ -291,7 +292,7 @@ int main(int argc, char **argv, char **envp)
}
}
if (uc_close(&handle) == UC_ERR_OK) {
if (uc_close(uc) == UC_ERR_OK) {
printf("ok %d - uc_close complete\n", log_num++);
} else {
printf("not ok %d - uc_close complete\n", log_num++);

View File

@ -72,18 +72,18 @@ static int log_num = 1;
#define CODE_SIZE 0x1000
// callback for tracing instruction
static void hook_code(uch handle, uint64_t addr, uint32_t size, void *user_data)
static void hook_code(ucengine *uc, 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) {
if (uc_mem_read(uc, 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) {
if (uc_mem_read(uc, 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);
@ -97,7 +97,7 @@ static void hook_code(uch handle, uint64_t addr, uint32_t size, void *user_data)
printf("# Received: 0x%x\n", testval);
}
}
if (uc_mem_unmap(handle, 0x200000 + test_num * 0x100000, 0x1000) != UC_ERR_OK) {
if (uc_mem_unmap(uc, 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++);
@ -106,7 +106,7 @@ static void hook_code(uch handle, uint64_t addr, uint32_t size, void *user_data)
break;
case 0xf4: //hlt
printf("# Handling HLT\n");
if (uc_emu_stop(handle) != UC_ERR_OK) {
if (uc_emu_stop(uc) != 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 {
@ -120,14 +120,14 @@ static void hook_code(uch handle, uint64_t addr, uint32_t size, void *user_data)
}
// callback for tracing memory access (READ or WRITE)
static void hook_mem_write(uch handle, uc_mem_type type,
static void hook_mem_write(ucengine *uc, 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);
}
// callback for tracing invalid memory access (READ or WRITE)
static bool hook_mem_invalid(uch handle, uc_mem_type type,
static bool hook_mem_invalid(ucengine *uc, uc_mem_type type,
uint64_t addr, int size, int64_t value, void *user_data)
{
uint32_t testval;
@ -138,13 +138,13 @@ static bool hook_mem_invalid(uch handle, uc_mem_type type,
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) {
if (uc_mem_read(uc, 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) {
if (uc_mem_map(uc, 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++);
@ -155,7 +155,8 @@ static bool hook_mem_invalid(uch handle, uc_mem_type type,
int main(int argc, char **argv, char **envp)
{
uch handle, trace1, trace2;
ucengine *uc;
uc_hook_h trace1, trace2;
uc_err err;
uint32_t addr, testval;
int32_t buf1[1024], buf2[1024], readbuf[1024];
@ -171,7 +172,7 @@ int main(int argc, char **argv, char **envp)
printf("# Memory unmapping test\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &handle);
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
if (err) {
printf("not ok %d - Failed on uc_open() with error returned: %u\n", log_num++, err);
return 1;
@ -179,20 +180,20 @@ int main(int argc, char **argv, char **envp)
printf("ok %d - uc_open() success\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);
uc_mem_map(uc, CODE_SECTION, CODE_SIZE, UC_PROT_READ | UC_PROT_EXEC);
uc_mem_map(uc, 0x200000, 0x1000, UC_PROT_READ | UC_PROT_WRITE);
uc_mem_map(uc, 0x300000, 0x1000, UC_PROT_READ | UC_PROT_WRITE);
uc_mem_map(uc, 0x3ff000, 0x3000, UC_PROT_READ | UC_PROT_WRITE);
// fill in sections that shouldn't get touched
if (uc_mem_write(handle, 0x3ff000, (uint8_t*)buf1, 4096)) {
if (uc_mem_write(uc, 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++);
}
if (uc_mem_write(handle, 0x401000, (uint8_t*)buf2, 4096)) {
if (uc_mem_write(uc, 0x401000, (uint8_t*)buf2, 4096)) {
printf("not ok %d - Failed to write random buffer 2 to memory, quit!\n", log_num++);
return 3;
} else {
@ -200,31 +201,31 @@ int main(int argc, char **argv, char **envp)
}
// write machine code to be emulated to memory
if (uc_mem_write(handle, CODE_SECTION, PROGRAM, sizeof(PROGRAM))) {
if (uc_mem_write(uc, 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_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) {
printf("not ok %d - Failed to install UC_HOOK_CODE handler\n", log_num++);
if (uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) {
printf("not ok %d - Failed to install UC_HOOK_CODE ucr\n", log_num++);
return 5;
} else {
printf("ok %d - UC_HOOK_CODE installed\n", log_num++);
}
// intercept memory write events
if (uc_hook_add(handle, &trace1, UC_HOOK_MEM_WRITE, hook_mem_write, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) {
printf("not ok %d - Failed to install UC_HOOK_MEM_WRITE handler\n", log_num++);
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE, hook_mem_write, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) {
printf("not ok %d - Failed to install UC_HOOK_MEM_WRITE ucr\n", log_num++);
return 6;
} else {
printf("ok %d - UC_HOOK_MEM_WRITE 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++);
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_INVALID, hook_mem_invalid, NULL) != UC_ERR_OK) {
printf("not ok %d - Failed to install UC_HOOK_MEM_INVALID ucr\n", log_num++);
return 7;
} else {
printf("ok %d - UC_HOOK_MEM_INVALID installed\n", log_num++);
@ -232,7 +233,7 @@ int main(int argc, char **argv, char **envp)
// 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);
err = uc_emu_start(uc, 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;
@ -245,7 +246,7 @@ int main(int argc, char **argv, char **envp)
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) {
if (uc_mem_read(uc, 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);
@ -260,7 +261,7 @@ int main(int argc, char **argv, char **envp)
//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)) {
if (uc_mem_read(uc, 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++);
@ -271,7 +272,7 @@ int main(int argc, char **argv, char **envp)
}
}
if (uc_mem_read(handle, 0x401000, (uint8_t*)readbuf, 4096)) {
if (uc_mem_read(uc, 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++);
@ -282,7 +283,7 @@ int main(int argc, char **argv, char **envp)
}
}
if (uc_close(&handle) == UC_ERR_OK) {
if (uc_close(uc) == UC_ERR_OK) {
printf("ok %d - uc_close complete\n", log_num++);
} else {
printf("not ok %d - uc_close complete\n", log_num++);

42
uc.c
View File

@ -31,8 +31,6 @@
#include "qemu/include/hw/boards.h"
static uint8_t *copy_region(struct uc_struct *uc, MemoryRegion *mr);
static bool split_region(struct uc_struct *uc, MemoryRegion *mr, uint64_t address, size_t size, bool do_delete);
UNICORN_EXPORT
unsigned int uc_version(unsigned int *major, unsigned int *minor)
@ -589,11 +587,11 @@ uc_err uc_mem_map(ucengine *uc, uint64_t address, size_t size, uint32_t perms)
// Create a backup copy of the indicated MemoryRegion.
// Generally used in prepartion for splitting a MemoryRegion.
static uint8_t *copy_region(uch handle, MemoryRegion *mr)
static uint8_t *copy_region(struct uc_struct *uc, MemoryRegion *mr)
{
uint8_t *block = (uint8_t *)malloc(int128_get64(mr->size));
if (block != NULL) {
uc_err err = uc_mem_read(handle, mr->addr, block, int128_get64(mr->size));
uc_err err = uc_mem_read(uc, mr->addr, block, int128_get64(mr->size));
if (err != UC_ERR_OK) {
free(block);
block = NULL;
@ -618,7 +616,7 @@ static uint8_t *copy_region(uch handle, MemoryRegion *mr)
*/
// TODO: investigate whether qemu region manipulation functions already offered
// this capability
static bool split_region(uch handle, MemoryRegion *mr, uint64_t address,
static bool split_region(struct uc_struct *uc, MemoryRegion *mr, uint64_t address,
size_t size, bool do_delete)
{
uint8_t *backup;
@ -641,7 +639,7 @@ static bool split_region(uch handle, MemoryRegion *mr, uint64_t address,
// impossible case
return false;
backup = copy_region(handle, mr);
backup = copy_region(uc, mr);
if (backup == NULL)
return false;
@ -651,7 +649,7 @@ static bool split_region(uch handle, MemoryRegion *mr, uint64_t address,
end = mr->end;
// unmap this region first, then do split it later
if (uc_mem_unmap(handle, mr->addr, int128_get64(mr->size)) != UC_ERR_OK)
if (uc_mem_unmap(uc, mr->addr, int128_get64(mr->size)) != UC_ERR_OK)
goto error;
/* overlapping cases
@ -677,23 +675,23 @@ static bool split_region(uch handle, MemoryRegion *mr, uint64_t address,
// allocation just failed so no guarantee that we can recover the original
// allocation at this point
if (l_size > 0) {
if (uc_mem_map(handle, begin, l_size, perms) != UC_ERR_OK)
if (uc_mem_map(uc, begin, l_size, perms) != UC_ERR_OK)
goto error;
if (uc_mem_write(handle, begin, backup, l_size) != UC_ERR_OK)
if (uc_mem_write(uc, begin, backup, l_size) != UC_ERR_OK)
goto error;
}
if (m_size > 0 && !do_delete) {
if (uc_mem_map(handle, address, m_size, perms) != UC_ERR_OK)
if (uc_mem_map(uc, address, m_size, perms) != UC_ERR_OK)
goto error;
if (uc_mem_write(handle, address, backup + l_size, m_size) != UC_ERR_OK)
if (uc_mem_write(uc, address, backup + l_size, m_size) != UC_ERR_OK)
goto error;
}
if (r_size > 0) {
if (uc_mem_map(handle, chunk_end, r_size, perms) != UC_ERR_OK)
if (uc_mem_map(uc, chunk_end, r_size, perms) != UC_ERR_OK)
goto error;
if (uc_mem_write(handle, chunk_end, backup + l_size + m_size, r_size) != UC_ERR_OK)
if (uc_mem_write(uc, chunk_end, backup + l_size + m_size, r_size) != UC_ERR_OK)
goto error;
}
@ -705,17 +703,12 @@ error:
}
UNICORN_EXPORT
uc_err uc_mem_protect(uch handle, uint64_t address, size_t size, uint32_t perms)
uc_err uc_mem_protect(struct uc_struct *uc, uint64_t address, size_t size, uint32_t perms)
{
struct uc_struct* uc = (struct uc_struct *)handle;
MemoryRegion *mr;
uint64_t addr = address;
size_t count, len;
if (handle == 0)
// invalid handle
return UC_ERR_UCH;
if (size == 0)
// trivial case, no change
return UC_ERR_OK;
@ -743,7 +736,7 @@ uc_err uc_mem_protect(uch handle, uint64_t address, size_t size, uint32_t perms)
while(count < size) {
mr = memory_mapping(uc, addr);
len = MIN(size - count, mr->end - addr);
if (!split_region(handle, mr, addr, len, false))
if (!split_region(uc, mr, addr, len, false))
return UC_ERR_NOMEM;
mr = memory_mapping(uc, addr);
@ -757,17 +750,12 @@ uc_err uc_mem_protect(uch handle, uint64_t address, size_t size, uint32_t perms)
}
UNICORN_EXPORT
uc_err uc_mem_unmap(uch handle, uint64_t address, size_t size)
uc_err uc_mem_unmap(struct uc_struct *uc, uint64_t address, size_t size)
{
MemoryRegion *mr;
struct uc_struct* uc = (struct uc_struct *)handle;
uint64_t addr;
size_t count, len;
if (handle == 0)
// invalid handle
return UC_ERR_UCH;
if (size == 0)
// nothing to unmap
return UC_ERR_OK;
@ -791,7 +779,7 @@ uc_err uc_mem_unmap(uch handle, uint64_t address, size_t size)
while(count < size) {
mr = memory_mapping(uc, addr);
len = MIN(size - count, mr->end - addr);
if (!split_region(handle, mr, addr, len, true))
if (!split_region(uc, mr, addr, len, true))
return UC_ERR_NOMEM;
// if we can retrieve the mapping, then no splitting took place
// so unmap here