import Unicorn2

This commit is contained in:
Nguyen Anh Quynh
2021-10-03 22:14:44 +08:00
parent 772558119a
commit aaaea14214
837 changed files with 368717 additions and 200912 deletions

View File

@@ -1,30 +0,0 @@
#!/usr/bin/python
from unicorn import *
from unicorn.arm_const import *
import regress
class APSRAccess(regress.RegressTest):
def runTest(self):
code = (
b'\x00\x00\xa0\xe1' + # 0: mov r0, r0
b'\x08\x10\x9f\xe5' + # 4: ldr r1, [pc, #8]
b'\x01\xf0\x28\xe1' + # 8: 01 f0 28 e1 msr apsr_nzcvq, r1
b'\x00\x00\xa0\xe1' + # c: mov r0, r0
b'\x00\x00\xa0\xe1' + # 10: mov r0, r0
b'\x00\x00\x00\xff') # 14: data for inst @4
uc = Uc(UC_ARCH_ARM, UC_MODE_ARM)
uc.mem_map(0x1000, 0x1000)
uc.mem_write(0x1000, code) # bxeq lr; mov r0, r0
uc.reg_write(UC_ARM_REG_APSR, 0)
uc.emu_start(0x1000, 0x100c)
self.assertEqual(uc.reg_read(UC_ARM_REG_APSR), 0xf8000000)
self.assertEqual(uc.reg_read(UC_ARM_REG_APSR_NZCV), 0xf0000000)
if __name__ == '__main__':
regress.main()

View File

@@ -0,0 +1,52 @@
from unicorn import *
from unicorn.arm_const import *
# .text:0001F894 ADD PC, PC, R3
# .text:0001F898 ; ---------------------------------------------------------------------------
# .text:0001F898 VLD1.8 {D0}, [R1]!
# .text:0001F89C VST1.8 {D0}, [R12]!
# .text:0001F8A0 VLD1.8 {D0}, [R1]!
# .text:0001F8A4 VST1.8 {D0}, [R12]!
# .text:0001F8A8 VLD1.8 {D0}, [R1]!
# .text:0001F8AC VST1.8 {D0}, [R12]!
# .text:0001F8B0 VLD1.8 {D0}, [R1]!
# .text:0001F8B4 VST1.8 {D0}, [R12]!
# .text:0001F8B8 VLD1.8 {D0}, [R1]!
# .text:0001F8BC VST1.8 {D0}, [R12]!
# .text:0001F8C0 VLD1.8 {D0}, [R1]!
# .text:0001F8C4 VST1.8 {D0}, [R12]!
# .text:0001F8C8 VLD1.8 {D0}, [R1]!
# .text:0001F8CC VST1.8 {D0}, [R12]!
# .text:0001F8D0 TST R2, #4
# .text:0001F8D4 LDRNE R3, [R1],#4
# .text:0001F8D8 STRNE R3, [R12],#4
# .text:0001F8DC MOVS R2, R2,LSL#31
# .text:0001F8E0 LDRHCS R3, [R1],#2
# .text:0001F8E4 LDRBNE R1, [R1]
# .text:0001F8E8 STRHCS R3, [R12],#2
# .text:0001F8EC STRBNE R1, [R12]
shellcode = [0x3, 0xf0, 0x8f, 0xe0, 0xd, 0x7, 0x21, 0xf4, 0xd, 0x7, 0xc, 0xf4, 0xd, 0x7, 0x21, 0xf4, 0xd, 0x7, 0xc, 0xf4, 0xd, 0x7, 0x21, 0xf4, 0xd, 0x7, 0xc, 0xf4, 0xd, 0x7, 0x21, 0xf4, 0xd, 0x7, 0xc, 0xf4, 0xd, 0x7, 0x21, 0xf4, 0xd, 0x7, 0xc, 0xf4, 0xd, 0x7, 0x21, 0xf4, 0xd, 0x7, 0xc, 0xf4, 0xd, 0x7, 0x21, 0xf4, 0xd, 0x7, 0xc, 0xf4, 0x4, 0x0, 0x12, 0xe3, 0x4, 0x30, 0x91, 0x14, 0x4, 0x30, 0x8c, 0x14, 0x82, 0x2f, 0xb0, 0xe1, 0xb2, 0x30, 0xd1, 0x20, 0x0, 0x10, 0xd1, 0x15, 0xb2, 0x30, 0xcc, 0x20, 0x0, 0x10, 0xcc, 0x15]
base = 0x1F894
from_address = 0x1000
to_address = 0x2000
cplen = 8
bs = b"c8"*cplen
uc = Uc(UC_ARCH_ARM, UC_MODE_ARM)
uc.mem_map(from_address, 0x1000)
uc.mem_map(to_address, 0x1000)
uc.mem_map(0x1F000, 0x1000)
uc.mem_write(from_address, bs)
uc.mem_write(base, bytes(shellcode))
uc.reg_write(UC_ARM_REG_R12, to_address)
uc.reg_write(UC_ARM_REG_R1, from_address)
uc.reg_write(UC_ARM_REG_R2, cplen)
uc.reg_write(UC_ARM_REG_R3, 0x24)
# enable_vfp
uc.reg_write(UC_ARM_REG_C1_C0_2, uc.reg_read(UC_ARM_REG_C1_C0_2) | (0xf << 20))
uc.reg_write(UC_ARM_REG_FPEXC, 0x40000000)
uc.emu_start(base, base+len(shellcode))
fr = uc.mem_read(from_address, len(bs))
to = uc.mem_read(to_address, len(bs))
print(f"memcpy result:\nfrom: {bytes(fr)}\nto: {bytes(to)}")

View File

@@ -0,0 +1,15 @@
from unicorn import *
from unicorn.arm_const import *
# ADD R0, R10, R0;
# B L0;
# L0:
# ADD R0, R10, R0; <--- we stop at here, the first instruction of the next TB.
code = b'\x00\x00\x8a\xe0\xff\xff\xff\xea\x00\x00\x8a\xe0'
address = 0x1000
mu = Uc(UC_ARCH_ARM, UC_MODE_ARM)
mu.mem_map(address, 0x1000)
mu.mem_write(address, code)
mu.emu_start(address, address + len(code) - 4)

View File

@@ -1,39 +0,0 @@
import regress
from unicorn import Uc, UC_ARCH_X86, UC_MODE_64, UC_HOOK_CODE
CODE = b"\x90" * 3
CODE_ADDR = 0x1000
class HookCounter(object):
"""Counts number of hook calls."""
def __init__(self):
self.hook_calls = 0
def bad_code_hook(self, uc, address, size, data):
self.hook_calls += 1
raise ValueError("Something went wrong")
def good_code_hook(self, uc, address, size, data):
self.hook_calls += 1
class TestExceptionInHook(regress.RegressTest):
def test_exception_in_hook(self):
uc = Uc(UC_ARCH_X86, UC_MODE_64)
uc.mem_map(CODE_ADDR, 0x1000)
uc.mem_write(CODE_ADDR, CODE)
counter = HookCounter()
uc.hook_add(UC_HOOK_CODE, counter.bad_code_hook, begin=CODE_ADDR, end=CODE_ADDR + len(CODE))
uc.hook_add(UC_HOOK_CODE, counter.good_code_hook, begin=CODE_ADDR, end=CODE_ADDR + len(CODE))
self.assertRaises(ValueError, uc.emu_start, CODE_ADDR, CODE_ADDR + len(CODE))
# Make sure hooks calls finish before raising (hook_calls == 2)
self.assertEqual(counter.hook_calls, 2)
if __name__ == "__main__":
regress.main()

View File

@@ -1,39 +0,0 @@
#include <stdio.h>
#include <unicorn/unicorn.h>
uint64_t starts[] = {0x10000000, 0x110004000ll};
int main(int argc, char **argv, char **envp) {
uc_engine *uc;
uc_err err;
int i;
// Initialize emulator in X86-64bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_64, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return 1;
}
for (i = 0; i < (sizeof(starts) / sizeof(uint64_t)); i++) {
uc_mem_map(uc, starts[i], 4096, UC_PROT_ALL);
}
uint32_t count;
uc_mem_region *regions;
int err_count = 0;
err = uc_mem_regions(uc, &regions, &count);
if (err == UC_ERR_OK) {
for (i = 0; i < count; i++) {
fprintf(stderr, "region %d: 0x%"PRIx64"-0x%"PRIx64" (%d)\n", i, regions[i].begin, regions[i].end - 1, regions[i].perms);
if (regions[i].begin != starts[i]) {
err_count++;
fprintf(stderr, " ERROR: region start does not match requested start address, expected 0x%"PRIx64", found 0x%"PRIx64"\n",
starts[i], regions[i].begin);
}
}
uc_free(regions);
}
uc_close(uc);
return err_count;
}

View File

@@ -1,48 +0,0 @@
#define __STDC_FORMAT_MACROS
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unicorn/unicorn.h>
int main(int argc, char **argv, char **envp)
{
uc_engine *uc;
uc_err err;
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
if (err) {
printf("not ok - Failed on uc_open() with error returned: %u\n", err);
return -1;
}
uc_mem_map(uc, 0x1000, 0x1000, UC_PROT_ALL);
if (err) {
printf("not ok - Failed on uc_mem_map() with error returned: %u\n", err);
return -1;
}
uc_mem_map(uc, 0x4000, 0x1000, UC_PROT_ALL);
if (err) {
printf("not ok - Failed on uc_mem_map() with error returned: %u\n", err);
return -1;
}
err = uc_mem_unmap(uc, 0x4000, 0x1000);
if (err) {
printf("not ok - Failed on uc_mem_unmap() with error returned: %u\n", err);
return -1;
}
err = uc_mem_unmap(uc, 0x4000, 0x1000);
if (!err) {
printf("not ok - second unmap succeeded\n");
return -1;
}
printf("Tests OK\n");
uc_close(uc);
return 0;
}

View File

@@ -1,278 +0,0 @@
/*
Executable memory regions demo / unit test
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#define __STDC_FORMAT_MACROS
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unicorn/unicorn.h>
unsigned char PROGRAM[] =
"\xeb\x45\x5e\x81\xe6\x00\xf0\xff\xff\x40\x40\x40\x40\x40\x40\x40"
"\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40"
"\x40\x40\x40\x40\x40\x40\x40\x89\xf7\x81\xc7\x00\x00\x10\x00\xb9"
"\x4c\x00\x00\x00\x81\xff\x00\x00\x40\x00\x75\x01\xf4\xf3\xa4\x81"
"\xe7\x00\xf0\xff\xff\xff\xe7\xe8\xb6\xff\xff\xff";
// total size: 76 bytes
/*
bits 32
; assumes r-x section at 0x100000
; assumes rw- section at 0x200000
; assumes r-- section at 0x300000
; also needs an initialized stack
start:
jmp bottom
top:
pop esi
and esi, ~0xfff
times 30 inc eax
mov edi, esi
add edi, 0x100000
mov ecx, end - start
rep movsb
and edi, ~0xfff
cmp edi, 0x400000
jnz next_block
hlt
next_block:
jmp edi
bottom:
call top
end:
*/
int test_num = 0;
uint32_t tests[] = {
0x41414141,
0x43434343,
0x45454545
};
static int log_num = 1;
#define CODE_SECTION 0x100000
#define CODE_SIZE 0x1000
// callback for tracing instruction
static void hook_code(uc_engine *uc, uint64_t addr, uint32_t size, void *user_data)
{
uint8_t opcode;
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 0xf4: //hlt
printf("# Handling HLT\n");
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 {
printf("ok %d - hlt encountered, uc_emu_stop called\n", log_num++);
}
break;
default: //all others
// printf("# Handling OTHER\n");
break;
}
}
// callback for tracing memory access (READ or WRITE)
static void hook_mem_write(uc_engine *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(uc_engine *uc, uc_mem_type type,
uint64_t addr, int size, int64_t value, void *user_data)
{
switch(type) {
default:
printf("not ok %d - memory invalid type: %d at 0x%" PRIx64 "\n", log_num++, type, addr);
return false;
case UC_MEM_FETCH_PROT:
printf("# Fetch from non-executable memory at 0x%"PRIx64 "\n", addr);
//make page executable
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);
}
return true;
case UC_MEM_WRITE_PROT:
printf("# write to non-writeable memory at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n", addr, size, value);
if (uc_mem_protect(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++);
}
return true;
}
}
int main(int argc, char **argv, char **envp)
{
uc_engine *uc;
uc_hook trace1, trace2;
uc_err err;
uint32_t esp, eip;
int32_t buf1[1024], buf2[1024], readbuf[1024];
int i;
//don't really care about quality of randomness
srand(time(NULL));
for (i = 0; i < 1024; i++) {
buf1[i] = rand();
buf2[i] = rand();
}
printf("# Memory protect test\n");
// Initialize emulator in X86-32bit mode
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;
} else {
printf("ok %d - uc_open() success\n", log_num++);
}
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(uc, UC_X86_REG_ESP, &esp)) {
printf("not ok %d - Failed to set esp. quit!\n", log_num++);
return 2;
} else {
printf("ok %d - ESP set\n", log_num++);
}
// fill in sections that shouldn't get touched
if (uc_mem_write(uc, 0x1ff000, buf1, sizeof(buf1))) {
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(uc, 0x301000, buf2, sizeof(buf2))) {
printf("not ok %d - Failed to write random buffer 2 to memory, quit!\n", log_num++);
return 4;
} else {
printf("ok %d - Random buffer 2 written to memory\n", log_num++);
}
// write machine code to be emulated to memory
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(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0) != UC_ERR_OK) {
printf("not ok %d - Failed to install UC_HOOK_CODE ucr\n", log_num++);
return 6;
} else {
printf("ok %d - UC_HOOK_CODE installed\n", log_num++);
}
// intercept memory write events
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE, hook_mem_write, NULL, 1, 0) != UC_ERR_OK) {
printf("not ok %d - Failed to install UC_HOOK_MEM_WRITE ucr\n", log_num++);
return 7;
} else {
printf("ok %d - UC_HOOK_MEM_WRITE installed\n", log_num++);
}
// intercept invalid memory events
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE_PROT | UC_HOOK_MEM_FETCH_PROT, hook_mem_invalid, NULL, 1, 0) != UC_ERR_OK) {
printf("not ok %d - Failed to install memory invalid handler\n", log_num++);
return 8;
} else {
printf("ok %d - memory invalid handler installed\n", log_num++);
}
// emulate machine code until told to stop by hook_code
printf("# BEGIN execution\n");
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;
} else {
printf("ok %d - uc_emu_start complete\n", log_num++);
}
printf("# END execution\n");
// get ending 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);
}
//make sure that random blocks didn't get nuked
// fill in sections that shouldn't get touched
if (uc_mem_read(uc, 0x1ff000, readbuf, sizeof(readbuf))) {
printf("not ok %d - Failed to read random buffer 1 from memory\n", log_num++);
} else {
printf("ok %d - Random buffer 1 read from memory\n", log_num++);
if (memcmp(buf1, readbuf, 4096)) {
printf("not ok %d - Random buffer 1 contents are incorrect\n", log_num++);
} else {
printf("ok %d - Random buffer 1 contents are correct\n", log_num++);
}
}
if (uc_mem_read(uc, 0x301000, readbuf, sizeof(readbuf))) {
printf("not ok %d - Failed to read random buffer 2 from memory\n", log_num++);
} else {
printf("ok %d - Random buffer 2 read from memory\n", log_num++);
if (memcmp(buf2, readbuf, 4096)) {
printf("not ok %d - Random buffer 2 contents are incorrect\n", log_num++);
} else {
printf("ok %d - Random buffer 2 contents are correct\n", log_num++);
}
}
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++);
}
return 0;
}

View File

@@ -1,116 +0,0 @@
#define __STDC_FORMAT_MACROS
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unicorn/unicorn.h>
uint64_t baseranges[] = {0,0,0,0};
int step =0;
uint64_t urnd(){
uint64_t rnd = rand();
rnd = rnd << 32;
rnd += rand();
return rnd;
}
uint64_t get_addr(){
uint64_t base = ((uint64_t)urnd())%4;
uint64_t addr= baseranges[base] + urnd()%(4096*10);
return addr;
}
uint64_t get_aligned_addr(){
uint64_t addr = get_addr();
return addr - (addr % 4096);
}
uint64_t get_len(){
uint64_t len = (urnd() % (4096*5))+1;
return len;
}
uint64_t get_aligned_len(){
uint64_t len = get_len();
len = len - (len %4096);
len = ((len == 0) ? 4096 : len);
return len;
}
void perform_map_step(uc_engine *uc){
uint64_t addr = get_aligned_addr();
uint64_t len = get_aligned_len();
printf("map(uc,0x%"PRIx64",0x%"PRIx64"); //%d\n", addr, len, step);
uc_mem_map(uc, addr, len, UC_PROT_READ | UC_PROT_WRITE);
}
void perform_unmap_step(uc_engine *uc){
uint64_t addr = get_aligned_addr();
uint64_t len = get_aligned_len();
printf("unmap(uc,0x%"PRIx64",0x%"PRIx64"); //%d\n", addr, len, step);
uc_mem_unmap(uc, addr, len);
}
void perform_write_step(uc_engine *uc){
char buff[4096*4];
memset((void *)buff, 0, 4096*4);
uint64_t addr = get_addr();
uint64_t len = get_len()%(4096*3);
printf("write(uc,0x%"PRIx64",0x%"PRIx64"); //%d\n", addr, len, step);
uc_mem_write(uc, addr, buff, len);
}
void perform_read_step(uc_engine *uc){
char buff[4096*4];
uint64_t addr = get_addr();
uint64_t len = get_len()%(4096*4);
printf("read(uc,0x%"PRIx64",0x%"PRIx64"); //%d\n", addr, len, step);
uc_mem_read(uc, addr, buff, len);
}
void perform_fuzz_step(uc_engine *uc){
switch( ((uint32_t)rand())%4 ){
case 0: perform_map_step(uc); break;
case 1: perform_unmap_step(uc); break;
case 2: perform_read_step(uc); break;
case 3: perform_write_step(uc); break;
}
}
int main(int argc, char **argv, char **envp)
{
uc_engine *uc;
uc_err err;
if(argc<2){
printf("usage: mem_fuzz $seed\n");
return 1;
}
int seed = atoi(argv[1]);
int i = 0;
//don't really care about quality of randomness
srand(seed);
printf("running with seed %d\n",seed);
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_64, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return 1;
}
for(i = 0; i < 2048; i++){
step++;
perform_fuzz_step(uc);
}
// fill in sections that shouldn't get touched
if (uc_close(uc) != UC_ERR_OK) {
printf("Failed on uc_close\n");
return 1;
}
return 0;
}

View File

@@ -1,31 +0,0 @@
#include <unicorn/unicorn.h>
#include <stdio.h>
int main() {
uc_engine *u;
uc_err err;
printf("mem_map_0x100000000.c \n");
if ((err = uc_open(UC_ARCH_X86, UC_MODE_32, &u)) != UC_ERR_OK) {
printf("uc_open() failed: %s\n", uc_strerror(err));
return -1;
}
if ((err = uc_mem_map(u, 0x100000000, 0x002c0000, UC_PROT_ALL)) != UC_ERR_OK) {
printf("uc_mem_map() failed: %s\n", uc_strerror(err));
return -1;
}
if ((err = uc_mem_map(u, 0x0018D000, 0x00006000, UC_PROT_ALL)) != UC_ERR_OK) {
printf("uc_mem_map() failed: %s\n", uc_strerror(err));
return -1;
}
if ((err = uc_close(u)) != UC_ERR_OK) {
printf("uc_close() failed: %s\n", uc_strerror(err));
return -1;
}
printf("Success.\n");
return 0;
}

View File

@@ -1,17 +0,0 @@
#include <unicorn/unicorn.h>
#include <stdio.h>
int main() {
uc_engine *u;
uc_err err;
if ((err = uc_open(UC_ARCH_X86, UC_MODE_32, &u)) != UC_ERR_OK) {
printf("uc_open() failed: %s\n", uc_strerror(err));
}
printf("Trying large map.\n");
if ((err = uc_mem_map(u, 0x60802000, (unsigned) 0x28bd211200004000, UC_PROT_ALL)) != UC_ERR_OK) {
printf("uc_mem_map() failed: %s\n", uc_strerror(err));
return -1;
}
printf("Success.\n");
return 0;
}

View File

@@ -1,70 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <unicorn/unicorn.h>
#define ADDRESS1 0x10000000
#define ADDRESS2 0x20000000
#define SIZE (80 * 1024 * 1024)
static void VM_exec()
{
int c;
uc_engine *uc;
uc_err err;
// Initialize emulator in X86-64bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
if(err)
{
printf("Failed on uc_open() with error returned: %s\n", uc_strerror(err));
return;
}
repeat:
err = uc_mem_map(uc, ADDRESS1, SIZE, UC_PROT_ALL);
if(err != UC_ERR_OK)
{
printf("Failed to map memory %s\n", uc_strerror(err));
goto err;
}
err = uc_mem_map(uc, ADDRESS2, SIZE, UC_PROT_ALL);
if(err != UC_ERR_OK)
{
printf("Failed to map memory %s\n", uc_strerror(err));
goto err;
}
err = uc_mem_unmap(uc, ADDRESS1, SIZE);
if(err != UC_ERR_OK)
{
printf("Failed to unmap memory %s\n", uc_strerror(err));
goto err;
}
err = uc_mem_unmap(uc, ADDRESS2, SIZE);
if(err != UC_ERR_OK)
{
printf("Failed to unmap memory %s\n", uc_strerror(err));
goto err;
}
for(;;)
{
c = getchar(); //pause here and analyse memory usage before exiting with a program like VMMap;
if(c != 'e')
goto repeat;
else
break;
}
err:
uc_close(uc);
}
int main(int argc, char *argv[])
{
VM_exec();
return 0;
}

View File

@@ -1,300 +0,0 @@
/*
uc_mem_protect demo / unit test
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#define __STDC_FORMAT_MACROS
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unicorn/unicorn.h>
unsigned char PROGRAM[] =
"\xc7\x05\x00\x00\x20\x00\x41\x41\x41\x41\x90\xc7\x05\x00\x00\x20"
"\x00\x42\x42\x42\x42\xc7\x05\x00\x00\x30\x00\x43\x43\x43\x43\x90"
"\xc7\x05\x00\x00\x30\x00\x44\x44\x44\x44\xc7\x05\x00\x00\x40\x00"
"\x45\x45\x45\x45\x90\xc7\x05\x00\x00\x40\x00\x46\x46\x46\x46\xc7"
"\x05\x00\xf8\x3f\x00\x47\x47\x47\x47\xc7\x05\x00\x18\x40\x00\x48"
"\x48\x48\x48\xf4";
// total size: 84 bytes
/*
bits 32
; assumes code section at 0x100000
; assumes data section at 0x200000, initially rw
; assumes data section at 0x300000, initially rw
; assumes data section at 0x400000, initially rw
; with installed hooks unmaps or maps on each nop
mov dword [0x200000], 0x41414141
nop ; mark it RO
mov dword [0x200000], 0x42424242
mov dword [0x300000], 0x43434343
nop ; mark it RO
mov dword [0x300000], 0x44444444
mov dword [0x400000], 0x45454545
nop ; mark it RO
mov dword [0x400000], 0x46464646
mov dword [0x3ff800], 0x47474747 ; make sure surrounding areas remained RW
mov dword [0x401800], 0x48484848 ; make sure surrounding areas remained RW
hlt ; tell hook function we are done
*/
int test_num = 0;
uint32_t tests[] = {
0x41414141,
0x43434343,
0x45454545
};
static int log_num = 1;
#define CODE_SECTION 0x100000
#define CODE_SIZE 0x1000
// callback for tracing instruction
static void hook_code(uc_engine *uc, uint64_t addr, uint32_t size, void *user_data)
{
uint8_t opcode;
uint32_t testval;
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(uc, 0x200000 + test_num * 0x100000, &testval, sizeof(testval)) != UC_ERR_OK) {
printf("not ok %d - uc_mem_read fail for address: 0x%x\n", log_num++, 0x200000 + test_num * 0x100000);
} else {
printf("ok %d - good uc_mem_read for address: 0x%x\n", log_num++, 0x200000 + test_num * 0x100000);
printf("# uc_mem_read for test %d\n", test_num);
if (testval == tests[test_num]) {
printf("ok %d - passed test %d\n", log_num++, test_num);
} else {
printf("not ok %d - failed test %d\n", log_num++, test_num);
printf("# Expected: 0x%x\n",tests[test_num]);
printf("# Received: 0x%x\n", testval);
}
}
if (uc_mem_protect(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++);
}
test_num++;
break;
case 0xf4: //hlt
printf("# Handling HLT\n");
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 {
printf("ok %d - hlt encountered, uc_emu_stop called\n", log_num++);
}
break;
default: //all others
printf("# Handling OTHER\n");
break;
}
}
// callback for tracing memory access (READ or WRITE)
static void hook_mem_write(uc_engine *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(uc_engine *uc, uc_mem_type type,
uint64_t addr, int size, int64_t value, void *user_data)
{
uint32_t testval;
switch(type) {
default:
printf("not ok %d - memory invalid type: %d at 0x%" PRIx64 "\n", log_num++, type, addr);
return false;
case UC_MEM_WRITE_PROT:
printf("# write to non-writeable memory at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n", addr, size, value);
if (uc_mem_read(uc, addr, &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(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++);
}
return true;
}
}
int main(int argc, char **argv, char **envp)
{
uc_engine *uc;
uc_hook trace1, trace2;
uc_err err;
uint32_t addr, testval;
int32_t buf1[1024], buf2[1024], readbuf[1024];
int i;
//don't really care about quality of randomness
srand(time(NULL));
for (i = 0; i < 1024; i++) {
buf1[i] = rand();
buf2[i] = rand();
}
printf("# Memory protect test\n");
// Initialize emulator in X86-32bit mode
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;
} else {
printf("ok %d - uc_open() success\n", log_num++);
}
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(uc, 0x3ff000, buf1, sizeof(buf1))) {
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(uc, 0x401000, buf2, sizeof(buf2))) {
printf("not ok %d - Failed to write random buffer 2 to memory, quit!\n", log_num++);
return 3;
} else {
printf("ok %d - Random buffer 2 written to memory\n", log_num++);
}
// write machine code to be emulated to memory
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(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0) != UC_ERR_OK) {
printf("not ok %d - Failed to install UC_HOOK_CODE ucr\n", log_num++);
return 5;
} else {
printf("ok %d - UC_HOOK_CODE installed\n", log_num++);
}
// intercept memory write events
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE, hook_mem_write, NULL, 1, 0) != UC_ERR_OK) {
printf("not ok %d - Failed to install UC_HOOK_MEM_WRITE ucr\n", log_num++);
return 6;
} else {
printf("ok %d - UC_HOOK_MEM_WRITE installed\n", log_num++);
}
// intercept invalid memory events
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE_PROT, hook_mem_invalid, NULL, 1, 0) != UC_ERR_OK) {
printf("not ok %d - Failed to install memory invalid handler\n", log_num++);
return 7;
} else {
printf("ok %d - memory invalid handler installed\n", log_num++);
}
// emulate machine code until told to stop by hook_code
printf("# BEGIN execution\n");
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;
} else {
printf("ok %d - uc_emu_start complete\n", log_num++);
}
printf("# END execution\n");
//read from the remapped memory
testval = 0x42424242;
for (addr = 0x200000; addr <= 0x400000; addr += 0x100000) {
uint32_t val;
if (uc_mem_read(uc, addr, &val, sizeof(val)) != UC_ERR_OK) {
printf("not ok %d - Failed uc_mem_read for address 0x%x\n", log_num++, addr);
} else {
printf("ok %d - Good uc_mem_read from 0x%x\n", log_num++, addr);
}
if (val != testval) {
printf("not ok %d - Read 0x%x, expected 0x%x\n", log_num++, val, testval);
} else {
printf("ok %d - Correct value retrieved\n", log_num++);
}
testval += 0x02020202;
}
//account for the two mods made by the machine code
buf1[512] = 0x47474747;
buf2[512] = 0x48484848;
//make sure that random blocks didn't get nuked
// fill in sections that shouldn't get touched
if (uc_mem_read(uc, 0x3ff000, readbuf, sizeof(readbuf))) {
printf("not ok %d - Failed to read random buffer 1 from memory\n", log_num++);
} else {
printf("ok %d - Random buffer 1 read from memory\n", log_num++);
if (memcmp(buf1, readbuf, 4096)) {
printf("not ok %d - Random buffer 1 contents are incorrect\n", log_num++);
} else {
printf("ok %d - Random buffer 1 contents are correct\n", log_num++);
}
}
if (uc_mem_read(uc, 0x401000, readbuf, sizeof(readbuf))) {
printf("not ok %d - Failed to read random buffer 2 from memory\n", log_num++);
} else {
printf("ok %d - Random buffer 2 read from memory\n", log_num++);
if (memcmp(buf2, readbuf, 4096)) {
printf("not ok %d - Random buffer 2 contents are incorrect\n", log_num++);
} else {
printf("ok %d - Random buffer 2 contents are correct\n", log_num++);
}
}
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++);
}
return 0;
}

View File

@@ -1,291 +0,0 @@
/*
uc_mem_unmap demo / unit test
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#define __STDC_FORMAT_MACROS
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unicorn/unicorn.h>
unsigned char PROGRAM[] =
"\xc7\x05\x00\x00\x20\x00\x41\x41\x41\x41\x90\xc7\x05\x00\x00\x20"
"\x00\x42\x42\x42\x42\xc7\x05\x00\x00\x30\x00\x43\x43\x43\x43\x90"
"\xc7\x05\x00\x00\x30\x00\x44\x44\x44\x44\xc7\x05\x00\x00\x40\x00"
"\x45\x45\x45\x45\x90\xc7\x05\x00\x00\x40\x00\x46\x46\x46\x46\xf4";
// total size: 64 bytes
/*
; assumes code section at 0x100000
; assumes data section at 0x200000, initially rw
; assumes data section at 0x300000, initially rw
; assumes data section at 0x400000, initially rw
; with installed hooks unmaps or maps on each nop
mov dword [0x200000], 0x41414141
nop ; unmap it
mov dword [0x200000], 0x42424242
mov dword [0x300000], 0x43434343
nop ; unmap it
mov dword [0x300000], 0x44444444
mov dword [0x400000], 0x45454545
nop ; unmap it
mov dword [0x400000], 0x46464646
hlt ; tell hook function we are done
*/
int test_num = 0;
uint32_t tests[] = {
0x41414141,
0x43434343,
0x45454545
};
static int log_num = 1;
#define CODE_SECTION 0x100000
#define CODE_SIZE 0x1000
// callback for tracing instruction
static void hook_code(uc_engine *uc, uint64_t addr, uint32_t size, void *user_data)
{
uint8_t opcode;
uint32_t testval;
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(uc, 0x200000 + test_num * 0x100000, &testval, sizeof(testval)) != UC_ERR_OK) {
printf("not ok %d - uc_mem_read fail for address: 0x%x\n", log_num++, 0x200000 + test_num * 0x100000);
} else {
printf("ok %d - good uc_mem_read for address: 0x%x\n", log_num++, 0x200000 + test_num * 0x100000);
printf("# uc_mem_read for test %d\n", test_num);
if (testval == tests[test_num]) {
printf("ok %d - passed test %d\n", log_num++, test_num);
} else {
printf("not ok %d - failed test %d\n", log_num++, test_num);
printf("# Expected: 0x%x\n",tests[test_num]);
printf("# Received: 0x%x\n", testval);
}
}
if (uc_mem_unmap(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++);
}
test_num++;
break;
case 0xf4: //hlt
printf("# Handling HLT\n");
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 {
printf("ok %d - hlt encountered, uc_emu_stop called\n", log_num++);
}
break;
default: //all others
printf("# Handling OTHER\n");
break;
}
}
// callback for tracing memory access (READ or WRITE)
static void hook_mem_write(uc_engine *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(uc_engine *uc, uc_mem_type type,
uint64_t addr, int size, int64_t value, void *user_data)
{
uint32_t testval;
switch(type) {
default:
printf("not ok %d - memory invalid type: %d at 0x%" PRIx64 "\n", log_num++, type, addr);
return false;
case UC_MEM_WRITE_UNMAPPED:
printf("# write to invalid memory at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n", addr, size, value);
if (uc_mem_read(uc, addr, &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(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++);
}
return true;
}
}
int main(int argc, char **argv, char **envp)
{
uc_engine *uc;
uc_hook trace1, trace2;
uc_err err;
uint32_t addr, testval;
int32_t buf1[1024], buf2[1024], readbuf[1024];
int i;
//don't really care about quality of randomness
srand(time(NULL));
for (i = 0; i < 1024; i++) {
buf1[i] = rand();
buf2[i] = rand();
}
printf("# Memory unmapping test\n");
// Initialize emulator in X86-32bit mode
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;
} else {
printf("ok %d - uc_open() success\n", log_num++);
}
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(uc, 0x3ff000, buf1, sizeof(buf1))) {
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(uc, 0x401000, buf2, sizeof(buf1))) {
printf("not ok %d - Failed to write random buffer 2 to memory, quit!\n", log_num++);
return 3;
} else {
printf("ok %d - Random buffer 2 written to memory\n", log_num++);
}
// write machine code to be emulated to memory
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(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0) != UC_ERR_OK) {
printf("not ok %d - Failed to install UC_HOOK_CODE ucr\n", log_num++);
return 5;
} else {
printf("ok %d - UC_HOOK_CODE installed\n", log_num++);
}
// intercept memory write events
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE, hook_mem_write, NULL, 1, 0) != UC_ERR_OK) {
printf("not ok %d - Failed to install UC_HOOK_MEM_WRITE ucr\n", log_num++);
return 6;
} else {
printf("ok %d - UC_HOOK_MEM_WRITE installed\n", log_num++);
}
// intercept invalid memory events
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE_UNMAPPED, hook_mem_invalid, NULL, 1, 0) != UC_ERR_OK) {
printf("not ok %d - Failed to install memory invalid handler\n", log_num++);
return 7;
} else {
printf("ok %d - memory invalid handler installed\n", log_num++);
}
// emulate machine code until told to stop by hook_code
printf("# BEGIN execution\n");
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;
} else {
printf("ok %d - uc_emu_start complete\n", log_num++);
}
printf("# END execution\n");
//read from the remapped memory
testval = 0x42424242;
for (addr = 0x200000; addr <= 0x400000; addr += 0x100000) {
uint32_t val;
if (uc_mem_read(uc, addr, &val, sizeof(val)) != UC_ERR_OK) {
printf("not ok %d - Failed uc_mem_read for address 0x%x\n", log_num++, addr);
} else {
printf("ok %d - Good uc_mem_read from 0x%x\n", log_num++, addr);
}
if (val != testval) {
printf("not ok %d - Read 0x%x, expected 0x%x\n", log_num++, val, testval);
} else {
printf("ok %d - Correct value retrieved\n", log_num++);
}
testval += 0x02020202;
}
//make sure that random blocks didn't get nuked
// fill in sections that shouldn't get touched
if (uc_mem_read(uc, 0x3ff000, readbuf, sizeof(readbuf))) {
printf("not ok %d - Failed to read random buffer 1 from memory\n", log_num++);
} else {
printf("ok %d - Random buffer 1 read from memory\n", log_num++);
if (memcmp(buf1, readbuf, 4096)) {
printf("not ok %d - Random buffer 1 contents are incorrect\n", log_num++);
} else {
printf("ok %d - Random buffer 1 contents are correct\n", log_num++);
}
}
if (uc_mem_read(uc, 0x401000, readbuf, sizeof(readbuf))) {
printf("not ok %d - Failed to read random buffer 2 from memory\n", log_num++);
} else {
printf("ok %d - Random buffer 2 read from memory\n", log_num++);
if (memcmp(buf2, readbuf, 4096)) {
printf("not ok %d - Random buffer 2 contents are incorrect\n", log_num++);
} else {
printf("ok %d - Random buffer 2 contents are correct\n", log_num++);
}
}
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++);
}
return 0;
}

View File

@@ -1,176 +0,0 @@
/* Unicorn Emulator Engine */
/* By Nguyen Anh Quynh, 2015 */
/* Sample code to demonstrate how to emulate ARM code */
// windows specific
#ifdef _MSC_VER
#include <io.h>
#include <windows.h>
#define PRIx64 "llX"
#ifdef DYNLOAD
#include "unicorn_dynload.h"
#else // DYNLOAD
#include <unicorn/unicorn.h>
#ifdef _WIN64
#pragma comment(lib, "unicorn_staload64.lib")
#else // _WIN64
#pragma comment(lib, "unicorn_staload.lib")
#endif // _WIN64
#endif // DYNLOAD
// posix specific
#else // _MSC_VER
#include <unicorn/unicorn.h>
#endif // _MSC_VER
// code to be emulated
#define ARM_CODE "\x37\x00\xa0\xe3\x03\x10\x42\xe0" // mov r0, #0x37; sub r1, r2, r3
#define THUMB_CODE "\x83\xb0" // sub sp, #0xc
// memory address where emulation starts
#define ADDRESS 0x10000
static void hook_block(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
{
printf(">>> Tracing basic block at 0x%"PRIx64 ", block size = 0x%x\n", address, size);
}
static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
{
printf(">>> Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size);
}
static void test_arm(void)
{
uc_engine *uc;
uc_err err;
uc_hook trace1, trace2;
int r0 = 0x1234; // R0 register
int r2 = 0x6789; // R1 register
int r3 = 0x3333; // R2 register
int r1; // R1 register
printf("Emulate ARM code\n");
// Initialize emulator in ARM mode
err = uc_open(UC_ARCH_ARM, UC_MODE_ARM, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u (%s)\n",
err, uc_strerror(err));
return;
}
// map 2MB memory for this emulation
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc_mem_write(uc, ADDRESS, ARM_CODE, sizeof(ARM_CODE) - 1);
// initialize machine registers
uc_reg_write(uc, UC_ARM_REG_R0, &r0);
uc_reg_write(uc, UC_ARM_REG_R2, &r2);
uc_reg_write(uc, UC_ARM_REG_R3, &r3);
// tracing all basic blocks with customized callback
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
// tracing one instruction at ADDRESS with customized callback
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(ARM_CODE) -1, 0, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned: %u\n", err);
}
// now print out some registers
printf(">>> Emulation done. Below is the CPU context\n");
uc_reg_read(uc, UC_ARM_REG_R0, &r0);
uc_reg_read(uc, UC_ARM_REG_R1, &r1);
printf(">>> R0 = 0x%x\n", r0);
printf(">>> R1 = 0x%x\n", r1);
uc_close(uc);
}
static void test_thumb(void)
{
uc_engine *uc;
uc_err err;
uc_hook trace1, trace2;
int sp = 0x1234; // R0 register
printf("Emulate THUMB code\n");
// Initialize emulator in ARM mode
err = uc_open(UC_ARCH_ARM, UC_MODE_THUMB, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u (%s)\n",
err, uc_strerror(err));
return;
}
// map 2MB memory for this emulation
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc_mem_write(uc, ADDRESS, THUMB_CODE, sizeof(THUMB_CODE) - 1);
// initialize machine registers
uc_reg_write(uc, UC_ARM_REG_SP, &sp);
// tracing all basic blocks with customized callback
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
// tracing one instruction at ADDRESS with customized callback
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(THUMB_CODE) -1, 0, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned: %u\n", err);
}
// now print out some registers
printf(">>> Emulation done. Below is the CPU context\n");
uc_reg_read(uc, UC_ARM_REG_SP, &sp);
printf(">>> SP = 0x%x\n", sp);
uc_close(uc);
}
int main(int argc, char **argv, char **envp)
{
// dynamically load shared library
#ifdef DYNLOAD
if (!uc_dyn_load(NULL, 0)) {
printf("Error dynamically loading shared library.\n");
printf("Please check that unicorn.dll/unicorn.so is available as well as\n");
printf("any other dependent dll/so files.\n");
printf("The easiest way is to place them in the same directory as this app.\n");
return 1;
}
#endif
// test memleak
while(1) {
test_arm();
printf("==========================\n");
test_thumb();
}
// dynamically free shared library
#ifdef DYNLOAD
uc_dyn_free();
#endif
return 0;
}

View File

@@ -1,120 +0,0 @@
/* Unicorn Emulator Engine */
/* By Nguyen Anh Quynh, 2015 */
/* Sample code to demonstrate how to emulate ARM64 code */
// windows specific
#ifdef _MSC_VER
#include <io.h>
#include <windows.h>
#define PRIx64 "llX"
#ifdef DYNLOAD
#include "unicorn_dynload.h"
#else // DYNLOAD
#include <unicorn/unicorn.h>
#ifdef _WIN64
#pragma comment(lib, "unicorn_staload64.lib")
#else // _WIN64
#pragma comment(lib, "unicorn_staload.lib")
#endif // _WIN64
#endif // DYNLOAD
// posix specific
#else // _MSC_VER
#include <unicorn/unicorn.h>
#endif // _MSC_VER
// code to be emulated
#define ARM_CODE "\xab\x01\x0f\x8b" // add x11, x13, x15
// memory address where emulation starts
#define ADDRESS 0x10000
static void hook_block(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
{
printf(">>> Tracing basic block at 0x%"PRIx64 ", block size = 0x%x\n", address, size);
}
static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
{
printf(">>> Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size);
}
static void test_arm64(void)
{
uc_engine *uc;
uc_err err;
uc_hook trace1, trace2;
int64_t x11 = 0x1234; // X11 register
int64_t x13 = 0x6789; // X13 register
int64_t x15 = 0x3333; // X15 register
printf("Emulate ARM64 code\n");
// Initialize emulator in ARM mode
err = uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u (%s)\n",
err, uc_strerror(err));
return;
}
// map 2MB memory for this emulation
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc_mem_write(uc, ADDRESS, ARM_CODE, sizeof(ARM_CODE) - 1);
// initialize machine registers
uc_reg_write(uc, UC_ARM64_REG_X11, &x11);
uc_reg_write(uc, UC_ARM64_REG_X13, &x13);
uc_reg_write(uc, UC_ARM64_REG_X15, &x15);
// tracing all basic blocks with customized callback
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
// tracing one instruction at ADDRESS with customized callback
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(ARM_CODE) -1, 0, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned: %u\n", err);
}
// now print out some registers
printf(">>> Emulation done. Below is the CPU context\n");
uc_reg_read(uc, UC_ARM64_REG_X11, &x11);
printf(">>> X11 = 0x%" PRIx64 "\n", x11);
uc_close(uc);
}
int main(int argc, char **argv, char **envp)
{
// dynamically load shared library
#ifdef DYNLOAD
if (!uc_dyn_load(NULL, 0)) {
printf("Error dynamically loading shared library.\n");
printf("Please check that unicorn.dll/unicorn.so is available as well as\n");
printf("any other dependent dll/so files.\n");
printf("The easiest way is to place them in the same directory as this app.\n");
return 1;
}
#endif
while(1) {
test_arm64();
}
// dynamically free shared library
#ifdef DYNLOAD
uc_dyn_free();
#endif
return 0;
}

View File

@@ -1,183 +0,0 @@
/* Unicorn Emulator Engine */
/* By Loi Anh Tuan, 2015 */
/* Sample code to demonstrate how to emulate m68k code */
// windows specific
#ifdef _MSC_VER
#include <io.h>
#include <windows.h>
#define PRIx64 "llX"
#ifdef DYNLOAD
#include "unicorn_dynload.h"
#else // DYNLOAD
#include <unicorn/unicorn.h>
#ifdef _WIN64
#pragma comment(lib, "unicorn_staload64.lib")
#else // _WIN64
#pragma comment(lib, "unicorn_staload.lib")
#endif // _WIN64
#endif // DYNLOAD
// posix specific
#else // _MSC_VER
#include <unicorn/unicorn.h>
#endif // _MSC_VER
// code to be emulated
#define M68K_CODE "\x76\xed" // movq #-19, %d3
// memory address where emulation starts
#define ADDRESS 0x10000
static void hook_block(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
{
printf(">>> Tracing basic block at 0x%"PRIx64 ", block size = 0x%x\n", address, size);
}
static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
{
printf(">>> Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size);
}
static void test_m68k(void)
{
uc_engine *uc;
uc_hook trace1, trace2;
uc_err err;
int d0 = 0x0000; // d0 data register
int d1 = 0x0000; // d1 data register
int d2 = 0x0000; // d2 data register
int d3 = 0x0000; // d3 data register
int d4 = 0x0000; // d4 data register
int d5 = 0x0000; // d5 data register
int d6 = 0x0000; // d6 data register
int d7 = 0x0000; // d7 data register
int a0 = 0x0000; // a0 address register
int a1 = 0x0000; // a1 address register
int a2 = 0x0000; // a2 address register
int a3 = 0x0000; // a3 address register
int a4 = 0x0000; // a4 address register
int a5 = 0x0000; // a5 address register
int a6 = 0x0000; // a6 address register
int a7 = 0x0000; // a6 address register
int pc = 0x0000; // program counter
int sr = 0x0000; // status register
printf("Emulate M68K code\n");
// Initialize emulator in M68K mode
err = uc_open(UC_ARCH_M68K, UC_MODE_BIG_ENDIAN, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u (%s)\n",
err, uc_strerror(err));
return;
}
// map 2MB memory for this emulation
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc_mem_write(uc, ADDRESS, M68K_CODE, sizeof(M68K_CODE) - 1);
// initialize machine registers
uc_reg_write(uc, UC_M68K_REG_D0, &d0);
uc_reg_write(uc, UC_M68K_REG_D1, &d1);
uc_reg_write(uc, UC_M68K_REG_D2, &d2);
uc_reg_write(uc, UC_M68K_REG_D3, &d3);
uc_reg_write(uc, UC_M68K_REG_D4, &d4);
uc_reg_write(uc, UC_M68K_REG_D5, &d5);
uc_reg_write(uc, UC_M68K_REG_D6, &d6);
uc_reg_write(uc, UC_M68K_REG_D7, &d7);
uc_reg_write(uc, UC_M68K_REG_A0, &a0);
uc_reg_write(uc, UC_M68K_REG_A1, &a1);
uc_reg_write(uc, UC_M68K_REG_A2, &a2);
uc_reg_write(uc, UC_M68K_REG_A3, &a3);
uc_reg_write(uc, UC_M68K_REG_A4, &a4);
uc_reg_write(uc, UC_M68K_REG_A5, &a5);
uc_reg_write(uc, UC_M68K_REG_A6, &a6);
uc_reg_write(uc, UC_M68K_REG_A7, &a7);
uc_reg_write(uc, UC_M68K_REG_PC, &pc);
uc_reg_write(uc, UC_M68K_REG_SR, &sr);
// tracing all basic blocks with customized callback
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
// tracing all instruction
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(M68K_CODE)-1, 0, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned: %u\n", err);
}
// now print out some registers
printf(">>> Emulation done. Below is the CPU context\n");
uc_reg_read(uc, UC_M68K_REG_D0, &d0);
uc_reg_read(uc, UC_M68K_REG_D1, &d1);
uc_reg_read(uc, UC_M68K_REG_D2, &d2);
uc_reg_read(uc, UC_M68K_REG_D3, &d3);
uc_reg_read(uc, UC_M68K_REG_D4, &d4);
uc_reg_read(uc, UC_M68K_REG_D5, &d5);
uc_reg_read(uc, UC_M68K_REG_D6, &d6);
uc_reg_read(uc, UC_M68K_REG_D7, &d7);
uc_reg_read(uc, UC_M68K_REG_A0, &a0);
uc_reg_read(uc, UC_M68K_REG_A1, &a1);
uc_reg_read(uc, UC_M68K_REG_A2, &a2);
uc_reg_read(uc, UC_M68K_REG_A3, &a3);
uc_reg_read(uc, UC_M68K_REG_A4, &a4);
uc_reg_read(uc, UC_M68K_REG_A5, &a5);
uc_reg_read(uc, UC_M68K_REG_A6, &a6);
uc_reg_read(uc, UC_M68K_REG_A7, &a7);
uc_reg_read(uc, UC_M68K_REG_PC, &pc);
uc_reg_read(uc, UC_M68K_REG_SR, &sr);
printf(">>> A0 = 0x%x\t\t>>> D0 = 0x%x\n", a0, d0);
printf(">>> A1 = 0x%x\t\t>>> D1 = 0x%x\n", a1, d1);
printf(">>> A2 = 0x%x\t\t>>> D2 = 0x%x\n", a2, d2);
printf(">>> A3 = 0x%x\t\t>>> D3 = 0x%x\n", a3, d3);
printf(">>> A4 = 0x%x\t\t>>> D4 = 0x%x\n", a4, d4);
printf(">>> A5 = 0x%x\t\t>>> D5 = 0x%x\n", a5, d5);
printf(">>> A6 = 0x%x\t\t>>> D6 = 0x%x\n", a6, d6);
printf(">>> A7 = 0x%x\t\t>>> D7 = 0x%x\n", a7, d7);
printf(">>> PC = 0x%x\n", pc);
printf(">>> SR = 0x%x\n", sr);
uc_close(uc);
}
int main(int argc, char **argv, char **envp)
{
// dynamically load shared library
#ifdef DYNLOAD
if (!uc_dyn_load(NULL, 0)) {
printf("Error dynamically loading shared library.\n");
printf("Please check that unicorn.dll/unicorn.so is available as well as\n");
printf("any other dependent dll/so files.\n");
printf("The easiest way is to place them in the same directory as this app.\n");
return 1;
}
#endif
// test memleak
while(1) {
test_m68k();
}
// dynamically free shared library
#ifdef DYNLOAD
uc_dyn_free();
#endif
return 0;
}

View File

@@ -1,169 +0,0 @@
/* Unicorn Emulator Engine */
/* By Nguyen Anh Quynh, 2015 */
/* Sample code to demonstrate how to emulate Mips code (big endian) */
// windows specific
#ifdef _MSC_VER
#include <io.h>
#include <windows.h>
#define PRIx64 "llX"
#ifdef DYNLOAD
#include "unicorn_dynload.h"
#else // DYNLOAD
#include <unicorn/unicorn.h>
#ifdef _WIN64
#pragma comment(lib, "unicorn_staload64.lib")
#else // _WIN64
#pragma comment(lib, "unicorn_staload.lib")
#endif // _WIN64
#endif // DYNLOAD
// posix specific
#else // _MSC_VER
#include <unicorn/unicorn.h>
#endif // _MSC_VER
// code to be emulated
#define MIPS_CODE_EB "\x34\x21\x34\x56" // ori $at, $at, 0x3456;
#define MIPS_CODE_EL "\x56\x34\x21\x34" // ori $at, $at, 0x3456;
// memory address where emulation starts
#define ADDRESS 0x10000
static void hook_block(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
{
printf(">>> Tracing basic block at 0x%"PRIx64 ", block size = 0x%x\n", address, size);
}
static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
{
printf(">>> Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size);
}
static void test_mips_eb(void)
{
uc_engine *uc;
uc_err err;
uc_hook trace1, trace2;
int r1 = 0x6789; // R1 register
printf("Emulate MIPS code (big-endian)\n");
// Initialize emulator in MIPS mode
err = uc_open(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_BIG_ENDIAN, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u (%s)\n",
err, uc_strerror(err));
return;
}
// map 2MB memory for this emulation
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc_mem_write(uc, ADDRESS, MIPS_CODE_EB, sizeof(MIPS_CODE_EB) - 1);
// initialize machine registers
uc_reg_write(uc, UC_MIPS_REG_1, &r1);
// tracing all basic blocks with customized callback
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
// tracing one instruction at ADDRESS with customized callback
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(MIPS_CODE_EB) - 1, 0, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned: %u (%s)\n", err, uc_strerror(err));
}
// now print out some registers
printf(">>> Emulation done. Below is the CPU context\n");
uc_reg_read(uc, UC_MIPS_REG_1, &r1);
printf(">>> R1 = 0x%x\n", r1);
uc_close(uc);
}
static void test_mips_el(void)
{
uc_engine *uc;
uc_err err;
uc_hook trace1, trace2;
int r1 = 0x6789; // R1 register
printf("===========================\n");
printf("Emulate MIPS code (little-endian)\n");
// Initialize emulator in MIPS mode
err = uc_open(UC_ARCH_MIPS, UC_MODE_MIPS32, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u (%s)\n",
err, uc_strerror(err));
return;
}
// map 2MB memory for this emulation
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc_mem_write(uc, ADDRESS, MIPS_CODE_EL, sizeof(MIPS_CODE_EL) - 1);
// initialize machine registers
uc_reg_write(uc, UC_MIPS_REG_1, &r1);
// tracing all basic blocks with customized callback
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
// tracing one instruction at ADDRESS with customized callback
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(MIPS_CODE_EL) - 1, 0, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned: %u (%s)\n", err, uc_strerror(err));
}
// now print out some registers
printf(">>> Emulation done. Below is the CPU context\n");
uc_reg_read(uc, UC_MIPS_REG_1, &r1);
printf(">>> R1 = 0x%x\n", r1);
uc_close(uc);
}
int main(int argc, char **argv, char **envp)
{
// dynamically load shared library
#ifdef DYNLOAD
if (!uc_dyn_load(NULL, 0)) {
printf("Error dynamically loading shared library.\n");
printf("Please check that unicorn.dll/unicorn.so is available as well as\n");
printf("any other dependent dll/so files.\n");
printf("The easiest way is to place them in the same directory as this app.\n");
return 1;
}
#endif
// test memleak
while(1) {
test_mips_eb();
test_mips_el();
}
// dynamically free shared library
#ifdef DYNLOAD
uc_dyn_free();
#endif
return 0;
}

View File

@@ -1,123 +0,0 @@
/* Unicorn Emulator Engine */
/* By Nguyen Anh Quynh, 2015 */
/* Sample code to demonstrate how to emulate Sparc code */
// windows specific
#ifdef _MSC_VER
#include <io.h>
#include <windows.h>
#define PRIx64 "llX"
#ifdef DYNLOAD
#include "unicorn_dynload.h"
#else // DYNLOAD
#include <unicorn/unicorn.h>
#ifdef _WIN64
#pragma comment(lib, "unicorn_staload64.lib")
#else // _WIN64
#pragma comment(lib, "unicorn_staload.lib")
#endif // _WIN64
#endif // DYNLOAD
// posix specific
#else // _MSC_VER
#include <unicorn/unicorn.h>
#endif // _MSC_VER
// code to be emulated
#define SPARC_CODE "\x86\x00\x40\x02" // add %g1, %g2, %g3;
//#define SPARC_CODE "\xbb\x70\x00\x00" // illegal code
// memory address where emulation starts
#define ADDRESS 0x10000
static void hook_block(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
{
printf(">>> Tracing basic block at 0x%"PRIx64 ", block size = 0x%x\n", address, size);
}
static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
{
printf(">>> Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size);
}
static void test_sparc(void)
{
uc_engine *uc;
uc_err err;
uc_hook trace1, trace2;
int g1 = 0x1230; // G1 register
int g2 = 0x6789; // G2 register
int g3 = 0x5555; // G3 register
printf("Emulate SPARC code\n");
// Initialize emulator in Sparc mode
err = uc_open(UC_ARCH_SPARC, UC_MODE_SPARC32|UC_MODE_BIG_ENDIAN, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u (%s)\n",
err, uc_strerror(err));
return;
}
// map 2MB memory for this emulation
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc_mem_write(uc, ADDRESS, SPARC_CODE, sizeof(SPARC_CODE) - 1);
// initialize machine registers
uc_reg_write(uc, UC_SPARC_REG_G1, &g1);
uc_reg_write(uc, UC_SPARC_REG_G2, &g2);
uc_reg_write(uc, UC_SPARC_REG_G3, &g3);
// tracing all basic blocks with customized callback
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
// tracing all instructions with customized callback
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(SPARC_CODE) - 1, 0, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned: %u (%s)\n",
err, uc_strerror(err));
}
// now print out some registers
printf(">>> Emulation done. Below is the CPU context\n");
uc_reg_read(uc, UC_SPARC_REG_G3, &g3);
printf(">>> G3 = 0x%x\n", g3);
uc_close(uc);
}
int main(int argc, char **argv, char **envp)
{
// dynamically load shared library
#ifdef DYNLOAD
if (!uc_dyn_load(NULL, 0)) {
printf("Error dynamically loading shared library.\n");
printf("Please check that unicorn.dll/unicorn.so is available as well as\n");
printf("any other dependent dll/so files.\n");
printf("The easiest way is to place them in the same directory as this app.\n");
return 1;
}
#endif
// test memleak
while(1) {
test_sparc();
}
// dynamically free shared library
#ifdef DYNLOAD
uc_dyn_free();
#endif
return 0;
}

View File

@@ -1,304 +0,0 @@
/* Unicorn Emulator Engine */
/* By Nguyen Anh Quynh & Dang Hoang Vu, 2015 */
/* Sample code to demonstrate how to emulate X86 code */
// windows specific
#ifdef _MSC_VER
#include <io.h>
#include <windows.h>
#define PRIx64 "llX"
#ifdef DYNLOAD
#include "unicorn_dynload.h"
#else // DYNLOAD
#include <unicorn/unicorn.h>
#ifdef _WIN64
#pragma comment(lib, "unicorn_staload64.lib")
#else // _WIN64
#pragma comment(lib, "unicorn_staload.lib")
#endif // _WIN64
#endif // DYNLOAD
// posix specific
#else // _MSC_VER
#include <unicorn/unicorn.h>
#endif // _MSC_VER
// common includes
#include <string.h>
// code to be emulated
#define X86_CODE32 "\x41\x4a" // INC ecx; DEC edx
#define X86_CODE32_JUMP "\xeb\x02\x90\x90\x90\x90\x90\x90" // jmp 4; nop; nop; nop; nop; nop; nop
// #define X86_CODE32_SELF "\xeb\x1c\x5a\x89\xd6\x8b\x02\x66\x3d\xca\x7d\x75\x06\x66\x05\x03\x03\x89\x02\xfe\xc2\x3d\x41\x41\x41\x41\x75\xe9\xff\xe6\xe8\xdf\xff\xff\xff\x31\xd2\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xca\x7d\x41\x41\x41\x41"
//#define X86_CODE32 "\x51\x51\x51\x51" // PUSH ecx;
#define X86_CODE32_LOOP "\x41\x4a\xeb\xfe" // INC ecx; DEC edx; JMP self-loop
#define X86_CODE32_MEM_WRITE "\x89\x0D\xAA\xAA\xAA\xAA\x41\x4a" // mov [0xaaaaaaaa], ecx; INC ecx; DEC edx
#define X86_CODE32_MEM_READ "\x8B\x0D\xAA\xAA\xAA\xAA\x41\x4a" // mov ecx,[0xaaaaaaaa]; INC ecx; DEC edx
#define X86_CODE32_JMP_INVALID "\xe9\xe9\xee\xee\xee\x41\x4a" // JMP outside; INC ecx; DEC edx
#define X86_CODE32_INOUT "\x41\xE4\x3F\x4a\xE6\x46\x43" // INC ecx; IN AL, 0x3f; DEC edx; OUT 0x46, AL; INC ebx
//#define X86_CODE64 "\x41\xBC\x3B\xB0\x28\x2A \x49\x0F\xC9 \x90 \x4D\x0F\xAD\xCF\x49\x87\xFD\x90\x48\x81\xD2\x8A\xCE\x77\x35\x48\xF7\xD9" // <== still crash
//#define X86_CODE64 "\x41\xBC\x3B\xB0\x28\x2A\x49\x0F\xC9\x90\x4D\x0F\xAD\xCF\x49\x87\xFD\x90\x48\x81\xD2\x8A\xCE\x77\x35\x48\xF7\xD9"
#define X86_CODE64 "\x41\xBC\x3B\xB0\x28\x2A\x49\x0F\xC9\x90\x4D\x0F\xAD\xCF\x49\x87\xFD\x90\x48\x81\xD2\x8A\xCE\x77\x35\x48\xF7\xD9\x4D\x29\xF4\x49\x81\xC9\xF6\x8A\xC6\x53\x4D\x87\xED\x48\x0F\xAD\xD2\x49\xF7\xD4\x48\xF7\xE1\x4D\x19\xC5\x4D\x89\xC5\x48\xF7\xD6\x41\xB8\x4F\x8D\x6B\x59\x4D\x87\xD0\x68\x6A\x1E\x09\x3C\x59"
#define X86_CODE16 "\x00\x00" // add byte ptr [bx + si], al
#define X86_CODE64_SYSCALL "\x0f\x05" // SYSCALL
// memory address where emulation starts
#define ADDRESS 0x1000000
// callback for tracing basic blocks
static void hook_block(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
{
printf(">>> Tracing basic block at 0x%"PRIx64 ", block size = 0x%x\n", address, size);
}
// callback for tracing instruction
static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
{
int eflags;
printf(">>> Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size);
uc_reg_read(uc, UC_X86_REG_EFLAGS, &eflags);
printf(">>> --- EFLAGS is 0x%x\n", eflags);
// Uncomment below code to stop the emulation using uc_emu_stop()
// if (address == 0x1000009)
// uc_emu_stop(uc);
}
// callback for tracing instruction
static void hook_code64(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
{
uint64_t rip;
uc_reg_read(uc, UC_X86_REG_RIP, &rip);
printf(">>> Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size);
printf(">>> RIP is 0x%"PRIx64 "\n", rip);
// Uncomment below code to stop the emulation using uc_emu_stop()
// if (address == 0x1000009)
// uc_emu_stop(uc);
}
static void hook_mem64(uc_engine *uc, uc_mem_type type,
uint64_t address, int size, int64_t value, void *user_data)
{
switch(type) {
default: break;
case UC_MEM_READ:
printf(">>> Memory is being READ at 0x%"PRIx64 ", data size = %u\n",
address, size);
break;
case UC_MEM_WRITE:
printf(">>> Memory is being WRITE at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n",
address, size, value);
break;
}
}
static void test_i386(void)
{
uc_engine *uc;
uc_err err;
uint32_t tmp;
uc_hook trace1, trace2;
int r_ecx = 0x1234; // ECX register
int r_edx = 0x7890; // EDX register
printf("Emulate i386 code\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return;
}
// map 2MB memory for this emulation
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
if (uc_mem_write(uc, ADDRESS, X86_CODE32, sizeof(X86_CODE32) - 1)) {
printf("Failed to write emulation code to memory, quit!\n");
return;
}
// initialize machine registers
uc_reg_write(uc, UC_X86_REG_ECX, &r_ecx);
uc_reg_write(uc, UC_X86_REG_EDX, &r_edx);
// tracing all basic blocks with customized callback
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
// tracing all instruction by having @begin > @end
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
// emulate machine code in infinite time
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32) - 1, 0, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned %u: %s\n",
err, uc_strerror(err));
}
// now print out some registers
printf(">>> Emulation done. Below is the CPU context\n");
uc_reg_read(uc, UC_X86_REG_ECX, &r_ecx);
uc_reg_read(uc, UC_X86_REG_EDX, &r_edx);
printf(">>> ECX = 0x%x\n", r_ecx);
printf(">>> EDX = 0x%x\n", r_edx);
// read from memory
if (!uc_mem_read(uc, ADDRESS, &tmp, sizeof(tmp)))
printf(">>> Read 4 bytes from [0x%x] = 0x%x\n", ADDRESS, tmp);
else
printf(">>> Failed to read 4 bytes from [0x%x]\n", ADDRESS);
uc_close(uc);
}
static void test_x86_64(void)
{
uc_engine *uc;
uc_err err;
uc_hook trace1, trace2, trace3, trace4;
int64_t rax = 0x71f3029efd49d41d;
int64_t rbx = 0xd87b45277f133ddb;
int64_t rcx = 0xab40d1ffd8afc461;
int64_t rdx = 0x919317b4a733f01;
int64_t rsi = 0x4c24e753a17ea358;
int64_t rdi = 0xe509a57d2571ce96;
int64_t r8 = 0xea5b108cc2b9ab1f;
int64_t r9 = 0x19ec097c8eb618c1;
int64_t r10 = 0xec45774f00c5f682;
int64_t r11 = 0xe17e9dbec8c074aa;
int64_t r12 = 0x80f86a8dc0f6d457;
int64_t r13 = 0x48288ca5671c5492;
int64_t r14 = 0x595f72f6e4017f6e;
int64_t r15 = 0x1efd97aea331cccc;
int64_t rsp = ADDRESS + 0x200000;
printf("Emulate x86_64 code\n");
// Initialize emulator in X86-64bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_64, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return;
}
// map 2MB memory for this emulation
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
if (uc_mem_write(uc, ADDRESS, X86_CODE64, sizeof(X86_CODE64) - 1)) {
printf("Failed to write emulation code to memory, quit!\n");
return;
}
// initialize machine registers
uc_reg_write(uc, UC_X86_REG_RSP, &rsp);
uc_reg_write(uc, UC_X86_REG_RAX, &rax);
uc_reg_write(uc, UC_X86_REG_RBX, &rbx);
uc_reg_write(uc, UC_X86_REG_RCX, &rcx);
uc_reg_write(uc, UC_X86_REG_RDX, &rdx);
uc_reg_write(uc, UC_X86_REG_RSI, &rsi);
uc_reg_write(uc, UC_X86_REG_RDI, &rdi);
uc_reg_write(uc, UC_X86_REG_R8, &r8);
uc_reg_write(uc, UC_X86_REG_R9, &r9);
uc_reg_write(uc, UC_X86_REG_R10, &r10);
uc_reg_write(uc, UC_X86_REG_R11, &r11);
uc_reg_write(uc, UC_X86_REG_R12, &r12);
uc_reg_write(uc, UC_X86_REG_R13, &r13);
uc_reg_write(uc, UC_X86_REG_R14, &r14);
uc_reg_write(uc, UC_X86_REG_R15, &r15);
// tracing all basic blocks with customized callback
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
// tracing all instructions in the range [ADDRESS, ADDRESS+20]
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code64, NULL, (uint64_t)ADDRESS, (uint64_t)(ADDRESS+20));
// tracing all memory WRITE access (with @begin > @end)
uc_hook_add(uc, &trace3, UC_HOOK_MEM_WRITE, hook_mem64, NULL, (uint64_t)1, (uint64_t)0);
// tracing all memory READ access (with @begin > @end)
uc_hook_add(uc, &trace4, UC_HOOK_MEM_READ, hook_mem64, NULL, (uint64_t)1, (uint64_t)0);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE64) - 1, 0, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned %u: %s\n",
err, uc_strerror(err));
}
// now print out some registers
printf(">>> Emulation done. Below is the CPU context\n");
uc_reg_read(uc, UC_X86_REG_RAX, &rax);
uc_reg_read(uc, UC_X86_REG_RBX, &rbx);
uc_reg_read(uc, UC_X86_REG_RCX, &rcx);
uc_reg_read(uc, UC_X86_REG_RDX, &rdx);
uc_reg_read(uc, UC_X86_REG_RSI, &rsi);
uc_reg_read(uc, UC_X86_REG_RDI, &rdi);
uc_reg_read(uc, UC_X86_REG_R8, &r8);
uc_reg_read(uc, UC_X86_REG_R9, &r9);
uc_reg_read(uc, UC_X86_REG_R10, &r10);
uc_reg_read(uc, UC_X86_REG_R11, &r11);
uc_reg_read(uc, UC_X86_REG_R12, &r12);
uc_reg_read(uc, UC_X86_REG_R13, &r13);
uc_reg_read(uc, UC_X86_REG_R14, &r14);
uc_reg_read(uc, UC_X86_REG_R15, &r15);
printf(">>> RAX = 0x%" PRIx64 "\n", rax);
printf(">>> RBX = 0x%" PRIx64 "\n", rbx);
printf(">>> RCX = 0x%" PRIx64 "\n", rcx);
printf(">>> RDX = 0x%" PRIx64 "\n", rdx);
printf(">>> RSI = 0x%" PRIx64 "\n", rsi);
printf(">>> RDI = 0x%" PRIx64 "\n", rdi);
printf(">>> R8 = 0x%" PRIx64 "\n", r8);
printf(">>> R9 = 0x%" PRIx64 "\n", r9);
printf(">>> R10 = 0x%" PRIx64 "\n", r10);
printf(">>> R11 = 0x%" PRIx64 "\n", r11);
printf(">>> R12 = 0x%" PRIx64 "\n", r12);
printf(">>> R13 = 0x%" PRIx64 "\n", r13);
printf(">>> R14 = 0x%" PRIx64 "\n", r14);
printf(">>> R15 = 0x%" PRIx64 "\n", r15);
uc_close(uc);
}
int main(int argc, char **argv, char **envp)
{
// dynamically load shared library
#ifdef DYNLOAD
if (!uc_dyn_load(NULL, 0)) {
printf("Error dynamically loading shared library.\n");
printf("Please check that unicorn.dll/unicorn.so is available as well as\n");
printf("any other dependent dll/so files.\n");
printf("The easiest way is to place them in the same directory as this app.\n");
return 1;
}
#endif
while(1) {
test_i386();
test_x86_64();
}
// dynamically free shared library
#ifdef DYNLOAD
uc_dyn_free();
#endif
return 0;
}

13
tests/regress/mips_cp1.py Normal file
View File

@@ -0,0 +1,13 @@
from unicorn import *
from unicorn.mips_const import *
# .text:00416CB0 cfc1 $v1, FCSR
shellcode = [0x44, 0x43, 0xF8, 0x00]
base = 0x416CB0
uc = Uc(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_BIG_ENDIAN)
uc.mem_map(0x416000, 0x1000)
uc.mem_write(base, bytes(shellcode))
uc.emu_start(base, base + len(shellcode))

21
tests/regress/x86_ld_crash.py Executable file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,21 @@
from unicorn import *
from unicorn.x86_const import *
count = 0
def cb(uc, addr, sz, data):
global count
count += 1
print(f"addr: {hex(addr)} count: {count}")
if count == 5:
uc.emu_stop()
else:
uc.reg_write(UC_X86_REG_RIP, 0x2000)
mu = Uc(UC_ARCH_X86, UC_MODE_64)
mu.mem_map(0x1000, 0x4000)
mu.mem_write(0x1000, b"\x90" * 5)
mu.mem_write(0x2000, b"\x90" * 5)
mu.hook_add(UC_HOOK_CODE, cb)
mu.emu_start(0x1000, 0x2000+1, 0, 0)