Reformat code with format.sh
This commit is contained in:
parent
fa1f26138e
commit
d7a806c026
@ -403,7 +403,7 @@ struct uc_struct {
|
|||||||
uint32_t tcg_buffer_size; // The buffer size we are going to use
|
uint32_t tcg_buffer_size; // The buffer size we are going to use
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
PVOID seh_handle;
|
PVOID seh_handle;
|
||||||
void* seh_closure;
|
void *seh_closure;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -264,13 +264,15 @@ typedef enum uc_mem_type {
|
|||||||
|
|
||||||
@vaddr: virtuall address for lookup
|
@vaddr: virtuall address for lookup
|
||||||
@rw: the access mode
|
@rw: the access mode
|
||||||
@result: result entry, contains physical address (paddr) and permitted access type (perms) for the entry
|
@result: result entry, contains physical address (paddr) and permitted access
|
||||||
|
type (perms) for the entry
|
||||||
|
|
||||||
@return: return true if the entry was found. If a callback is present but
|
@return: return true if the entry was found. If a callback is present but
|
||||||
no one returns true a pagefault is generated.
|
no one returns true a pagefault is generated.
|
||||||
*/
|
*/
|
||||||
typedef bool (*uc_cb_tlbevent_t)(uc_engine *uc, uint64_t vaddr, uc_mem_type type,
|
typedef bool (*uc_cb_tlbevent_t)(uc_engine *uc, uint64_t vaddr,
|
||||||
uc_tlb_entry *result, void *user_data);
|
uc_mem_type type, uc_tlb_entry *result,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
// Represent a TranslationBlock.
|
// Represent a TranslationBlock.
|
||||||
typedef struct uc_tb {
|
typedef struct uc_tb {
|
||||||
@ -510,11 +512,12 @@ typedef enum uc_query_type {
|
|||||||
|
|
||||||
// unicorn tlb type selection
|
// unicorn tlb type selection
|
||||||
typedef enum uc_tlb_type {
|
typedef enum uc_tlb_type {
|
||||||
// The default unicorn virtuall TLB implementation.
|
// The default unicorn virtuall TLB implementation.
|
||||||
// The tlb implementation of the CPU, best to use for full system emulation.
|
// The tlb implementation of the CPU, best to use for full system emulation.
|
||||||
UC_TLB_CPU = 0,
|
UC_TLB_CPU = 0,
|
||||||
// This tlb defaults to virtuall address == physical address
|
// This tlb defaults to virtuall address == physical address
|
||||||
// Also a hook is availible to override the tlb entries (see uc_cb_tlbevent_t).
|
// Also a hook is availible to override the tlb entries (see
|
||||||
|
// uc_cb_tlbevent_t).
|
||||||
UC_TLB_VIRTUAL
|
UC_TLB_VIRTUAL
|
||||||
} uc_tlb_type;
|
} uc_tlb_type;
|
||||||
|
|
||||||
@ -652,7 +655,8 @@ See sample_ctl.c for a detailed example.
|
|||||||
uc_ctl(uc, UC_CTL_READ_WRITE(UC_CTL_TB_REQUEST_CACHE, 2), (address), (tb))
|
uc_ctl(uc, UC_CTL_READ_WRITE(UC_CTL_TB_REQUEST_CACHE, 2), (address), (tb))
|
||||||
#define uc_ctl_flush_tb(uc) uc_ctl(uc, UC_CTL_WRITE(UC_CTL_TB_FLUSH, 0))
|
#define uc_ctl_flush_tb(uc) uc_ctl(uc, UC_CTL_WRITE(UC_CTL_TB_FLUSH, 0))
|
||||||
#define uc_ctl_flush_tlb(uc) uc_ctl(uc, UC_CTL_WRITE(UC_CTL_TLB_FLUSH, 0))
|
#define uc_ctl_flush_tlb(uc) uc_ctl(uc, UC_CTL_WRITE(UC_CTL_TLB_FLUSH, 0))
|
||||||
#define uc_ctl_tlb_mode(uc, mode) uc_ctl(uc, UC_CTL_WRITE(UC_CTL_TLB_TYPE, 1), (mode))
|
#define uc_ctl_tlb_mode(uc, mode) \
|
||||||
|
uc_ctl(uc, UC_CTL_WRITE(UC_CTL_TLB_TYPE, 1), (mode))
|
||||||
#define uc_ctl_get_tcg_buffer_size(uc, size) \
|
#define uc_ctl_get_tcg_buffer_size(uc, size) \
|
||||||
uc_ctl(uc, UC_CTL_READ(UC_CTL_TCG_BUFFER_SIZE, 1), (size))
|
uc_ctl(uc, UC_CTL_READ(UC_CTL_TCG_BUFFER_SIZE, 1), (size))
|
||||||
#define uc_ctl_set_tcg_buffer_size(uc, size) \
|
#define uc_ctl_set_tcg_buffer_size(uc, size) \
|
||||||
|
@ -986,7 +986,7 @@ static int reg_write(CPUX86State *env, unsigned int regid, const void *value,
|
|||||||
goto write_cr;
|
goto write_cr;
|
||||||
case UC_X86_REG_CR4:
|
case UC_X86_REG_CR4:
|
||||||
cpu_x86_update_cr4(env, *(uint32_t *)value);
|
cpu_x86_update_cr4(env, *(uint32_t *)value);
|
||||||
write_cr:
|
write_cr:
|
||||||
env->cr[regid - UC_X86_REG_CR0] = *(uint32_t *)value;
|
env->cr[regid - UC_X86_REG_CR0] = *(uint32_t *)value;
|
||||||
break;
|
break;
|
||||||
case UC_X86_REG_DR0:
|
case UC_X86_REG_DR0:
|
||||||
@ -1169,16 +1169,16 @@ write_cr:
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
case UC_X86_REG_CR0:
|
case UC_X86_REG_CR0:
|
||||||
cpu_x86_update_cr0(env, *(uint32_t *) value);
|
cpu_x86_update_cr0(env, *(uint32_t *)value);
|
||||||
goto write_cr64;
|
goto write_cr64;
|
||||||
case UC_X86_REG_CR1:
|
case UC_X86_REG_CR1:
|
||||||
case UC_X86_REG_CR2:
|
case UC_X86_REG_CR2:
|
||||||
case UC_X86_REG_CR3:
|
case UC_X86_REG_CR3:
|
||||||
cpu_x86_update_cr3(env, *(uint32_t *) value);
|
cpu_x86_update_cr3(env, *(uint32_t *)value);
|
||||||
goto write_cr64;
|
goto write_cr64;
|
||||||
case UC_X86_REG_CR4:
|
case UC_X86_REG_CR4:
|
||||||
cpu_x86_update_cr4(env, *(uint32_t *) value);
|
cpu_x86_update_cr4(env, *(uint32_t *)value);
|
||||||
write_cr64:
|
write_cr64:
|
||||||
env->cr[regid - UC_X86_REG_CR0] = *(uint64_t *)value;
|
env->cr[regid - UC_X86_REG_CR0] = *(uint64_t *)value;
|
||||||
break;
|
break;
|
||||||
case UC_X86_REG_DR0:
|
case UC_X86_REG_DR0:
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
#define ARM64_CODE \
|
#define ARM64_CODE \
|
||||||
"\xab\x05\x00\xb8\xaf\x05\x40\x38" // str w11, [x13], #0; ldrb w15, [x13],
|
"\xab\x05\x00\xb8\xaf\x05\x40\x38" // str w11, [x13], #0; ldrb w15, [x13],
|
||||||
// #0
|
// #0
|
||||||
//#define ARM64_CODE_EB "\xb8\x00\x05\xab\x38\x40\x05\xaf" // str w11, [x13];
|
// #define ARM64_CODE_EB "\xb8\x00\x05\xab\x38\x40\x05\xaf" // str w11, [x13];
|
||||||
// ldrb w15, [x13]
|
// ldrb w15, [x13]
|
||||||
#define ARM64_CODE_EB ARM64_CODE
|
#define ARM64_CODE_EB ARM64_CODE
|
||||||
|
|
||||||
// mrs x2, tpidrro_el0
|
// mrs x2, tpidrro_el0
|
||||||
|
@ -18,25 +18,30 @@
|
|||||||
* mov rax, 60
|
* mov rax, 60
|
||||||
* syscall
|
* syscall
|
||||||
*/
|
*/
|
||||||
char code[] = "\xB8\x39\x00\x00\x00\x0F\x05\x48\x85\xC0\x74\x0F\xB8\x3C\x00\x00\x00\x48\x89\x04\x25\x00\x40\x00\x00\x0F\x05\xB9\x2A\x00\x00\x00\x48\x89\x0C\x25\x00\x40\x00\x00\xB8\x3C\x00\x00\x00\x0F\x05";
|
char code[] = "\xB8\x39\x00\x00\x00\x0F\x05\x48\x85\xC0\x74\x0F\xB8\x3C\x00\x00"
|
||||||
|
"\x00\x48\x89\x04\x25\x00\x40\x00\x00\x0F\x05\xB9\x2A\x00\x00\x00"
|
||||||
|
"\x48\x89\x0C\x25\x00\x40\x00\x00\xB8\x3C\x00\x00\x00\x0F\x05";
|
||||||
|
|
||||||
static void mmu_write_callback(uc_engine *uc, uc_mem_type type, uint64_t address, int size, int64_t value, void *user_data)
|
static void mmu_write_callback(uc_engine *uc, uc_mem_type type,
|
||||||
|
uint64_t address, int size, int64_t value,
|
||||||
|
void *user_data)
|
||||||
{
|
{
|
||||||
printf("write at 0x%lx: 0x%lx\n", address, value);
|
printf("write at 0x%lx: 0x%lx\n", address, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void x86_mmu_prepare_tlb(uc_engine *uc, uint64_t vaddr, uint64_t tlb_base)
|
static void x86_mmu_prepare_tlb(uc_engine *uc, uint64_t vaddr,
|
||||||
|
uint64_t tlb_base)
|
||||||
{
|
{
|
||||||
uc_err err;
|
uc_err err;
|
||||||
uint64_t cr0;
|
uint64_t cr0;
|
||||||
uint64_t cr4;
|
uint64_t cr4;
|
||||||
uc_x86_msr msr = {.rid = 0xC0000080, .value = 0};
|
uc_x86_msr msr = {.rid = 0xC0000080, .value = 0};
|
||||||
uint64_t pml4o = ((vaddr & 0x00ff8000000000) >> 39)*8;
|
uint64_t pml4o = ((vaddr & 0x00ff8000000000) >> 39) * 8;
|
||||||
uint64_t pdpo = ((vaddr & 0x00007fc0000000) >> 30)*8;
|
uint64_t pdpo = ((vaddr & 0x00007fc0000000) >> 30) * 8;
|
||||||
uint64_t pdo = ((vaddr & 0x0000003fe00000) >> 21)*8;
|
uint64_t pdo = ((vaddr & 0x0000003fe00000) >> 21) * 8;
|
||||||
uint64_t pml4e = (tlb_base + 0x1000) | 1 | (1 << 2);
|
uint64_t pml4e = (tlb_base + 0x1000) | 1 | (1 << 2);
|
||||||
uint64_t pdpe = (tlb_base + 0x2000) | 1 | (1 << 2);
|
uint64_t pdpe = (tlb_base + 0x2000) | 1 | (1 << 2);
|
||||||
uint64_t pde = (tlb_base + 0x3000) | 1 | (1 << 2);
|
uint64_t pde = (tlb_base + 0x3000) | 1 | (1 << 2);
|
||||||
err = uc_mem_write(uc, tlb_base + pml4o, &pml4e, sizeof(pml4o));
|
err = uc_mem_write(uc, tlb_base + pml4o, &pml4e, sizeof(pml4o));
|
||||||
if (err) {
|
if (err) {
|
||||||
printf("failed to write pml4e\n");
|
printf("failed to write pml4e\n");
|
||||||
@ -73,10 +78,10 @@ static void x86_mmu_prepare_tlb(uc_engine *uc, uint64_t vaddr, uint64_t tlb_base
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
cr0 |= 1; //enable protected mode
|
cr0 |= 1; // enable protected mode
|
||||||
cr0 |= 1l << 31; //enable paging
|
cr0 |= 1l << 31; // enable paging
|
||||||
cr4 |= 1l << 5; //enable physical address extension
|
cr4 |= 1l << 5; // enable physical address extension
|
||||||
msr.value |= 1l << 8; //enable long mode
|
msr.value |= 1l << 8; // enable long mode
|
||||||
|
|
||||||
err = uc_reg_write(uc, UC_X86_REG_CR0, &cr0);
|
err = uc_reg_write(uc, UC_X86_REG_CR0, &cr0);
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -95,10 +100,11 @@ static void x86_mmu_prepare_tlb(uc_engine *uc, uint64_t vaddr, uint64_t tlb_base
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void x86_mmu_pt_set(uc_engine *uc, uint64_t vaddr, uint64_t paddr, uint64_t tlb_base)
|
static void x86_mmu_pt_set(uc_engine *uc, uint64_t vaddr, uint64_t paddr,
|
||||||
|
uint64_t tlb_base)
|
||||||
{
|
{
|
||||||
uint64_t pto = ((vaddr & 0x000000001ff000) >> 12)*8;
|
uint64_t pto = ((vaddr & 0x000000001ff000) >> 12) * 8;
|
||||||
uint32_t pte = (paddr) | 1 | (1 << 2);
|
uint32_t pte = (paddr) | 1 | (1 << 2);
|
||||||
uc_mem_write(uc, tlb_base + 0x3000 + pto, &pte, sizeof(pte));
|
uc_mem_write(uc, tlb_base + 0x3000 + pto, &pte, sizeof(pte));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,20 +168,23 @@ void cpu_tlb(void)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = uc_hook_add(uc, &h1, UC_HOOK_INSN, &x86_mmu_syscall_callback, &parrent_done, 1, 0, UC_X86_INS_SYSCALL);
|
err = uc_hook_add(uc, &h1, UC_HOOK_INSN, &x86_mmu_syscall_callback,
|
||||||
|
&parrent_done, 1, 0, UC_X86_INS_SYSCALL);
|
||||||
if (err) {
|
if (err) {
|
||||||
printf("Failed on uc_hook_add() with error returned: %u\n", err);
|
printf("Failed on uc_hook_add() with error returned: %u\n", err);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Memory hooks are called after the mmu translation, so hook the physicall addresses
|
// Memory hooks are called after the mmu translation, so hook the physicall
|
||||||
err = uc_hook_add(uc, &h2, UC_HOOK_MEM_WRITE, &mmu_write_callback, NULL, 0x1000, 0x3000);
|
// addresses
|
||||||
|
err = uc_hook_add(uc, &h2, UC_HOOK_MEM_WRITE, &mmu_write_callback, NULL,
|
||||||
|
0x1000, 0x3000);
|
||||||
if (err) {
|
if (err) {
|
||||||
printf("Faled on uc_hook_add() with error returned: %u\n", err);
|
printf("Faled on uc_hook_add() with error returned: %u\n", err);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("map code\n");
|
printf("map code\n");
|
||||||
err = uc_mem_map(uc, 0x0, 0x1000, UC_PROT_ALL); //Code
|
err = uc_mem_map(uc, 0x0, 0x1000, UC_PROT_ALL); // Code
|
||||||
if (err) {
|
if (err) {
|
||||||
printf("Failed on uc_mem_map() with error return: %u\n", err);
|
printf("Failed on uc_mem_map() with error return: %u\n", err);
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -186,25 +195,24 @@ void cpu_tlb(void)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
printf("map parrent memory\n");
|
printf("map parrent memory\n");
|
||||||
err = uc_mem_map(uc, 0x1000, 0x1000, UC_PROT_ALL); //Parrent
|
err = uc_mem_map(uc, 0x1000, 0x1000, UC_PROT_ALL); // Parrent
|
||||||
if (err) {
|
if (err) {
|
||||||
printf("Failed on uc_mem_map() with error return: %u\n", err);
|
printf("Failed on uc_mem_map() with error return: %u\n", err);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
printf("map child memory\n");
|
printf("map child memory\n");
|
||||||
err = uc_mem_map(uc, 0x2000, 0x1000, UC_PROT_ALL); //Child
|
err = uc_mem_map(uc, 0x2000, 0x1000, UC_PROT_ALL); // Child
|
||||||
if (err) {
|
if (err) {
|
||||||
printf("failed to map child memory\n");
|
printf("failed to map child memory\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
printf("map tlb memory\n");
|
printf("map tlb memory\n");
|
||||||
err = uc_mem_map(uc, tlb_base, 0x4000, UC_PROT_ALL); //TLB
|
err = uc_mem_map(uc, tlb_base, 0x4000, UC_PROT_ALL); // TLB
|
||||||
if (err) {
|
if (err) {
|
||||||
printf("failed to map memory for tlb\n");
|
printf("failed to map memory for tlb\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
printf("set up the tlb\n");
|
printf("set up the tlb\n");
|
||||||
x86_mmu_prepare_tlb(uc, 0x0, tlb_base);
|
x86_mmu_prepare_tlb(uc, 0x0, tlb_base);
|
||||||
x86_mmu_pt_set(uc, 0x2000, 0x0, tlb_base);
|
x86_mmu_pt_set(uc, 0x2000, 0x0, tlb_base);
|
||||||
@ -277,7 +285,8 @@ void cpu_tlb(void)
|
|||||||
uc_close(uc);
|
uc_close(uc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool virtual_tlb_callback(uc_engine *uc, uint64_t addr, uc_mem_type type, uc_tlb_entry *result, void *user_data)
|
static bool virtual_tlb_callback(uc_engine *uc, uint64_t addr, uc_mem_type type,
|
||||||
|
uc_tlb_entry *result, void *user_data)
|
||||||
{
|
{
|
||||||
bool *parrent_done = user_data;
|
bool *parrent_done = user_data;
|
||||||
printf("tlb lookup for address: 0x%lX\n", addr);
|
printf("tlb lookup for address: 0x%lX\n", addr);
|
||||||
@ -324,20 +333,23 @@ void virtual_tlb(void)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = uc_hook_add(uc, &h1, UC_HOOK_INSN, &x86_mmu_syscall_callback, &parrent_done, 1, 0, UC_X86_INS_SYSCALL);
|
err = uc_hook_add(uc, &h1, UC_HOOK_INSN, &x86_mmu_syscall_callback,
|
||||||
|
&parrent_done, 1, 0, UC_X86_INS_SYSCALL);
|
||||||
if (err) {
|
if (err) {
|
||||||
printf("Failed on uc_hook_add() with error returned: %u\n", err);
|
printf("Failed on uc_hook_add() with error returned: %u\n", err);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Memory hooks are called after the mmu translation, so hook the physicall addresses
|
// Memory hooks are called after the mmu translation, so hook the physicall
|
||||||
err = uc_hook_add(uc, &h2, UC_HOOK_MEM_WRITE, &mmu_write_callback, NULL, 0x1000, 0x3000);
|
// addresses
|
||||||
|
err = uc_hook_add(uc, &h2, UC_HOOK_MEM_WRITE, &mmu_write_callback, NULL,
|
||||||
|
0x1000, 0x3000);
|
||||||
if (err) {
|
if (err) {
|
||||||
printf("Faled on uc_hook_add() with error returned: %u\n", err);
|
printf("Faled on uc_hook_add() with error returned: %u\n", err);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("map code\n");
|
printf("map code\n");
|
||||||
err = uc_mem_map(uc, 0x0, 0x1000, UC_PROT_ALL); //Code
|
err = uc_mem_map(uc, 0x0, 0x1000, UC_PROT_ALL); // Code
|
||||||
if (err) {
|
if (err) {
|
||||||
printf("Failed on uc_mem_map() with error return: %u\n", err);
|
printf("Failed on uc_mem_map() with error return: %u\n", err);
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -348,19 +360,20 @@ void virtual_tlb(void)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
printf("map parrent memory\n");
|
printf("map parrent memory\n");
|
||||||
err = uc_mem_map(uc, 0x1000, 0x1000, UC_PROT_ALL); //Parrent
|
err = uc_mem_map(uc, 0x1000, 0x1000, UC_PROT_ALL); // Parrent
|
||||||
if (err) {
|
if (err) {
|
||||||
printf("Failed on uc_mem_map() with error return: %u\n", err);
|
printf("Failed on uc_mem_map() with error return: %u\n", err);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
printf("map child memory\n");
|
printf("map child memory\n");
|
||||||
err = uc_mem_map(uc, 0x2000, 0x1000, UC_PROT_ALL); //Child
|
err = uc_mem_map(uc, 0x2000, 0x1000, UC_PROT_ALL); // Child
|
||||||
if (err) {
|
if (err) {
|
||||||
printf("failed to map child memory\n");
|
printf("failed to map child memory\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = uc_hook_add(uc, &h3, UC_HOOK_TLB_FILL, virtual_tlb_callback, &parrent_done, 1, 0);
|
err = uc_hook_add(uc, &h3, UC_HOOK_TLB_FILL, virtual_tlb_callback,
|
||||||
|
&parrent_done, 1, 0);
|
||||||
|
|
||||||
printf("run the parrent\n");
|
printf("run the parrent\n");
|
||||||
err = uc_emu_start(uc, 0x2000, 0x0, 0, 0);
|
err = uc_emu_start(uc, 0x2000, 0x0, 0, 0);
|
||||||
|
@ -11,7 +11,7 @@ $ cstool riscv64 1305100093850502
|
|||||||
0 13 05 10 00 addi a0, zero, 1
|
0 13 05 10 00 addi a0, zero, 1
|
||||||
4 93 85 05 02 addi a1, a1, 0x20
|
4 93 85 05 02 addi a1, a1, 0x20
|
||||||
#endif
|
#endif
|
||||||
//#define RISCV_CODE "\x13\x05\x10\x00\x93\x85\x05\x02\x93\x85\x05\x02"
|
// #define RISCV_CODE "\x13\x05\x10\x00\x93\x85\x05\x02\x93\x85\x05\x02"
|
||||||
#define RISCV_CODE "\x13\x05\x10\x00\x93\x85\x05\x02"
|
#define RISCV_CODE "\x13\x05\x10\x00\x93\x85\x05\x02"
|
||||||
|
|
||||||
// memory address where emulation starts
|
// memory address where emulation starts
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
// code to be emulated
|
// code to be emulated
|
||||||
#define SPARC_CODE "\x86\x00\x40\x02" // add %g1, %g2, %g3;
|
#define SPARC_CODE "\x86\x00\x40\x02" // add %g1, %g2, %g3;
|
||||||
//#define SPARC_CODE "\xbb\x70\x00\x00" // illegal code
|
// #define SPARC_CODE "\xbb\x70\x00\x00" // illegal code
|
||||||
|
|
||||||
// memory address where emulation starts
|
// memory address where emulation starts
|
||||||
#define ADDRESS 0x10000
|
#define ADDRESS 0x10000
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
"\xeb\x02\x90\x90\x90\x90\x90\x90" // jmp 4; nop; nop; nop; nop; nop; nop
|
"\xeb\x02\x90\x90\x90\x90\x90\x90" // jmp 4; nop; nop; nop; nop; nop; nop
|
||||||
// #define X86_CODE32_SELF
|
// #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"
|
// "\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 "\x51\x51\x51\x51" // PUSH ecx;
|
||||||
#define X86_CODE32_LOOP "\x41\x4a\xeb\xfe" // INC ecx; DEC edx; JMP self-loop
|
#define X86_CODE32_LOOP "\x41\x4a\xeb\xfe" // INC ecx; DEC edx; JMP self-loop
|
||||||
#define X86_CODE32_MEM_WRITE \
|
#define X86_CODE32_MEM_WRITE \
|
||||||
"\x89\x0D\xAA\xAA\xAA\xAA\x41\x4a" // mov [0xaaaaaaaa], ecx; INC ecx; DEC
|
"\x89\x0D\xAA\xAA\xAA\xAA\x41\x4a" // mov [0xaaaaaaaa], ecx; INC ecx; DEC
|
||||||
@ -30,7 +30,7 @@
|
|||||||
// AL; INC ebx
|
// AL; INC ebx
|
||||||
#define X86_CODE32_INC "\x40" // INC eax
|
#define X86_CODE32_INC "\x40" // INC eax
|
||||||
|
|
||||||
//#define X86_CODE64 "\x41\xBC\x3B\xB0\x28\x2A \x49\x0F\xC9 \x90
|
// #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\x0F\xAD\xCF\x49\x87\xFD\x90\x48\x81\xD2\x8A\xCE\x77\x35\x48\xF7\xD9" //
|
||||||
//<== still crash #define X86_CODE64
|
//<== 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"
|
//"\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"
|
||||||
|
@ -270,7 +270,8 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
|
||||||
#if defined(unix) || defined(__unix__) || defined(__unix) || defined(__APPLE__) || defined(__HAIKU__)
|
#if defined(unix) || defined(__unix__) || defined(__unix) || \
|
||||||
|
defined(__APPLE__) || defined(__HAIKU__)
|
||||||
#define ACUTEST_UNIX_ 1
|
#define ACUTEST_UNIX_ 1
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
|
@ -32,53 +32,47 @@
|
|||||||
// GNU libc offers the helpful header <endian.h> which defines
|
// GNU libc offers the helpful header <endian.h> which defines
|
||||||
// __BYTE_ORDER
|
// __BYTE_ORDER
|
||||||
|
|
||||||
#if defined (__GLIBC__)
|
#if defined(__GLIBC__)
|
||||||
# include <endian.h>
|
#include <endian.h>
|
||||||
# if (__BYTE_ORDER == __LITTLE_ENDIAN)
|
#if (__BYTE_ORDER == __LITTLE_ENDIAN)
|
||||||
# define BOOST_LITTLE_ENDIAN
|
#define BOOST_LITTLE_ENDIAN
|
||||||
# elif (__BYTE_ORDER == __BIG_ENDIAN)
|
#elif (__BYTE_ORDER == __BIG_ENDIAN)
|
||||||
# define BOOST_BIG_ENDIAN
|
#define BOOST_BIG_ENDIAN
|
||||||
# elif (__BYTE_ORDER == __PDP_ENDIAN)
|
#elif (__BYTE_ORDER == __PDP_ENDIAN)
|
||||||
# define BOOST_PDP_ENDIAN
|
#define BOOST_PDP_ENDIAN
|
||||||
# else
|
#else
|
||||||
// Failsafe
|
// Failsafe
|
||||||
# define BOOST_LITTLE_ENDIAN
|
#define BOOST_LITTLE_ENDIAN
|
||||||
# endif
|
#endif
|
||||||
# define BOOST_BYTE_ORDER __BYTE_ORDER
|
#define BOOST_BYTE_ORDER __BYTE_ORDER
|
||||||
#elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)
|
#elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)
|
||||||
# define BOOST_BIG_ENDIAN
|
#define BOOST_BIG_ENDIAN
|
||||||
# define BOOST_BYTE_ORDER 4321
|
#define BOOST_BYTE_ORDER 4321
|
||||||
#elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
|
#elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
|
||||||
# define BOOST_LITTLE_ENDIAN
|
#define BOOST_LITTLE_ENDIAN
|
||||||
# define BOOST_BYTE_ORDER 1234
|
#define BOOST_BYTE_ORDER 1234
|
||||||
// https://developer.arm.com/documentation/dui0491/i/Compiler-specific-Features/Predefined-macros
|
// https://developer.arm.com/documentation/dui0491/i/Compiler-specific-Features/Predefined-macros
|
||||||
#elif defined(__sparc) || defined(__sparc__) \
|
#elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || \
|
||||||
|| defined(_POWER) || defined(__powerpc__) \
|
defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || \
|
||||||
|| defined(__ppc__) || defined(__hpux) || defined(__hppa) \
|
defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || \
|
||||||
|| defined(_MIPSEB) || defined(_POWER) \
|
defined(__s390__) || defined(__ARMEB__) || defined(__AARCH64EB__) || \
|
||||||
|| defined(__s390__) \
|
defined(__BIG_ENDIAN) || defined(__ARM_BIG_ENDIAN)
|
||||||
|| defined(__ARMEB__) || defined(__AARCH64EB__) \
|
#define BOOST_BIG_ENDIAN
|
||||||
|| defined(__BIG_ENDIAN) || defined(__ARM_BIG_ENDIAN)
|
#define BOOST_BYTE_ORDER 4321
|
||||||
# define BOOST_BIG_ENDIAN
|
#elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || \
|
||||||
# define BOOST_BYTE_ORDER 4321
|
defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || \
|
||||||
#elif defined(__i386__) || defined(__alpha__) \
|
defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || \
|
||||||
|| defined(__ia64) || defined(__ia64__) \
|
defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || \
|
||||||
|| defined(_M_IX86) || defined(_M_IA64) \
|
defined(_M_X64) || defined(__bfin__) || defined(__ARMEL__) || \
|
||||||
|| defined(_M_ALPHA) || defined(__amd64) \
|
defined(__AARCH64EL__) || defined(__arm64__) || defined(__arm__)
|
||||||
|| defined(__amd64__) || defined(_M_AMD64) \
|
#define BOOST_LITTLE_ENDIAN
|
||||||
|| defined(__x86_64) || defined(__x86_64__) \
|
#define BOOST_BYTE_ORDER 1234
|
||||||
|| defined(_M_X64) || defined(__bfin__) \
|
|
||||||
|| defined(__ARMEL__) || defined(__AARCH64EL__) \
|
|
||||||
|| defined(__arm64__) || defined(__arm__)
|
|
||||||
# define BOOST_LITTLE_ENDIAN
|
|
||||||
# define BOOST_BYTE_ORDER 1234
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
// Failsafe
|
// Failsafe
|
||||||
# define BOOST_LITTLE_ENDIAN
|
#define BOOST_LITTLE_ENDIAN
|
||||||
# define BOOST_BYTE_ORDER 1234
|
#define BOOST_BYTE_ORDER 1234
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -380,7 +380,8 @@ static void test_arm64_mmu(void)
|
|||||||
char tlbe[8];
|
char tlbe[8];
|
||||||
uint64_t x0, x1, x2;
|
uint64_t x0, x1, x2;
|
||||||
/*
|
/*
|
||||||
* Not exact the binary, but aarch64-linux-gnu-as generate this code and reference sometimes data after ttb0_base.
|
* Not exact the binary, but aarch64-linux-gnu-as generate this code and
|
||||||
|
reference sometimes data after ttb0_base.
|
||||||
* // Read data from physical address
|
* // Read data from physical address
|
||||||
* ldr X0, =0x40000000
|
* ldr X0, =0x40000000
|
||||||
* ldr X1, [X0]
|
* ldr X1, [X0]
|
||||||
@ -411,7 +412,12 @@ static void test_arm64_mmu(void)
|
|||||||
* // Stop
|
* // Stop
|
||||||
* b .
|
* b .
|
||||||
*/
|
*/
|
||||||
char code[] = "\x00\x81\x00\x58\x01\x00\x40\xf9\x00\x81\x00\x58\x40\x20\x18\xd5\x00\x81\x00\x58\x00\xa2\x18\xd5\x40\x7f\x00\x10\x00\x20\x18\xd5\x00\x10\x38\xd5\x00\x00\x7e\xb2\x00\x00\x74\xb2\x00\x00\x40\xb2\x00\x10\x18\xd5\x9f\x3f\x03\xd5\xdf\x3f\x03\xd5\xe0\x7f\x00\x58\x02\x00\x40\xf9\x00\x00\x00\x14\x1f\x20\x03\xd5\x1f\x20\x03\xd5\x1F\x20\x03\xD5\x1F\x20\x03\xD5";
|
char code[] = "\x00\x81\x00\x58\x01\x00\x40\xf9\x00\x81\x00\x58\x40\x20\x18"
|
||||||
|
"\xd5\x00\x81\x00\x58\x00\xa2\x18\xd5\x40\x7f\x00\x10\x00\x20"
|
||||||
|
"\x18\xd5\x00\x10\x38\xd5\x00\x00\x7e\xb2\x00\x00\x74\xb2\x00"
|
||||||
|
"\x00\x40\xb2\x00\x10\x18\xd5\x9f\x3f\x03\xd5\xdf\x3f\x03\xd5"
|
||||||
|
"\xe0\x7f\x00\x58\x02\x00\x40\xf9\x00\x00\x00\x14\x1f\x20\x03"
|
||||||
|
"\xd5\x1f\x20\x03\xd5\x1F\x20\x03\xD5\x1F\x20\x03\xD5";
|
||||||
|
|
||||||
data = malloc(0x1000);
|
data = malloc(0x1000);
|
||||||
TEST_CHECK(data != NULL);
|
TEST_CHECK(data != NULL);
|
||||||
@ -436,7 +442,7 @@ static void test_arm64_mmu(void)
|
|||||||
OK(uc_mem_write(uc, 0x1010, tlbe, sizeof(tlbe)));
|
OK(uc_mem_write(uc, 0x1010, tlbe, sizeof(tlbe)));
|
||||||
OK(uc_mem_write(uc, 0x1018, tlbe, sizeof(tlbe)));
|
OK(uc_mem_write(uc, 0x1018, tlbe, sizeof(tlbe)));
|
||||||
|
|
||||||
//mentioned data referenced by the asm generated my aarch64-linux-gnu-as
|
// mentioned data referenced by the asm generated my aarch64-linux-gnu-as
|
||||||
tlbe[0] = 0;
|
tlbe[0] = 0;
|
||||||
tlbe[1] = 0;
|
tlbe[1] = 0;
|
||||||
OK(uc_mem_write(uc, 0x1020, tlbe, sizeof(tlbe)));
|
OK(uc_mem_write(uc, 0x1020, tlbe, sizeof(tlbe)));
|
||||||
@ -500,7 +506,7 @@ static void test_arm64_pc_wrap(void)
|
|||||||
|
|
||||||
OK(uc_reg_read(uc, UC_ARM64_REG_X0, &x0));
|
OK(uc_reg_read(uc, UC_ARM64_REG_X0, &x0));
|
||||||
|
|
||||||
TEST_CHECK( (x0 == 1 + 2) );
|
TEST_CHECK((x0 == 1 + 2));
|
||||||
|
|
||||||
OK(uc_mem_map(uc, page, 4096, UC_PROT_READ | UC_PROT_EXEC));
|
OK(uc_mem_map(uc, page, 4096, UC_PROT_READ | UC_PROT_EXEC));
|
||||||
OK(uc_mem_write(uc, pc, add_x1_x3, sizeof(add_x1_x3) - 1));
|
OK(uc_mem_write(uc, pc, add_x1_x3, sizeof(add_x1_x3) - 1));
|
||||||
@ -518,7 +524,7 @@ static void test_arm64_pc_wrap(void)
|
|||||||
|
|
||||||
OK(uc_reg_read(uc, UC_ARM64_REG_X0, &x0));
|
OK(uc_reg_read(uc, UC_ARM64_REG_X0, &x0));
|
||||||
|
|
||||||
TEST_CHECK( (x0 == 5 + 5) );
|
TEST_CHECK((x0 == 5 + 5));
|
||||||
|
|
||||||
OK(uc_close(uc));
|
OK(uc_close(uc));
|
||||||
}
|
}
|
||||||
@ -536,6 +542,6 @@ TEST_LIST = {{"test_arm64_until", test_arm64_until},
|
|||||||
{"test_arm64_block_sync_pc", test_arm64_block_sync_pc},
|
{"test_arm64_block_sync_pc", test_arm64_block_sync_pc},
|
||||||
{"test_arm64_block_invalid_mem_read_write_sync",
|
{"test_arm64_block_invalid_mem_read_write_sync",
|
||||||
test_arm64_block_invalid_mem_read_write_sync},
|
test_arm64_block_invalid_mem_read_write_sync},
|
||||||
{"test_arm64_mmu", test_arm64_mmu},
|
{"test_arm64_mmu", test_arm64_mmu},
|
||||||
{"test_arm64_pc_wrap", test_arm64_pc_wrap},
|
{"test_arm64_pc_wrap", test_arm64_pc_wrap},
|
||||||
{NULL, NULL}};
|
{NULL, NULL}};
|
||||||
|
@ -304,7 +304,8 @@ static void test_uc_hook_cached_uaf(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_uc_emu_stop_set_ip_callback(uc_engine *uc, uint64_t address, uint32_t size, void *userdata)
|
static void test_uc_emu_stop_set_ip_callback(uc_engine *uc, uint64_t address,
|
||||||
|
uint32_t size, void *userdata)
|
||||||
{
|
{
|
||||||
uint64_t rip = code_start + 0xb;
|
uint64_t rip = code_start + 0xb;
|
||||||
|
|
||||||
@ -320,27 +321,31 @@ static void test_uc_emu_stop_set_ip(void)
|
|||||||
uc_hook h;
|
uc_hook h;
|
||||||
uint64_t rip;
|
uint64_t rip;
|
||||||
|
|
||||||
char code[] = "\x48\x31\xc0" // 0x0 xor rax, rax : rax = 0
|
char code[] =
|
||||||
"\x90" // 0x3 nop :
|
"\x48\x31\xc0" // 0x0 xor rax, rax : rax = 0
|
||||||
"\x48\xff\xc0" // 0x4 inc rax : rax++
|
"\x90" // 0x3 nop :
|
||||||
"\x90" // 0x7 nop : <-- going to stop here
|
"\x48\xff\xc0" // 0x4 inc rax : rax++
|
||||||
"\x48\xff\xc0" // 0x8 inc rax : rax++
|
"\x90" // 0x7 nop : <-- going to stop here
|
||||||
"\x90" // 0xb nop :
|
"\x48\xff\xc0" // 0x8 inc rax : rax++
|
||||||
"\x0f\x0b" // 0xc ud2 : <-- will raise UC_ERR_INSN_INVALID, but should not never be reached
|
"\x90" // 0xb nop :
|
||||||
"\x90" // 0xe nop :
|
"\x0f\x0b" // 0xc ud2 : <-- will raise
|
||||||
"\x90"; // 0xf nop :
|
// UC_ERR_INSN_INVALID, but should not never be reached
|
||||||
|
"\x90" // 0xe nop :
|
||||||
|
"\x90"; // 0xf nop :
|
||||||
|
|
||||||
uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_64, code, sizeof(code) - 1);
|
uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_64, code, sizeof(code) - 1);
|
||||||
OK(uc_hook_add(uc, &h, UC_HOOK_CODE, test_uc_emu_stop_set_ip_callback, NULL, 1, 0));
|
OK(uc_hook_add(uc, &h, UC_HOOK_CODE, test_uc_emu_stop_set_ip_callback, NULL,
|
||||||
|
1, 0));
|
||||||
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
|
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
|
||||||
OK(uc_reg_read(uc, UC_X86_REG_RIP, &rip));
|
OK(uc_reg_read(uc, UC_X86_REG_RIP, &rip));
|
||||||
TEST_CHECK(rip == code_start + 0xb);
|
TEST_CHECK(rip == code_start + 0xb);
|
||||||
OK(uc_close(uc));
|
OK(uc_close(uc));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool test_tlb_clear_tlb(uc_engine *uc, uint64_t addr, uc_mem_type type, uc_tlb_entry *result, void *user_data)
|
static bool test_tlb_clear_tlb(uc_engine *uc, uint64_t addr, uc_mem_type type,
|
||||||
|
uc_tlb_entry *result, void *user_data)
|
||||||
{
|
{
|
||||||
size_t *tlbcount = (size_t*)user_data;
|
size_t *tlbcount = (size_t *)user_data;
|
||||||
*tlbcount += 1;
|
*tlbcount += 1;
|
||||||
result->paddr = addr;
|
result->paddr = addr;
|
||||||
result->perms = UC_PROT_ALL;
|
result->perms = UC_PROT_ALL;
|
||||||
@ -357,14 +362,19 @@ static void test_tlb_clear(void)
|
|||||||
uc_engine *uc;
|
uc_engine *uc;
|
||||||
uc_hook hook1, hook2;
|
uc_hook hook1, hook2;
|
||||||
size_t tlbcount = 0;
|
size_t tlbcount = 0;
|
||||||
char code[] = "\xa3\x00\x00\x20\x00\x00\x00\x00\x00\x0f\x05\xa3\x00\x00\x20\x00\x00\x00\x00\x00"; //movabs dword ptr [0x200000], eax; syscall; movabs dword ptr [0x200000], eax
|
char code[] =
|
||||||
|
"\xa3\x00\x00\x20\x00\x00\x00\x00\x00\x0f\x05\xa3\x00\x00\x20\x00\x00"
|
||||||
|
"\x00\x00\x00"; // movabs dword ptr [0x200000], eax; syscall; movabs
|
||||||
|
// dword ptr [0x200000], eax
|
||||||
|
|
||||||
uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_64, code, sizeof(code) - 1);
|
uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_64, code, sizeof(code) - 1);
|
||||||
OK(uc_mem_map(uc, 0x200000, 0x1000, UC_PROT_ALL));
|
OK(uc_mem_map(uc, 0x200000, 0x1000, UC_PROT_ALL));
|
||||||
|
|
||||||
OK(uc_ctl_tlb_mode(uc, UC_TLB_VIRTUAL));
|
OK(uc_ctl_tlb_mode(uc, UC_TLB_VIRTUAL));
|
||||||
OK(uc_hook_add(uc, &hook1, UC_HOOK_TLB_FILL, test_tlb_clear_tlb, &tlbcount, 1, 0));
|
OK(uc_hook_add(uc, &hook1, UC_HOOK_TLB_FILL, test_tlb_clear_tlb, &tlbcount,
|
||||||
OK(uc_hook_add(uc, &hook2, UC_HOOK_INSN, test_tlb_clear_syscall, NULL, 1, 0, UC_X86_INS_SYSCALL));
|
1, 0));
|
||||||
|
OK(uc_hook_add(uc, &hook2, UC_HOOK_INSN, test_tlb_clear_syscall, NULL, 1, 0,
|
||||||
|
UC_X86_INS_SYSCALL));
|
||||||
|
|
||||||
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
|
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
|
||||||
|
|
||||||
@ -373,7 +383,6 @@ static void test_tlb_clear(void)
|
|||||||
OK(uc_close(uc));
|
OK(uc_close(uc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST_LIST = {{"test_uc_ctl_mode", test_uc_ctl_mode},
|
TEST_LIST = {{"test_uc_ctl_mode", test_uc_ctl_mode},
|
||||||
{"test_uc_ctl_page_size", test_uc_ctl_page_size},
|
{"test_uc_ctl_page_size", test_uc_ctl_page_size},
|
||||||
{"test_uc_ctl_arch", test_uc_ctl_arch},
|
{"test_uc_ctl_arch", test_uc_ctl_arch},
|
||||||
|
@ -634,12 +634,13 @@ static void test_riscv_correct_address_in_long_jump_hook(void)
|
|||||||
OK(uc_close(uc));
|
OK(uc_close(uc));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_riscv_mmu_prepare_tlb(uc_engine *uc, uint32_t data_address, uint32_t code_address)
|
static void test_riscv_mmu_prepare_tlb(uc_engine *uc, uint32_t data_address,
|
||||||
|
uint32_t code_address)
|
||||||
{
|
{
|
||||||
uint64_t tlbe;
|
uint64_t tlbe;
|
||||||
uint32_t sptbr = 0x2000;
|
uint32_t sptbr = 0x2000;
|
||||||
|
|
||||||
OK(uc_mem_map(uc, sptbr, 0x3000, UC_PROT_ALL)); //tlb base
|
OK(uc_mem_map(uc, sptbr, 0x3000, UC_PROT_ALL)); // tlb base
|
||||||
|
|
||||||
tlbe = ((sptbr + 0x1000) >> 2) | 1;
|
tlbe = ((sptbr + 0x1000) >> 2) | 1;
|
||||||
OK(uc_mem_write(uc, sptbr, &tlbe, sizeof(tlbe)));
|
OK(uc_mem_write(uc, sptbr, &tlbe, sizeof(tlbe)));
|
||||||
@ -647,13 +648,14 @@ static void test_riscv_mmu_prepare_tlb(uc_engine *uc, uint32_t data_address, uin
|
|||||||
OK(uc_mem_write(uc, sptbr + 0x1000, &tlbe, sizeof(tlbe)));
|
OK(uc_mem_write(uc, sptbr + 0x1000, &tlbe, sizeof(tlbe)));
|
||||||
|
|
||||||
tlbe = (code_address >> 2) | (7 << 1) | 1;
|
tlbe = (code_address >> 2) | (7 << 1) | 1;
|
||||||
OK(uc_mem_write(uc, sptbr + 0x2000 + 0x15*8, &tlbe, sizeof(tlbe)));
|
OK(uc_mem_write(uc, sptbr + 0x2000 + 0x15 * 8, &tlbe, sizeof(tlbe)));
|
||||||
|
|
||||||
tlbe = (data_address >> 2) | (7 << 1) | 1;
|
tlbe = (data_address >> 2) | (7 << 1) | 1;
|
||||||
OK(uc_mem_write(uc, sptbr + 0x2000 + 0x16*8, &tlbe, sizeof(tlbe)));
|
OK(uc_mem_write(uc, sptbr + 0x2000 + 0x16 * 8, &tlbe, sizeof(tlbe)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_riscv_mmu_hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *userdata)
|
static void test_riscv_mmu_hook_code(uc_engine *uc, uint64_t address,
|
||||||
|
uint32_t size, void *userdata)
|
||||||
{
|
{
|
||||||
if (address == 0x15010) {
|
if (address == 0x15010) {
|
||||||
OK(uc_emu_stop(uc));
|
OK(uc_emu_stop(uc));
|
||||||
@ -678,7 +680,16 @@ static void test_riscv_mmu(void)
|
|||||||
csrw mepc, t1
|
csrw mepc, t1
|
||||||
mret
|
mret
|
||||||
*/
|
*/
|
||||||
char code_m[] = "\x1b\x0e\xf0\xff" "\x13\x1e\xfe\x03" "\x13\x0e\x2e\x00" "\x73\x10\x0e\x18" "\xb7\x12\x00\x00" "\x9b\x82\x02\x82" "\x73\x90\x02\x30" "\x37\x53\x01\x00" "\x73\x10\x13\x34" "\x73\x00\x20\x30";
|
char code_m[] = "\x1b\x0e\xf0\xff"
|
||||||
|
"\x13\x1e\xfe\x03"
|
||||||
|
"\x13\x0e\x2e\x00"
|
||||||
|
"\x73\x10\x0e\x18"
|
||||||
|
"\xb7\x12\x00\x00"
|
||||||
|
"\x9b\x82\x02\x82"
|
||||||
|
"\x73\x90\x02\x30"
|
||||||
|
"\x37\x53\x01\x00"
|
||||||
|
"\x73\x10\x13\x34"
|
||||||
|
"\x73\x00\x20\x30";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
li t0, 0x41414141
|
li t0, 0x41414141
|
||||||
@ -686,7 +697,11 @@ static void test_riscv_mmu(void)
|
|||||||
sw t0, 0(t1)
|
sw t0, 0(t1)
|
||||||
nop
|
nop
|
||||||
*/
|
*/
|
||||||
char code_s[] = "\xb7\x42\x41\x41" "\x9b\x82\x12\x14" "\x37\x63\x01\x00" "\x23\x20\x53\x00" "\x13\x00\x00\x00";
|
char code_s[] = "\xb7\x42\x41\x41"
|
||||||
|
"\x9b\x82\x12\x14"
|
||||||
|
"\x37\x63\x01\x00"
|
||||||
|
"\x23\x20\x53\x00"
|
||||||
|
"\x13\x00\x00\x00";
|
||||||
|
|
||||||
OK(uc_open(UC_ARCH_RISCV, UC_MODE_RISCV64, &uc));
|
OK(uc_open(UC_ARCH_RISCV, UC_MODE_RISCV64, &uc));
|
||||||
OK(uc_ctl_tlb_mode(uc, UC_TLB_CPU));
|
OK(uc_ctl_tlb_mode(uc, UC_TLB_CPU));
|
||||||
|
@ -1125,8 +1125,8 @@ static void test_x86_invalid_vex_l(void)
|
|||||||
OK(uc_close(uc));
|
OK(uc_close(uc));
|
||||||
}
|
}
|
||||||
|
|
||||||
// AARCH64 inline the read while s390x won't split the access. Though not tested on other hosts
|
// AARCH64 inline the read while s390x won't split the access. Though not tested
|
||||||
// but we restrict a bit more.
|
// on other hosts but we restrict a bit more.
|
||||||
#if !defined(TARGET_READ_INLINED) && defined(BOOST_LITTLE_ENDIAN)
|
#if !defined(TARGET_READ_INLINED) && defined(BOOST_LITTLE_ENDIAN)
|
||||||
|
|
||||||
struct writelog_t {
|
struct writelog_t {
|
||||||
@ -1230,7 +1230,8 @@ static void test_x86_lazy_mapping(void)
|
|||||||
OK(uc_close(uc));
|
OK(uc_close(uc));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_x86_16_incorrect_ip_cb(uc_engine *uc, uint64_t address, uint32_t size, void* data)
|
static void test_x86_16_incorrect_ip_cb(uc_engine *uc, uint64_t address,
|
||||||
|
uint32_t size, void *data)
|
||||||
{
|
{
|
||||||
uint16_t cs, ip;
|
uint16_t cs, ip;
|
||||||
|
|
||||||
@ -1250,8 +1251,10 @@ static void test_x86_16_incorrect_ip(void)
|
|||||||
|
|
||||||
uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_16, code, sizeof(code) - 1);
|
uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_16, code, sizeof(code) - 1);
|
||||||
|
|
||||||
OK(uc_hook_add(uc, &hk1, UC_HOOK_BLOCK, test_x86_16_incorrect_ip_cb, NULL, 1, 0));
|
OK(uc_hook_add(uc, &hk1, UC_HOOK_BLOCK, test_x86_16_incorrect_ip_cb, NULL,
|
||||||
OK(uc_hook_add(uc, &hk2, UC_HOOK_CODE, test_x86_16_incorrect_ip_cb, NULL, 1, 0));
|
1, 0));
|
||||||
|
OK(uc_hook_add(uc, &hk2, UC_HOOK_CODE, test_x86_16_incorrect_ip_cb, NULL, 1,
|
||||||
|
0));
|
||||||
|
|
||||||
OK(uc_reg_write(uc, UC_X86_REG_CS, &cs));
|
OK(uc_reg_write(uc, UC_X86_REG_CS, &cs));
|
||||||
|
|
||||||
@ -1260,17 +1263,18 @@ static void test_x86_16_incorrect_ip(void)
|
|||||||
OK(uc_close(uc));
|
OK(uc_close(uc));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_x86_mmu_prepare_tlb(uc_engine *uc, uint64_t vaddr, uint64_t tlb_base)
|
static void test_x86_mmu_prepare_tlb(uc_engine *uc, uint64_t vaddr,
|
||||||
|
uint64_t tlb_base)
|
||||||
{
|
{
|
||||||
uint64_t cr0;
|
uint64_t cr0;
|
||||||
uint64_t cr4;
|
uint64_t cr4;
|
||||||
uc_x86_msr msr = {.rid = 0x0c0000080, .value = 0};
|
uc_x86_msr msr = {.rid = 0x0c0000080, .value = 0};
|
||||||
uint64_t pml4o = ((vaddr & 0x00ff8000000000) >> 39)*8;
|
uint64_t pml4o = ((vaddr & 0x00ff8000000000) >> 39) * 8;
|
||||||
uint64_t pdpo = ((vaddr & 0x00007fc0000000) >> 30)*8;
|
uint64_t pdpo = ((vaddr & 0x00007fc0000000) >> 30) * 8;
|
||||||
uint64_t pdo = ((vaddr & 0x0000003fe00000) >> 21)*8;
|
uint64_t pdo = ((vaddr & 0x0000003fe00000) >> 21) * 8;
|
||||||
uint64_t pml4e = (tlb_base + 0x1000) | 1 | (1 << 2);
|
uint64_t pml4e = (tlb_base + 0x1000) | 1 | (1 << 2);
|
||||||
uint64_t pdpe = (tlb_base + 0x2000) | 1 | (1 << 2);
|
uint64_t pdpe = (tlb_base + 0x2000) | 1 | (1 << 2);
|
||||||
uint64_t pde = (tlb_base + 0x3000) | 1 | (1 << 2);
|
uint64_t pde = (tlb_base + 0x3000) | 1 | (1 << 2);
|
||||||
OK(uc_mem_write(uc, tlb_base + pml4o, &pml4e, sizeof(pml4o)));
|
OK(uc_mem_write(uc, tlb_base + pml4o, &pml4e, sizeof(pml4o)));
|
||||||
OK(uc_mem_write(uc, tlb_base + 0x1000 + pdpo, &pdpe, sizeof(pdpe)));
|
OK(uc_mem_write(uc, tlb_base + 0x1000 + pdpo, &pdpe, sizeof(pdpe)));
|
||||||
OK(uc_mem_write(uc, tlb_base + 0x2000 + pdo, &pde, sizeof(pde)));
|
OK(uc_mem_write(uc, tlb_base + 0x2000 + pdo, &pde, sizeof(pde)));
|
||||||
@ -1287,10 +1291,11 @@ static void test_x86_mmu_prepare_tlb(uc_engine *uc, uint64_t vaddr, uint64_t tlb
|
|||||||
OK(uc_reg_write(uc, UC_X86_REG_MSR, &msr));
|
OK(uc_reg_write(uc, UC_X86_REG_MSR, &msr));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_x86_mmu_pt_set(uc_engine *uc, uint64_t vaddr, uint64_t paddr, uint64_t tlb_base)
|
static void test_x86_mmu_pt_set(uc_engine *uc, uint64_t vaddr, uint64_t paddr,
|
||||||
|
uint64_t tlb_base)
|
||||||
{
|
{
|
||||||
uint64_t pto = ((vaddr & 0x000000001ff000) >> 12)*8;
|
uint64_t pto = ((vaddr & 0x000000001ff000) >> 12) * 8;
|
||||||
uint32_t pte = (paddr) | 1 | (1 << 2);
|
uint32_t pte = (paddr) | 1 | (1 << 2);
|
||||||
uc_mem_write(uc, tlb_base + 0x3000 + pto, &pte, sizeof(pte));
|
uc_mem_write(uc, tlb_base + 0x3000 + pto, &pte, sizeof(pte));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1346,18 +1351,22 @@ static void test_x86_mmu(void)
|
|||||||
* mov rax, 60
|
* mov rax, 60
|
||||||
* syscall
|
* syscall
|
||||||
*/
|
*/
|
||||||
char code[] = "\xB8\x39\x00\x00\x00\x0F\x05\x48\x85\xC0\x74\x0F\xB8\x3C\x00\x00\x00\x48\x89\x04\x25\x00\x40\x00\x00\x0F\x05\xB9\x2A\x00\x00\x00\x48\x89\x0C\x25\x00\x40\x00\x00\xB8\x3C\x00\x00\x00\x0F\x05";
|
char code[] =
|
||||||
|
"\xB8\x39\x00\x00\x00\x0F\x05\x48\x85\xC0\x74\x0F\xB8\x3C\x00\x00\x00"
|
||||||
|
"\x48\x89\x04\x25\x00\x40\x00\x00\x0F\x05\xB9\x2A\x00\x00\x00\x48\x89"
|
||||||
|
"\x0C\x25\x00\x40\x00\x00\xB8\x3C\x00\x00\x00\x0F\x05";
|
||||||
|
|
||||||
OK(uc_open(UC_ARCH_X86, UC_MODE_64, &uc));
|
OK(uc_open(UC_ARCH_X86, UC_MODE_64, &uc));
|
||||||
OK(uc_ctl_tlb_mode(uc, UC_TLB_CPU));
|
OK(uc_ctl_tlb_mode(uc, UC_TLB_CPU));
|
||||||
OK(uc_hook_add(uc, &h1, UC_HOOK_INSN, &test_x86_mmu_callback, &parrent_done, 1, 0, UC_X86_INS_SYSCALL));
|
OK(uc_hook_add(uc, &h1, UC_HOOK_INSN, &test_x86_mmu_callback, &parrent_done,
|
||||||
|
1, 0, UC_X86_INS_SYSCALL));
|
||||||
OK(uc_context_alloc(uc, &context));
|
OK(uc_context_alloc(uc, &context));
|
||||||
|
|
||||||
OK(uc_mem_map(uc, 0x0, 0x1000, UC_PROT_ALL)); //Code
|
OK(uc_mem_map(uc, 0x0, 0x1000, UC_PROT_ALL)); // Code
|
||||||
OK(uc_mem_write(uc, 0x0, code, sizeof(code) - 1));
|
OK(uc_mem_write(uc, 0x0, code, sizeof(code) - 1));
|
||||||
OK(uc_mem_map(uc, 0x1000, 0x1000, UC_PROT_ALL)); //Parrent
|
OK(uc_mem_map(uc, 0x1000, 0x1000, UC_PROT_ALL)); // Parrent
|
||||||
OK(uc_mem_map(uc, 0x2000, 0x1000, UC_PROT_ALL)); //Child
|
OK(uc_mem_map(uc, 0x2000, 0x1000, UC_PROT_ALL)); // Child
|
||||||
OK(uc_mem_map(uc, tlb_base, 0x4000, UC_PROT_ALL)); //TLB
|
OK(uc_mem_map(uc, tlb_base, 0x4000, UC_PROT_ALL)); // TLB
|
||||||
|
|
||||||
test_x86_mmu_prepare_tlb(uc, 0x0, tlb_base);
|
test_x86_mmu_prepare_tlb(uc, 0x0, tlb_base);
|
||||||
test_x86_mmu_pt_set(uc, 0x2000, 0x0, tlb_base);
|
test_x86_mmu_pt_set(uc, 0x2000, 0x0, tlb_base);
|
||||||
@ -1386,7 +1395,9 @@ static void test_x86_mmu(void)
|
|||||||
TEST_CHECK(child == 42);
|
TEST_CHECK(child == 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool test_x86_vtlb_callback(uc_engine *uc, uint64_t addr, uc_mem_type type, uc_tlb_entry *result, void *user_data)
|
static bool test_x86_vtlb_callback(uc_engine *uc, uint64_t addr,
|
||||||
|
uc_mem_type type, uc_tlb_entry *result,
|
||||||
|
void *user_data)
|
||||||
{
|
{
|
||||||
result->paddr = addr;
|
result->paddr = addr;
|
||||||
result->perms = UC_PROT_ALL;
|
result->perms = UC_PROT_ALL;
|
||||||
@ -1404,7 +1415,8 @@ static void test_x86_vtlb(void)
|
|||||||
uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_32, code, sizeof(code) - 1);
|
uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_32, code, sizeof(code) - 1);
|
||||||
|
|
||||||
OK(uc_ctl_tlb_mode(uc, UC_TLB_VIRTUAL));
|
OK(uc_ctl_tlb_mode(uc, UC_TLB_VIRTUAL));
|
||||||
OK(uc_hook_add(uc, &hook, UC_HOOK_TLB_FILL, test_x86_vtlb_callback, NULL, 1, 0));
|
OK(uc_hook_add(uc, &hook, UC_HOOK_TLB_FILL, test_x86_vtlb_callback, NULL, 1,
|
||||||
|
0));
|
||||||
|
|
||||||
OK(uc_emu_start(uc, code_start, code_start + 4, 0, 0));
|
OK(uc_emu_start(uc, code_start, code_start + 4, 0, 0));
|
||||||
|
|
||||||
@ -1419,14 +1431,13 @@ static void test_x86_segmentation()
|
|||||||
{
|
{
|
||||||
uc_engine *uc;
|
uc_engine *uc;
|
||||||
uint64_t fs = 0x53;
|
uint64_t fs = 0x53;
|
||||||
uc_x86_mmr gdtr = { 0, 0xfffff8076d962000, 0x57, 0 };
|
uc_x86_mmr gdtr = {0, 0xfffff8076d962000, 0x57, 0};
|
||||||
|
|
||||||
OK(uc_open(UC_ARCH_X86, UC_MODE_64, &uc));
|
OK(uc_open(UC_ARCH_X86, UC_MODE_64, &uc));
|
||||||
OK(uc_reg_write(uc, UC_X86_REG_GDTR, &gdtr));
|
OK(uc_reg_write(uc, UC_X86_REG_GDTR, &gdtr));
|
||||||
uc_assert_err(UC_ERR_EXCEPTION, uc_reg_write(uc, UC_X86_REG_FS, &fs));
|
uc_assert_err(UC_ERR_EXCEPTION, uc_reg_write(uc, UC_X86_REG_FS, &fs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST_LIST = {
|
TEST_LIST = {
|
||||||
{"test_x86_in", test_x86_in},
|
{"test_x86_in", test_x86_in},
|
||||||
{"test_x86_out", test_x86_out},
|
{"test_x86_out", test_x86_out},
|
||||||
|
@ -10,20 +10,19 @@
|
|||||||
// Copied from glibc-2.29
|
// Copied from glibc-2.29
|
||||||
|
|
||||||
/* Swap bytes in 32 bit value. */
|
/* Swap bytes in 32 bit value. */
|
||||||
#define bswap_32(x) \
|
#define bswap_32(x) \
|
||||||
((((x) & 0xff000000u) >> 24) | (((x) & 0x00ff0000u) >> 8) | \
|
((((x)&0xff000000u) >> 24) | (((x)&0x00ff0000u) >> 8) | \
|
||||||
(((x) & 0x0000ff00u) << 8) | (((x) & 0x000000ffu) << 24))
|
(((x)&0x0000ff00u) << 8) | (((x)&0x000000ffu) << 24))
|
||||||
|
|
||||||
/* Swap bytes in 64 bit value. */
|
/* Swap bytes in 64 bit value. */
|
||||||
#define bswap_64(x) \
|
#define bswap_64(x) \
|
||||||
((((x) & 0xff00000000000000ull) >> 56) \
|
((((x)&0xff00000000000000ull) >> 56) | \
|
||||||
| (((x) & 0x00ff000000000000ull) >> 40) \
|
(((x)&0x00ff000000000000ull) >> 40) | \
|
||||||
| (((x) & 0x0000ff0000000000ull) >> 24) \
|
(((x)&0x0000ff0000000000ull) >> 24) | \
|
||||||
| (((x) & 0x000000ff00000000ull) >> 8) \
|
(((x)&0x000000ff00000000ull) >> 8) | (((x)&0x00000000ff000000ull) << 8) | \
|
||||||
| (((x) & 0x00000000ff000000ull) << 8) \
|
(((x)&0x0000000000ff0000ull) << 24) | \
|
||||||
| (((x) & 0x0000000000ff0000ull) << 24) \
|
(((x)&0x000000000000ff00ull) << 40) | \
|
||||||
| (((x) & 0x000000000000ff00ull) << 40) \
|
(((x)&0x00000000000000ffull) << 56))
|
||||||
| (((x) & 0x00000000000000ffull) << 56))
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assert that err matches expect
|
* Assert that err matches expect
|
||||||
|
6
uc.c
6
uc.c
@ -1495,16 +1495,14 @@ MemoryRegion *find_memory_region(struct uc_struct *uc, uint64_t address)
|
|||||||
// try with the cache index first
|
// try with the cache index first
|
||||||
i = uc->mapped_block_cache_index;
|
i = uc->mapped_block_cache_index;
|
||||||
|
|
||||||
if (i < uc->mapped_block_count &&
|
if (i < uc->mapped_block_count && address >= uc->mapped_blocks[i]->addr &&
|
||||||
address >= uc->mapped_blocks[i]->addr &&
|
|
||||||
address <= uc->mapped_blocks[i]->end - 1) {
|
address <= uc->mapped_blocks[i]->end - 1) {
|
||||||
return uc->mapped_blocks[i];
|
return uc->mapped_blocks[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
i = bsearch_mapped_blocks(uc, address);
|
i = bsearch_mapped_blocks(uc, address);
|
||||||
|
|
||||||
if (i < uc->mapped_block_count &&
|
if (i < uc->mapped_block_count && address >= uc->mapped_blocks[i]->addr &&
|
||||||
address >= uc->mapped_blocks[i]->addr &&
|
|
||||||
address <= uc->mapped_blocks[i]->end - 1) {
|
address <= uc->mapped_blocks[i]->end - 1) {
|
||||||
uc->mapped_block_cache_index = i;
|
uc->mapped_block_cache_index = i;
|
||||||
return uc->mapped_blocks[i];
|
return uc->mapped_blocks[i];
|
||||||
|
Loading…
Reference in New Issue
Block a user