update samples to conform to uc API changes

This commit is contained in:
Jonathon Reinhart 2015-09-02 21:25:59 -04:00
parent bd0a6921cc
commit 0feab69a61
5 changed files with 88 additions and 85 deletions

View File

@ -8,17 +8,17 @@
int main() int main()
{ {
uch uh; struct uc_struct *uc;
uint8_t *buf, *buf2; uint8_t *buf, *buf2;
int i; int i;
uc_err err; uc_err err;
err = uc_open (UC_ARCH_X86, UC_MODE_64, &uh); err = uc_open (UC_ARCH_X86, UC_MODE_64, &uc);
if (err) { if (err) {
printf ("uc_open %d\n", err); printf ("uc_open %d\n", err);
return 1; return 1;
} }
err = uc_mem_map (uh, ADDR, SIZE, UC_PROT_ALL); err = uc_mem_map (uc, ADDR, SIZE, UC_PROT_ALL);
if (err) { if (err) {
printf ("uc_mem_map %d\n", err); printf ("uc_mem_map %d\n", err);
return 1; return 1;
@ -29,12 +29,12 @@ int main()
buf[i] = i & 0xff; buf[i] = i & 0xff;
} }
/* crash here */ /* crash here */
err = uc_mem_write (uh, ADDR, buf, SIZE+OVERFLOW); err = uc_mem_write (uc, ADDR, buf, SIZE+OVERFLOW);
if (err) { if (err) {
printf ("uc_mem_map %d\n", err); printf ("uc_mem_map %d\n", err);
return 1; return 1;
} }
err = uc_mem_read (uh, ADDR+10, buf2, 4); err = uc_mem_read (uc, ADDR+10, buf2, 4);
if (err) { if (err) {
printf ("uc_mem_map %d\n", err); printf ("uc_mem_map %d\n", err);
return 1; return 1;

View File

@ -36,7 +36,7 @@ bits 32
*/ */
// callback for tracing memory access (READ or WRITE) // callback for tracing memory access (READ or WRITE)
static bool hook_mem_invalid(uch handle, uc_mem_type type, static bool hook_mem_invalid(struct uc_struct *uc, uc_mem_type type,
uint64_t address, int size, int64_t value, void *user_data) uint64_t address, int size, int64_t value, void *user_data)
{ {
@ -54,42 +54,43 @@ 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; struct uc_struct *uc;
uc_hook_h trace1, trace2;
uc_err err; uc_err err;
uint32_t eax, ebx; uint32_t eax, ebx;
printf("Memory protections test\n"); printf("Memory protections 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("Failed on uc_open() with error returned: %u\n", err); printf("Failed on uc_open() with error returned: %u\n", err);
return 1; return 1;
} }
uc_mem_map(handle, 0x100000, 0x1000, UC_PROT_READ); uc_mem_map(uc, 0x100000, 0x1000, UC_PROT_READ);
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, 0x400000, 0x1000, UC_PROT_WRITE); uc_mem_map(uc, 0x400000, 0x1000, UC_PROT_WRITE);
// 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("Failed to write emulation code to memory, quit!\n"); printf("Failed to write emulation code to memory, quit!\n");
return 2; return 2;
} else { } else {
printf("Allowed to write to read only memory via uc_mem_write\n"); printf("Allowed to write to read only memory via uc_mem_write\n");
} }
uc_mem_write(handle, 0x300000, (const uint8_t*)"\x41\x41\x41\x41", 4); uc_mem_write(uc, 0x300000, (const uint8_t*)"\x41\x41\x41\x41", 4);
uc_mem_write(handle, 0x400000, (const uint8_t*)"\x42\x42\x42\x42", 4); uc_mem_write(uc, 0x400000, (const uint8_t*)"\x42\x42\x42\x42", 4);
//uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)0x400000, (uint64_t)0x400fff); //uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)0x400000, (uint64_t)0x400fff);
// intercept invalid memory events // intercept invalid memory events
uc_hook_add(handle, &trace1, UC_HOOK_MEM_INVALID, hook_mem_invalid, NULL); uc_hook_add(uc, &trace1, UC_HOOK_MEM_INVALID, hook_mem_invalid, NULL);
// emulate machine code in infinite time // emulate machine code in infinite time
printf("BEGIN execution\n"); printf("BEGIN execution\n");
err = uc_emu_start(handle, 0x100000, 0x100000 + sizeof(PROGRAM), 0, 2); err = uc_emu_start(uc, 0x100000, 0x100000 + sizeof(PROGRAM), 0, 2);
if (err) { if (err) {
printf("Expected failure on uc_emu_start() with error returned %u: %s\n", printf("Expected failure on uc_emu_start() with error returned %u: %s\n",
err, uc_strerror(err)); err, uc_strerror(err));
@ -98,12 +99,12 @@ int main(int argc, char **argv, char **envp)
} }
printf("END execution\n"); printf("END execution\n");
uc_reg_read(handle, UC_X86_REG_EAX, &eax); uc_reg_read(uc, UC_X86_REG_EAX, &eax);
printf("Final eax = 0x%x\n", eax); printf("Final eax = 0x%x\n", eax);
uc_reg_read(handle, UC_X86_REG_EBX, &ebx); uc_reg_read(uc, UC_X86_REG_EBX, &ebx);
printf("Final ebx = 0x%x\n", ebx); printf("Final ebx = 0x%x\n", ebx);
uc_close(&handle); uc_close(uc);
return 0; return 0;
} }

View File

@ -50,17 +50,17 @@ hlt
static int log_num = 1; static int log_num = 1;
// 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(struct uc_struct *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);
_exit(-1); _exit(-1);
} }
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);
} }
@ -74,7 +74,7 @@ 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(struct uc_struct *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);
@ -89,7 +89,8 @@ static void hook_mem_write(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; struct uc_struct *uc;
uc_hook_h trace1, trace2;
uc_err err; uc_err err;
uint8_t buf1[100], readbuf[100]; uint8_t buf1[100], readbuf[100];
@ -98,7 +99,7 @@ int main(int argc, char **argv, char **envp)
memset(buf1, 'A', 20); memset(buf1, 'A', 20);
// 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;
@ -107,11 +108,11 @@ 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_mem_map(uc, 0x100000, 0x1000, UC_PROT_READ);
uc_mem_map(handle, 0x200000, 0x2000, UC_PROT_READ | UC_PROT_WRITE); uc_mem_map(uc, 0x200000, 0x2000, UC_PROT_READ | UC_PROT_WRITE);
// fill in the data that we want to copy // fill in the data that we want to copy
if (uc_mem_write(handle, 0x200000, (uint8_t*)buf1, 20)) { if (uc_mem_write(uc, 0x200000, (uint8_t*)buf1, 20)) {
printf("not ok %d - Failed to write read buffer to memory, quit!\n", log_num++); printf("not ok %d - Failed to write read buffer to memory, quit!\n", log_num++);
return 2; return 2;
} }
@ -120,7 +121,7 @@ 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 4; return 4;
} }
@ -128,7 +129,7 @@ int main(int argc, char **argv, char **envp)
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 handler\n", log_num++);
return 5; return 5;
} }
@ -137,7 +138,7 @@ int main(int argc, char **argv, char **envp)
} }
// intercept memory write events only, NOT read events // intercept memory write events only, NOT read 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 handler\n", log_num++);
return 6; return 6;
} }
@ -147,7 +148,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, 0x101000, 0, 0); err = uc_emu_start(uc, 0x100000, 0x101000, 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;
@ -159,7 +160,7 @@ int main(int argc, char **argv, char **envp)
//make sure that data got copied //make sure that data got copied
// fill in sections that shouldn't get touched // fill in sections that shouldn't get touched
if (uc_mem_read(handle, 0x201000, (uint8_t*)readbuf, 20)) { if (uc_mem_read(uc, 0x201000, (uint8_t*)readbuf, 20)) {
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 {
@ -172,7 +173,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 {

View File

@ -46,22 +46,22 @@ bottom:
*/ */
// callback for tracing instruction // callback for tracing instruction
static void hook_code(uch handle, uint64_t address, uint32_t size, void *user_data) static void hook_code(struct uc_struct *uc, uint64_t address, uint32_t size, void *user_data)
{ {
uint32_t esp; uint32_t esp;
printf(">>> Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size); printf(">>> Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size);
uc_reg_read(handle, UC_X86_REG_ESP, &esp); uc_reg_read(uc, UC_X86_REG_ESP, &esp);
printf(">>> --- ESP is 0x%x\n", esp); printf(">>> --- ESP is 0x%x\n", esp);
} }
// callback for tracing memory access (READ or WRITE) // callback for tracing memory access (READ or WRITE)
static bool hook_mem_invalid(uch handle, uc_mem_type type, static bool hook_mem_invalid(struct uc_struct *uc, uc_mem_type type,
uint64_t address, int size, int64_t value, void *user_data) uint64_t address, int size, int64_t value, void *user_data)
{ {
uint32_t esp; uint32_t esp;
uc_reg_read(handle, UC_X86_REG_ESP, &esp); uc_reg_read(uc, UC_X86_REG_ESP, &esp);
switch(type) { switch(type) {
default: default:
@ -74,7 +74,7 @@ static bool hook_mem_invalid(uch handle, uc_mem_type type,
upper = (esp + 0xfff) & ~0xfff; upper = (esp + 0xfff) & ~0xfff;
printf(">>> Stack appears to be missing at 0x%"PRIx64 ", allocating now\n", address); printf(">>> Stack appears to be missing at 0x%"PRIx64 ", allocating now\n", address);
// map this memory in with 2MB in size // map this memory in with 2MB in size
uc_mem_map(handle, upper - 0x8000, 0x8000, UC_PROT_READ | UC_PROT_WRITE); uc_mem_map(uc, upper - 0x8000, 0x8000, UC_PROT_READ | UC_PROT_WRITE);
// return true to indicate we want to continue // return true to indicate we want to continue
return true; return true;
} }
@ -94,7 +94,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; struct uc_struct *uc;
uc_hook_h trace1, trace2;
uc_err err; uc_err err;
uint8_t bytes[8]; uint8_t bytes[8];
uint32_t esp; uint32_t esp;
@ -108,44 +109,44 @@ int main(int argc, char **argv, char **envp)
printf("Memory mapping test\n"); printf("Memory mapping 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("Failed on uc_open() with error returned: %u\n", err); printf("Failed on uc_open() with error returned: %u\n", err);
return 1; return 1;
} }
uc_mem_map(handle, 0x100000, 0x1000, UC_PROT_ALL); uc_mem_map(uc, 0x100000, 0x1000, UC_PROT_ALL);
uc_mem_map(handle, 0x200000, 0x2000, UC_PROT_ALL); uc_mem_map(uc, 0x200000, 0x2000, UC_PROT_ALL);
uc_mem_map(handle, 0x300000, 0x3000, UC_PROT_ALL); uc_mem_map(uc, 0x300000, 0x3000, UC_PROT_ALL);
uc_mem_map(handle, 0x400000, 0x4000, UC_PROT_READ); uc_mem_map(uc, 0x400000, 0x4000, UC_PROT_READ);
if (map_stack) { if (map_stack) {
printf("Pre-mapping stack\n"); printf("Pre-mapping stack\n");
uc_mem_map(handle, STACK, STACK_SIZE, UC_PROT_READ | UC_PROT_WRITE); uc_mem_map(uc, STACK, STACK_SIZE, UC_PROT_READ | UC_PROT_WRITE);
} else { } else {
printf("Mapping stack on first invalid memory access\n"); printf("Mapping stack on first invalid memory access\n");
} }
esp = STACK + STACK_SIZE; esp = STACK + STACK_SIZE;
uc_reg_write(handle, UC_X86_REG_ESP, &esp); uc_reg_write(uc, UC_X86_REG_ESP, &esp);
// write machine code to be emulated to memory // write machine code to be emulated to memory
if (uc_mem_write(handle, 0x400000, PROGRAM, sizeof(PROGRAM))) { if (uc_mem_write(uc, 0x400000, PROGRAM, sizeof(PROGRAM))) {
printf("Failed to write emulation code to memory, quit!\n"); printf("Failed to write emulation code to memory, quit!\n");
return 2; return 2;
} else { } else {
printf("Allowed to write to read only memory via uc_mem_write\n"); printf("Allowed to write to read only memory via uc_mem_write\n");
} }
//uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)0x400000, (uint64_t)0x400fff); //uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)0x400000, (uint64_t)0x400fff);
// intercept invalid memory events // intercept invalid memory events
uc_hook_add(handle, &trace1, UC_HOOK_MEM_INVALID, hook_mem_invalid, NULL); uc_hook_add(uc, &trace1, UC_HOOK_MEM_INVALID, hook_mem_invalid, NULL);
// emulate machine code in infinite time // emulate machine code in infinite time
printf("BEGIN execution - 1\n"); printf("BEGIN execution - 1\n");
err = uc_emu_start(handle, 0x400000, 0x400000 + sizeof(PROGRAM), 0, 10); err = uc_emu_start(uc, 0x400000, 0x400000 + sizeof(PROGRAM), 0, 10);
if (err) { if (err) {
printf("Expected failue on uc_emu_start() with error returned %u: %s\n", printf("Expected failue on uc_emu_start() with error returned %u: %s\n",
err, uc_strerror(err)); err, uc_strerror(err));
@ -157,8 +158,8 @@ int main(int argc, char **argv, char **envp)
// emulate machine code in infinite time // emulate machine code in infinite time
printf("BEGIN execution - 2\n"); printf("BEGIN execution - 2\n");
uint32_t eax = 0x40002C; uint32_t eax = 0x40002C;
uc_reg_write(handle, UC_X86_REG_EAX, &eax); uc_reg_write(uc, UC_X86_REG_EAX, &eax);
err = uc_emu_start(handle, 0x400015, 0x400000 + sizeof(PROGRAM), 0, 2); err = uc_emu_start(uc, 0x400015, 0x400000 + sizeof(PROGRAM), 0, 2);
if (err) { if (err) {
printf("Expected failure on uc_emu_start() with error returned %u: %s\n", printf("Expected failure on uc_emu_start() with error returned %u: %s\n",
err, uc_strerror(err)); err, uc_strerror(err));
@ -168,7 +169,7 @@ int main(int argc, char **argv, char **envp)
printf("END execution - 2\n"); printf("END execution - 2\n");
printf("Verifying content at 0x400025 is unchanged\n"); printf("Verifying content at 0x400025 is unchanged\n");
if (!uc_mem_read(handle, 0x400025, bytes, 4)) { if (!uc_mem_read(uc, 0x400025, bytes, 4)) {
printf(">>> Read 4 bytes from [0x%x] = 0x%x\n", (uint32_t)0x400025, *(uint32_t*) bytes); printf(">>> Read 4 bytes from [0x%x] = 0x%x\n", (uint32_t)0x400025, *(uint32_t*) bytes);
if (0x41414141 != *(uint32_t*) bytes) { if (0x41414141 != *(uint32_t*) bytes) {
printf("ERROR content in read only memory changed\n"); printf("ERROR content in read only memory changed\n");
@ -181,7 +182,7 @@ int main(int argc, char **argv, char **envp)
} }
printf("Verifying content at 0x40002C is unchanged\n"); printf("Verifying content at 0x40002C is unchanged\n");
if (!uc_mem_read(handle, 0x40002C, bytes, 4)) { if (!uc_mem_read(uc, 0x40002C, bytes, 4)) {
printf(">>> Read 4 bytes from [0x%x] = 0x%x\n", (uint32_t)0x40002C, *(uint32_t*) bytes); printf(">>> Read 4 bytes from [0x%x] = 0x%x\n", (uint32_t)0x40002C, *(uint32_t*) bytes);
if (0x42424242 != *(uint32_t*) bytes) { if (0x42424242 != *(uint32_t*) bytes) {
printf("ERROR content in read only memory changed\n"); printf("ERROR content in read only memory changed\n");
@ -194,14 +195,14 @@ int main(int argc, char **argv, char **envp)
} }
printf("Verifying content at bottom of stack is readable and correct\n"); printf("Verifying content at bottom of stack is readable and correct\n");
if (!uc_mem_read(handle, esp - 4, bytes, 4)) { if (!uc_mem_read(uc, esp - 4, bytes, 4)) {
printf(">>> Read 4 bytes from [0x%x] = 0x%x\n", (uint32_t)(esp - 4), *(uint32_t*) bytes); printf(">>> Read 4 bytes from [0x%x] = 0x%x\n", (uint32_t)(esp - 4), *(uint32_t*) bytes);
} else { } else {
printf(">>> Failed to read 4 bytes from [0x%x]\n", (uint32_t)(esp - 4)); printf(">>> Failed to read 4 bytes from [0x%x]\n", (uint32_t)(esp - 4));
return 4; return 4;
} }
uc_close(&handle); uc_close(uc);
return 0; return 0;
} }

View File

@ -24,21 +24,21 @@ https://github.com/unicorn-engine/unicorn/issues/78
// number of seconds to wait before timeout // number of seconds to wait before timeout
#define TIMEOUT 5 #define TIMEOUT 5
static void hook_block(uch handle, uint64_t address, uint32_t size, void *user_data) static void hook_block(struct uc_struct *uc, uint64_t address, uint32_t size, void *user_data)
{ {
printf(">>> Tracing basic block at 0x%"PRIx64 ", block size = 0x%x\n", address, size); printf(">>> Tracing basic block at 0x%"PRIx64 ", block size = 0x%x\n", address, size);
} }
static void hook_code(uch handle, uint64_t address, uint32_t size, void *user_data) static void hook_code(struct uc_struct *uc, uint64_t address, uint32_t size, void *user_data)
{ {
printf(">>> Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size); printf(">>> Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size);
} }
static void test_arm(void) static void test_arm(void)
{ {
uch handle; struct uc_struct *uc;
uc_err err; uc_err err;
uch trace1, trace2; uc_hook_h trace1, trace2;
int r0 = 0x1234; // R0 register int r0 = 0x1234; // R0 register
int r2 = 0x6789; // R1 register int r2 = 0x6789; // R1 register
@ -48,7 +48,7 @@ static void test_arm(void)
printf("Emulate ARM code\n"); printf("Emulate ARM code\n");
// Initialize emulator in ARM mode // Initialize emulator in ARM mode
err = uc_open(UC_ARCH_ARM, UC_MODE_ARM, &handle); err = uc_open(UC_ARCH_ARM, UC_MODE_ARM, &uc);
if (err) { if (err) {
printf("Failed on uc_open() with error returned: %u (%s)\n", printf("Failed on uc_open() with error returned: %u (%s)\n",
err, uc_strerror(err)); err, uc_strerror(err));
@ -56,25 +56,25 @@ static void test_arm(void)
} }
// map 2MB memory for this emulation // map 2MB memory for this emulation
uc_mem_map(handle, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory // write machine code to be emulated to memory
uc_mem_write(handle, ADDRESS, (uint8_t *)ARM_CODE, sizeof(ARM_CODE) - 1); uc_mem_write(uc, ADDRESS, (uint8_t *)ARM_CODE, sizeof(ARM_CODE) - 1);
// initialize machine registers // initialize machine registers
uc_reg_write(handle, UC_ARM_REG_R0, &r0); uc_reg_write(uc, UC_ARM_REG_R0, &r0);
uc_reg_write(handle, UC_ARM_REG_R2, &r2); uc_reg_write(uc, UC_ARM_REG_R2, &r2);
uc_reg_write(handle, UC_ARM_REG_R3, &r3); uc_reg_write(uc, UC_ARM_REG_R3, &r3);
// tracing all basic blocks with customized callback // tracing all basic blocks with customized callback
uc_hook_add(handle, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0); 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 // tracing one instruction at ADDRESS with customized callback
uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS); 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 // emulate machine code in infinite time (last param = 0), or when
// finishing all the code. // finishing all the code.
err = uc_emu_start(handle, ADDRESS, ADDRESS + sizeof(ARM_CODE) -1, UC_SECOND_SCALE * TIMEOUT, 0); err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(ARM_CODE) -1, UC_SECOND_SCALE * TIMEOUT, 0);
if (err) { if (err) {
printf("Failed on uc_emu_start() with error returned: %u\n", err); printf("Failed on uc_emu_start() with error returned: %u\n", err);
} }
@ -82,26 +82,26 @@ static void test_arm(void)
// now print out some registers // now print out some registers
printf(">>> Emulation done. Below is the CPU context\n"); printf(">>> Emulation done. Below is the CPU context\n");
uc_reg_read(handle, UC_ARM_REG_R0, &r0); uc_reg_read(uc, UC_ARM_REG_R0, &r0);
uc_reg_read(handle, UC_ARM_REG_R1, &r1); uc_reg_read(uc, UC_ARM_REG_R1, &r1);
printf(">>> R0 = 0x%x\n", r0); printf(">>> R0 = 0x%x\n", r0);
printf(">>> R1 = 0x%x\n", r1); printf(">>> R1 = 0x%x\n", r1);
uc_close(&handle); uc_close(uc);
} }
static void test_thumb(void) static void test_thumb(void)
{ {
uch handle; struct uc_struct *uc;
uc_err err; uc_err err;
uch trace1, trace2; uc_hook_h trace1, trace2;
int sp = 0x1234; // R0 register int sp = 0x1234; // R0 register
printf("Emulate THUMB code\n"); printf("Emulate THUMB code\n");
// Initialize emulator in ARM mode // Initialize emulator in ARM mode
err = uc_open(UC_ARCH_ARM, UC_MODE_THUMB, &handle); err = uc_open(UC_ARCH_ARM, UC_MODE_THUMB, &uc);
if (err) { if (err) {
printf("Failed on uc_open() with error returned: %u (%s)\n", printf("Failed on uc_open() with error returned: %u (%s)\n",
err, uc_strerror(err)); err, uc_strerror(err));
@ -109,23 +109,23 @@ static void test_thumb(void)
} }
// map 2MB memory for this emulation // map 2MB memory for this emulation
uc_mem_map(handle, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory // write machine code to be emulated to memory
uc_mem_write(handle, ADDRESS, (uint8_t *)THUMB_CODE, sizeof(THUMB_CODE) - 1); uc_mem_write(uc, ADDRESS, (uint8_t *)THUMB_CODE, sizeof(THUMB_CODE) - 1);
// initialize machine registers // initialize machine registers
uc_reg_write(handle, UC_ARM_REG_SP, &sp); uc_reg_write(uc, UC_ARM_REG_SP, &sp);
// tracing all basic blocks with customized callback // tracing all basic blocks with customized callback
uc_hook_add(handle, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0); 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 // tracing one instruction at ADDRESS with customized callback
uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS); 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 // emulate machine code in infinite time (last param = 0), or when
// finishing all the code. // finishing all the code.
err = uc_emu_start(handle, ADDRESS, ADDRESS + sizeof(THUMB_CODE) -1, UC_SECOND_SCALE * TIMEOUT, 0); err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(THUMB_CODE) -1, UC_SECOND_SCALE * TIMEOUT, 0);
if (err) { if (err) {
printf("Failed on uc_emu_start() with error returned: %u\n", err); printf("Failed on uc_emu_start() with error returned: %u\n", err);
} }
@ -133,10 +133,10 @@ static void test_thumb(void)
// now print out some registers // now print out some registers
printf(">>> Emulation done. Below is the CPU context\n"); printf(">>> Emulation done. Below is the CPU context\n");
uc_reg_read(handle, UC_ARM_REG_SP, &sp); uc_reg_read(uc, UC_ARM_REG_SP, &sp);
printf(">>> SP = 0x%x\n", sp); printf(">>> SP = 0x%x\n", sp);
uc_close(&handle); uc_close(uc);
} }
int main(int argc, char **argv, char **envp) int main(int argc, char **argv, char **envp)