bring new code and samples up-to-date with API changes
This commit is contained in:
parent
5e9d07a40a
commit
da46071c7d
@ -433,7 +433,7 @@ uc_err uc_mem_map(ucengine *uc, uint64_t address, size_t size, uint32_t perms);
|
|||||||
for detailed error).
|
for detailed error).
|
||||||
*/
|
*/
|
||||||
UNICORN_EXPORT
|
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.
|
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).
|
for detailed error).
|
||||||
*/
|
*/
|
||||||
UNICORN_EXPORT
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -185,7 +185,7 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
|||||||
// Unicorn: callback on fetch from NX
|
// Unicorn: callback on fetch from NX
|
||||||
if (mr != NULL && !(mr->perms & UC_PROT_EXEC)) { //non-executable
|
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)(
|
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)) {
|
uc->hook_callbacks[uc->hook_mem_idx].user_data)) {
|
||||||
env->invalid_error = UC_ERR_OK;
|
env->invalid_error = UC_ERR_OK;
|
||||||
} else {
|
} 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
|
// Unicorn: callback on fetch from NX
|
||||||
if (mr != NULL && !(mr->perms & UC_PROT_EXEC)) { //non-executable
|
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)(
|
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)) {
|
uc->hook_callbacks[uc->hook_mem_idx].user_data)) {
|
||||||
env->invalid_error = UC_ERR_OK;
|
env->invalid_error = UC_ERR_OK;
|
||||||
} else {
|
} else {
|
||||||
|
@ -78,11 +78,11 @@ static int log_num = 1;
|
|||||||
#define CODE_SIZE 0x1000
|
#define CODE_SIZE 0x1000
|
||||||
|
|
||||||
// callback for tracing instruction
|
// 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;
|
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);
|
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) {
|
switch (opcode) {
|
||||||
case 0xf4: //hlt
|
case 0xf4: //hlt
|
||||||
printf("# Handling HLT\n");
|
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);
|
printf("not ok %d - uc_emu_stop fail during hook_code callback, addr: 0x%" PRIx64 "\n", log_num++, addr);
|
||||||
_exit(-1);
|
_exit(-1);
|
||||||
} else {
|
} 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)
|
// 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)
|
uint64_t addr, int size, int64_t value, void *user_data)
|
||||||
{
|
{
|
||||||
printf("# write to memory at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n", addr, size, value);
|
printf("# write to memory at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n", addr, size, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// callback for tracing invalid memory access (READ or WRITE)
|
// 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)
|
uint64_t addr, int size, int64_t value, void *user_data)
|
||||||
{
|
{
|
||||||
switch(type) {
|
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);
|
printf("# Fetch from non-executable memory at 0x%"PRIx64 "\n", addr);
|
||||||
|
|
||||||
//make page executable
|
//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);
|
printf("not ok %d - uc_mem_protect fail for address: 0x%" PRIx64 "\n", log_num++, addr);
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - uc_mem_protect success at 0x%" PRIx64 "\n", log_num++, addr);
|
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:
|
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);
|
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);
|
printf("not ok %d - uc_mem_protect fail during hook_mem_invalid callback, addr: 0x%" PRIx64 "\n", log_num++, addr);
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - uc_mem_protect success\n", log_num++);
|
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)
|
int main(int argc, char **argv, char **envp)
|
||||||
{
|
{
|
||||||
uch handle, trace1, trace2;
|
ucengine *uc;
|
||||||
|
uc_hook_h trace1, trace2;
|
||||||
uc_err err;
|
uc_err err;
|
||||||
uint32_t esp, eip;
|
uint32_t esp, eip;
|
||||||
int32_t buf1[1024], buf2[1024], readbuf[1024];
|
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");
|
printf("# Memory protect test\n");
|
||||||
|
|
||||||
// Initialize emulator in X86-32bit mode
|
// 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) {
|
if (err) {
|
||||||
printf("not ok %d - Failed on uc_open() with error returned: %u\n", log_num++, err);
|
printf("not ok %d - Failed on uc_open() with error returned: %u\n", log_num++, err);
|
||||||
return 1;
|
return 1;
|
||||||
@ -166,15 +167,15 @@ int main(int argc, char **argv, char **envp)
|
|||||||
printf("ok %d - uc_open() success\n", log_num++);
|
printf("ok %d - uc_open() success\n", log_num++);
|
||||||
}
|
}
|
||||||
|
|
||||||
uc_mem_map(handle, 0x100000, 0x1000, UC_PROT_READ | UC_PROT_EXEC);
|
uc_mem_map(uc, 0x100000, 0x1000, UC_PROT_READ | UC_PROT_EXEC);
|
||||||
uc_mem_map(handle, 0x1ff000, 0x2000, UC_PROT_READ | UC_PROT_WRITE);
|
uc_mem_map(uc, 0x1ff000, 0x2000, UC_PROT_READ | UC_PROT_WRITE);
|
||||||
uc_mem_map(handle, 0x300000, 0x2000, UC_PROT_READ);
|
uc_mem_map(uc, 0x300000, 0x2000, UC_PROT_READ);
|
||||||
uc_mem_map(handle, 0xf00000, 0x1000, UC_PROT_READ | UC_PROT_WRITE);
|
uc_mem_map(uc, 0xf00000, 0x1000, UC_PROT_READ | UC_PROT_WRITE);
|
||||||
|
|
||||||
esp = 0xf00000 + 0x1000;
|
esp = 0xf00000 + 0x1000;
|
||||||
|
|
||||||
// Setup stack pointer
|
// 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++);
|
printf("not ok %d - Failed to set esp. quit!\n", log_num++);
|
||||||
return 2;
|
return 2;
|
||||||
} else {
|
} else {
|
||||||
@ -182,14 +183,14 @@ int main(int argc, char **argv, char **envp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// fill in sections that shouldn't get touched
|
// 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++);
|
printf("not ok %d - Failed to write random buffer 1 to memory, quit!\n", log_num++);
|
||||||
return 3;
|
return 3;
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - Random buffer 1 written to memory\n", log_num++);
|
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++);
|
printf("not ok %d - Failed to write random buffer 2 to memory, quit!\n", log_num++);
|
||||||
return 4;
|
return 4;
|
||||||
} else {
|
} else {
|
||||||
@ -197,31 +198,31 @@ int main(int argc, char **argv, char **envp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// write machine code to be emulated to memory
|
// 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++);
|
printf("not ok %d - Failed to write emulation code to memory, quit!\n", log_num++);
|
||||||
return 5;
|
return 5;
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - Program written to memory\n", log_num++);
|
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) {
|
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 handler\n", log_num++);
|
printf("not ok %d - Failed to install UC_HOOK_CODE ucr\n", log_num++);
|
||||||
return 6;
|
return 6;
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - UC_HOOK_CODE installed\n", log_num++);
|
printf("ok %d - UC_HOOK_CODE installed\n", log_num++);
|
||||||
}
|
}
|
||||||
|
|
||||||
// intercept memory write events
|
// 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) {
|
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 handler\n", log_num++);
|
printf("not ok %d - Failed to install UC_HOOK_MEM_WRITE ucr\n", log_num++);
|
||||||
return 7;
|
return 7;
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - UC_HOOK_MEM_WRITE installed\n", log_num++);
|
printf("ok %d - UC_HOOK_MEM_WRITE installed\n", log_num++);
|
||||||
}
|
}
|
||||||
|
|
||||||
// intercept invalid memory events
|
// intercept invalid memory events
|
||||||
if (uc_hook_add(handle, &trace1, UC_HOOK_MEM_INVALID, hook_mem_invalid, NULL) != UC_ERR_OK) {
|
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 handler\n", log_num++);
|
printf("not ok %d - Failed to install UC_HOOK_MEM_INVALID ucr\n", log_num++);
|
||||||
return 8;
|
return 8;
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - UC_HOOK_MEM_INVALID installed\n", log_num++);
|
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
|
// emulate machine code until told to stop by hook_code
|
||||||
printf("# BEGIN execution\n");
|
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) {
|
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));
|
printf("not ok %d - Failure on uc_emu_start() with error %u:%s\n", log_num++, err, uc_strerror(err));
|
||||||
return 9;
|
return 9;
|
||||||
@ -239,7 +240,7 @@ int main(int argc, char **argv, char **envp)
|
|||||||
printf("# END execution\n");
|
printf("# END execution\n");
|
||||||
|
|
||||||
// get ending EIP
|
// 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++);
|
printf("not ok %d - Failed to read eip.\n", log_num++);
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - Ending EIP 0x%x\n", log_num++, eip);
|
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
|
//make sure that random blocks didn't get nuked
|
||||||
// fill in sections that shouldn't get touched
|
// 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++);
|
printf("not ok %d - Failed to read random buffer 1 from memory\n", log_num++);
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - Random buffer 1 read from memory\n", log_num++);
|
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++);
|
printf("not ok %d - Failed to read random buffer 2 from memory\n", log_num++);
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - Random buffer 2 read from memory\n", log_num++);
|
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++);
|
printf("ok %d - uc_close complete\n", log_num++);
|
||||||
} else {
|
} else {
|
||||||
printf("not ok %d - uc_close complete\n", log_num++);
|
printf("not ok %d - uc_close complete\n", log_num++);
|
||||||
|
@ -77,18 +77,18 @@ static int log_num = 1;
|
|||||||
#define CODE_SIZE 0x1000
|
#define CODE_SIZE 0x1000
|
||||||
|
|
||||||
// callback for tracing instruction
|
// 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;
|
uint8_t opcode;
|
||||||
uint32_t testval;
|
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("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);
|
printf("ok %d - uc_mem_read for opcode at address 0x%" PRIx64 "\n", log_num++, addr);
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case 0x90: //nop
|
case 0x90: //nop
|
||||||
printf("# Handling NOP\n");
|
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);
|
printf("not ok %d - uc_mem_read fail for address: 0x%x\n", log_num++, 0x200000 + test_num * 0x100000);
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - good uc_mem_read for address: 0x%x\n", log_num++, 0x200000 + test_num * 0x100000);
|
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);
|
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);
|
printf("not ok %d - uc_mem_protect fail during hook_code callback, addr: 0x%x\n", log_num++, 0x200000 + test_num * 0x100000);
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - uc_mem_protect success\n", log_num++);
|
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;
|
break;
|
||||||
case 0xf4: //hlt
|
case 0xf4: //hlt
|
||||||
printf("# Handling HLT\n");
|
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);
|
printf("not ok %d - uc_emu_stop fail during hook_code callback, addr: 0x%" PRIx64 "\n", log_num++, addr);
|
||||||
_exit(-1);
|
_exit(-1);
|
||||||
} else {
|
} 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)
|
// 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)
|
uint64_t addr, int size, int64_t value, void *user_data)
|
||||||
{
|
{
|
||||||
printf("# write to memory at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n", addr, size, value);
|
printf("# write to memory at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n", addr, size, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// callback for tracing invalid memory access (READ or WRITE)
|
// 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)
|
uint64_t addr, int size, int64_t value, void *user_data)
|
||||||
{
|
{
|
||||||
uint32_t testval;
|
uint32_t testval;
|
||||||
@ -143,13 +143,13 @@ static bool hook_mem_invalid(uch handle, uc_mem_type type,
|
|||||||
case UC_MEM_WRITE_PROT:
|
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);
|
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);
|
printf("not ok %d - uc_mem_read fail for address: 0x%" PRIx64 "\n", log_num++, addr);
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - uc_mem_read success after mem_protect at test %d\n", log_num++, test_num - 1);
|
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);
|
printf("not ok %d - uc_mem_protect fail during hook_mem_invalid callback, addr: 0x%" PRIx64 "\n", log_num++, addr);
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - uc_mem_protect success\n", log_num++);
|
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)
|
int main(int argc, char **argv, char **envp)
|
||||||
{
|
{
|
||||||
uch handle, trace1, trace2;
|
ucengine *uc;
|
||||||
|
uc_hook_h trace1, trace2;
|
||||||
uc_err err;
|
uc_err err;
|
||||||
uint32_t addr, testval;
|
uint32_t addr, testval;
|
||||||
int32_t buf1[1024], buf2[1024], readbuf[1024];
|
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");
|
printf("# Memory protect test\n");
|
||||||
|
|
||||||
// Initialize emulator in X86-32bit mode
|
// 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) {
|
if (err) {
|
||||||
printf("not ok %d - Failed on uc_open() with error returned: %u\n", log_num++, err);
|
printf("not ok %d - Failed on uc_open() with error returned: %u\n", log_num++, err);
|
||||||
return 1;
|
return 1;
|
||||||
@ -184,20 +185,20 @@ int main(int argc, char **argv, char **envp)
|
|||||||
printf("ok %d - uc_open() success\n", log_num++);
|
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(uc, 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(uc, 0x200000, 0x1000, UC_PROT_READ | UC_PROT_WRITE);
|
||||||
uc_mem_map(handle, 0x300000, 0x1000, UC_PROT_READ | UC_PROT_WRITE);
|
uc_mem_map(uc, 0x300000, 0x1000, UC_PROT_READ | UC_PROT_WRITE);
|
||||||
uc_mem_map(handle, 0x3ff000, 0x3000, 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
|
// 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++);
|
printf("not ok %d - Failed to write random buffer 1 to memory, quit!\n", log_num++);
|
||||||
return 2;
|
return 2;
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - Random buffer 1 written to memory\n", log_num++);
|
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++);
|
printf("not ok %d - Failed to write random buffer 2 to memory, quit!\n", log_num++);
|
||||||
return 3;
|
return 3;
|
||||||
} else {
|
} else {
|
||||||
@ -205,31 +206,31 @@ int main(int argc, char **argv, char **envp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// write machine code to be emulated to memory
|
// 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++);
|
printf("not ok %d - Failed to write emulation code to memory, quit!\n", log_num++);
|
||||||
return 4;
|
return 4;
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - Program written to memory\n", log_num++);
|
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) {
|
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 handler\n", log_num++);
|
printf("not ok %d - Failed to install UC_HOOK_CODE ucr\n", log_num++);
|
||||||
return 5;
|
return 5;
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - UC_HOOK_CODE installed\n", log_num++);
|
printf("ok %d - UC_HOOK_CODE installed\n", log_num++);
|
||||||
}
|
}
|
||||||
|
|
||||||
// intercept memory write events
|
// 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) {
|
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 handler\n", log_num++);
|
printf("not ok %d - Failed to install UC_HOOK_MEM_WRITE ucr\n", log_num++);
|
||||||
return 6;
|
return 6;
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - UC_HOOK_MEM_WRITE installed\n", log_num++);
|
printf("ok %d - UC_HOOK_MEM_WRITE installed\n", log_num++);
|
||||||
}
|
}
|
||||||
|
|
||||||
// intercept invalid memory events
|
// intercept invalid memory events
|
||||||
if (uc_hook_add(handle, &trace1, UC_HOOK_MEM_INVALID, hook_mem_invalid, NULL) != UC_ERR_OK) {
|
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 handler\n", log_num++);
|
printf("not ok %d - Failed to install UC_HOOK_MEM_INVALID ucr\n", log_num++);
|
||||||
return 7;
|
return 7;
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - UC_HOOK_MEM_INVALID installed\n", log_num++);
|
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
|
// emulate machine code until told to stop by hook_code
|
||||||
printf("# BEGIN execution\n");
|
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) {
|
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));
|
printf("not ok %d - Failure on uc_emu_start() with error %u:%s\n", log_num++, err, uc_strerror(err));
|
||||||
return 8;
|
return 8;
|
||||||
@ -250,7 +251,7 @@ int main(int argc, char **argv, char **envp)
|
|||||||
testval = 0x42424242;
|
testval = 0x42424242;
|
||||||
for (addr = 0x200000; addr <= 0x400000; addr += 0x100000) {
|
for (addr = 0x200000; addr <= 0x400000; addr += 0x100000) {
|
||||||
uint32_t val;
|
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);
|
printf("not ok %d - Failed uc_mem_read for address 0x%x\n", log_num++, addr);
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - Good uc_mem_read from 0x%x\n", log_num++, addr);
|
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
|
//make sure that random blocks didn't get nuked
|
||||||
// fill in sections that shouldn't get touched
|
// 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++);
|
printf("not ok %d - Failed to read random buffer 1 from memory\n", log_num++);
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - Random buffer 1 read from memory\n", log_num++);
|
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++);
|
printf("not ok %d - Failed to read random buffer 2 from memory\n", log_num++);
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - Random buffer 2 read from memory\n", log_num++);
|
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++);
|
printf("ok %d - uc_close complete\n", log_num++);
|
||||||
} else {
|
} else {
|
||||||
printf("not ok %d - uc_close complete\n", log_num++);
|
printf("not ok %d - uc_close complete\n", log_num++);
|
||||||
|
@ -72,18 +72,18 @@ static int log_num = 1;
|
|||||||
#define CODE_SIZE 0x1000
|
#define CODE_SIZE 0x1000
|
||||||
|
|
||||||
// callback for tracing instruction
|
// 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;
|
uint8_t opcode;
|
||||||
uint32_t testval;
|
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("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);
|
printf("ok %d - uc_mem_read for opcode at address 0x%" PRIx64 "\n", log_num++, addr);
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case 0x90: //nop
|
case 0x90: //nop
|
||||||
printf("# Handling NOP\n");
|
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);
|
printf("not ok %d - uc_mem_read fail for address: 0x%x\n", log_num++, 0x200000 + test_num * 0x100000);
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - good uc_mem_read for address: 0x%x\n", log_num++, 0x200000 + test_num * 0x100000);
|
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);
|
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);
|
printf("not ok %d - uc_mem_unmap fail during hook_code callback, addr: 0x%x\n", log_num++, 0x200000 + test_num * 0x100000);
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - uc_mem_unmap success\n", log_num++);
|
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;
|
break;
|
||||||
case 0xf4: //hlt
|
case 0xf4: //hlt
|
||||||
printf("# Handling HLT\n");
|
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);
|
printf("not ok %d - uc_emu_stop fail during hook_code callback, addr: 0x%" PRIx64 "\n", log_num++, addr);
|
||||||
_exit(-1);
|
_exit(-1);
|
||||||
} else {
|
} 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)
|
// 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)
|
uint64_t addr, int size, int64_t value, void *user_data)
|
||||||
{
|
{
|
||||||
printf("# write to memory at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n", addr, size, value);
|
printf("# write to memory at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n", addr, size, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// callback for tracing invalid memory access (READ or WRITE)
|
// 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)
|
uint64_t addr, int size, int64_t value, void *user_data)
|
||||||
{
|
{
|
||||||
uint32_t testval;
|
uint32_t testval;
|
||||||
@ -138,13 +138,13 @@ static bool hook_mem_invalid(uch handle, uc_mem_type type,
|
|||||||
case UC_MEM_WRITE:
|
case UC_MEM_WRITE:
|
||||||
printf("# write to invalid memory at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n", addr, size, value);
|
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);
|
printf("ok %d - uc_mem_read fail for address: 0x%" PRIx64 "\n", log_num++, addr);
|
||||||
} else {
|
} else {
|
||||||
printf("not ok %d - uc_mem_read success after unmap at test %d\n", log_num++, test_num - 1);
|
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);
|
printf("not ok %d - uc_mem_map fail during hook_mem_invalid callback, addr: 0x%" PRIx64 "\n", log_num++, addr);
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - uc_mem_map success\n", log_num++);
|
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)
|
int main(int argc, char **argv, char **envp)
|
||||||
{
|
{
|
||||||
uch handle, trace1, trace2;
|
ucengine *uc;
|
||||||
|
uc_hook_h trace1, trace2;
|
||||||
uc_err err;
|
uc_err err;
|
||||||
uint32_t addr, testval;
|
uint32_t addr, testval;
|
||||||
int32_t buf1[1024], buf2[1024], readbuf[1024];
|
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");
|
printf("# Memory unmapping test\n");
|
||||||
|
|
||||||
// Initialize emulator in X86-32bit mode
|
// 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) {
|
if (err) {
|
||||||
printf("not ok %d - Failed on uc_open() with error returned: %u\n", log_num++, err);
|
printf("not ok %d - Failed on uc_open() with error returned: %u\n", log_num++, err);
|
||||||
return 1;
|
return 1;
|
||||||
@ -179,20 +180,20 @@ int main(int argc, char **argv, char **envp)
|
|||||||
printf("ok %d - uc_open() success\n", log_num++);
|
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(uc, 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(uc, 0x200000, 0x1000, UC_PROT_READ | UC_PROT_WRITE);
|
||||||
uc_mem_map(handle, 0x300000, 0x1000, UC_PROT_READ | UC_PROT_WRITE);
|
uc_mem_map(uc, 0x300000, 0x1000, UC_PROT_READ | UC_PROT_WRITE);
|
||||||
uc_mem_map(handle, 0x3ff000, 0x3000, 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
|
// 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++);
|
printf("not ok %d - Failed to write random buffer 1 to memory, quit!\n", log_num++);
|
||||||
return 2;
|
return 2;
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - Random buffer 1 written to memory\n", log_num++);
|
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++);
|
printf("not ok %d - Failed to write random buffer 2 to memory, quit!\n", log_num++);
|
||||||
return 3;
|
return 3;
|
||||||
} else {
|
} else {
|
||||||
@ -200,31 +201,31 @@ int main(int argc, char **argv, char **envp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// write machine code to be emulated to memory
|
// 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++);
|
printf("not ok %d - Failed to write emulation code to memory, quit!\n", log_num++);
|
||||||
return 4;
|
return 4;
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - Program written to memory\n", log_num++);
|
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) {
|
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 handler\n", log_num++);
|
printf("not ok %d - Failed to install UC_HOOK_CODE ucr\n", log_num++);
|
||||||
return 5;
|
return 5;
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - UC_HOOK_CODE installed\n", log_num++);
|
printf("ok %d - UC_HOOK_CODE installed\n", log_num++);
|
||||||
}
|
}
|
||||||
|
|
||||||
// intercept memory write events
|
// 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) {
|
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 handler\n", log_num++);
|
printf("not ok %d - Failed to install UC_HOOK_MEM_WRITE ucr\n", log_num++);
|
||||||
return 6;
|
return 6;
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - UC_HOOK_MEM_WRITE installed\n", log_num++);
|
printf("ok %d - UC_HOOK_MEM_WRITE installed\n", log_num++);
|
||||||
}
|
}
|
||||||
|
|
||||||
// intercept invalid memory events
|
// intercept invalid memory events
|
||||||
if (uc_hook_add(handle, &trace1, UC_HOOK_MEM_INVALID, hook_mem_invalid, NULL) != UC_ERR_OK) {
|
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 handler\n", log_num++);
|
printf("not ok %d - Failed to install UC_HOOK_MEM_INVALID ucr\n", log_num++);
|
||||||
return 7;
|
return 7;
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - UC_HOOK_MEM_INVALID installed\n", log_num++);
|
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
|
// emulate machine code until told to stop by hook_code
|
||||||
printf("# BEGIN execution\n");
|
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) {
|
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));
|
printf("not ok %d - Failure on uc_emu_start() with error %u:%s\n", log_num++, err, uc_strerror(err));
|
||||||
return 8;
|
return 8;
|
||||||
@ -245,7 +246,7 @@ int main(int argc, char **argv, char **envp)
|
|||||||
testval = 0x42424242;
|
testval = 0x42424242;
|
||||||
for (addr = 0x200000; addr <= 0x400000; addr += 0x100000) {
|
for (addr = 0x200000; addr <= 0x400000; addr += 0x100000) {
|
||||||
uint32_t val;
|
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);
|
printf("not ok %d - Failed uc_mem_read for address 0x%x\n", log_num++, addr);
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - Good uc_mem_read from 0x%x\n", log_num++, addr);
|
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
|
//make sure that random blocks didn't get nuked
|
||||||
// fill in sections that shouldn't get touched
|
// 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++);
|
printf("not ok %d - Failed to read random buffer 1 from memory\n", log_num++);
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - Random buffer 1 read from memory\n", log_num++);
|
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++);
|
printf("not ok %d - Failed to read random buffer 2 from memory\n", log_num++);
|
||||||
} else {
|
} else {
|
||||||
printf("ok %d - Random buffer 2 read from memory\n", log_num++);
|
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++);
|
printf("ok %d - uc_close complete\n", log_num++);
|
||||||
} else {
|
} else {
|
||||||
printf("not ok %d - uc_close complete\n", log_num++);
|
printf("not ok %d - uc_close complete\n", log_num++);
|
||||||
|
42
uc.c
42
uc.c
@ -31,8 +31,6 @@
|
|||||||
|
|
||||||
#include "qemu/include/hw/boards.h"
|
#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
|
UNICORN_EXPORT
|
||||||
unsigned int uc_version(unsigned int *major, unsigned int *minor)
|
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.
|
// Create a backup copy of the indicated MemoryRegion.
|
||||||
// Generally used in prepartion for splitting a 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));
|
uint8_t *block = (uint8_t *)malloc(int128_get64(mr->size));
|
||||||
if (block != NULL) {
|
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) {
|
if (err != UC_ERR_OK) {
|
||||||
free(block);
|
free(block);
|
||||||
block = NULL;
|
block = NULL;
|
||||||
@ -618,7 +616,7 @@ static uint8_t *copy_region(uch handle, MemoryRegion *mr)
|
|||||||
*/
|
*/
|
||||||
// TODO: investigate whether qemu region manipulation functions already offered
|
// TODO: investigate whether qemu region manipulation functions already offered
|
||||||
// this capability
|
// 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)
|
size_t size, bool do_delete)
|
||||||
{
|
{
|
||||||
uint8_t *backup;
|
uint8_t *backup;
|
||||||
@ -641,7 +639,7 @@ static bool split_region(uch handle, MemoryRegion *mr, uint64_t address,
|
|||||||
// impossible case
|
// impossible case
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
backup = copy_region(handle, mr);
|
backup = copy_region(uc, mr);
|
||||||
if (backup == NULL)
|
if (backup == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -651,7 +649,7 @@ static bool split_region(uch handle, MemoryRegion *mr, uint64_t address,
|
|||||||
end = mr->end;
|
end = mr->end;
|
||||||
|
|
||||||
// unmap this region first, then do split it later
|
// 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;
|
goto error;
|
||||||
|
|
||||||
/* overlapping cases
|
/* 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 just failed so no guarantee that we can recover the original
|
||||||
// allocation at this point
|
// allocation at this point
|
||||||
if (l_size > 0) {
|
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;
|
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;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_size > 0 && !do_delete) {
|
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;
|
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;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r_size > 0) {
|
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;
|
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;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -705,17 +703,12 @@ error:
|
|||||||
}
|
}
|
||||||
|
|
||||||
UNICORN_EXPORT
|
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;
|
MemoryRegion *mr;
|
||||||
uint64_t addr = address;
|
uint64_t addr = address;
|
||||||
size_t count, len;
|
size_t count, len;
|
||||||
|
|
||||||
if (handle == 0)
|
|
||||||
// invalid handle
|
|
||||||
return UC_ERR_UCH;
|
|
||||||
|
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
// trivial case, no change
|
// trivial case, no change
|
||||||
return UC_ERR_OK;
|
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) {
|
while(count < size) {
|
||||||
mr = memory_mapping(uc, addr);
|
mr = memory_mapping(uc, addr);
|
||||||
len = MIN(size - count, mr->end - 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;
|
return UC_ERR_NOMEM;
|
||||||
|
|
||||||
mr = memory_mapping(uc, addr);
|
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
|
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;
|
MemoryRegion *mr;
|
||||||
struct uc_struct* uc = (struct uc_struct *)handle;
|
|
||||||
uint64_t addr;
|
uint64_t addr;
|
||||||
size_t count, len;
|
size_t count, len;
|
||||||
|
|
||||||
if (handle == 0)
|
|
||||||
// invalid handle
|
|
||||||
return UC_ERR_UCH;
|
|
||||||
|
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
// nothing to unmap
|
// nothing to unmap
|
||||||
return UC_ERR_OK;
|
return UC_ERR_OK;
|
||||||
@ -791,7 +779,7 @@ uc_err uc_mem_unmap(uch handle, uint64_t address, size_t size)
|
|||||||
while(count < size) {
|
while(count < size) {
|
||||||
mr = memory_mapping(uc, addr);
|
mr = memory_mapping(uc, addr);
|
||||||
len = MIN(size - count, mr->end - 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;
|
return UC_ERR_NOMEM;
|
||||||
// if we can retrieve the mapping, then no splitting took place
|
// if we can retrieve the mapping, then no splitting took place
|
||||||
// so unmap here
|
// so unmap here
|
||||||
|
Loading…
Reference in New Issue
Block a user