void _interrupt(uc_engine *uc, uint32_t intno, void *user_data) { if (intno == 6) { uc_emu_stop(uc); got_sigill = 1; } }
int m68k_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, int count) { CPUState *mycpu = uc->cpu; int i; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; const void *value = vals[i]; if (regid >= UC_M68K_REG_A0 && regid <= UC_M68K_REG_A7) M68K_CPU(uc, mycpu)->env.aregs[regid - UC_M68K_REG_A0] = *(uint32_t *)value; else if (regid >= UC_M68K_REG_D0 && regid <= UC_M68K_REG_D7) M68K_CPU(uc, mycpu)->env.dregs[regid - UC_M68K_REG_D0] = *(uint32_t *)value; else { switch(regid) { default: break; case UC_M68K_REG_PC: M68K_CPU(uc, mycpu)->env.pc = *(uint32_t *)value; // force to quit execution and flush TB uc->quit_request = true; uc_emu_stop(uc); break; } } } return 0; }
int arm64_reg_write(struct uc_struct *uc, unsigned int regid, const void *value) { CPUState *mycpu = first_cpu; if (regid >= UC_ARM64_REG_X0 && regid <= UC_ARM64_REG_X28) ARM_CPU(uc, mycpu)->env.xregs[regid - UC_ARM64_REG_X0] = *(uint64_t *)value; else { switch(regid) { default: break; case UC_ARM64_REG_X29: ARM_CPU(uc, mycpu)->env.xregs[29] = *(uint64_t *)value; break; case UC_ARM64_REG_X30: ARM_CPU(uc, mycpu)->env.xregs[30] = *(uint64_t *)value; break; case UC_ARM64_REG_PC: ARM_CPU(uc, mycpu)->env.pc = *(uint64_t *)value; // force to quit execution and flush TB uc->quit_request = true; uc_emu_stop(uc); break; case UC_ARM64_REG_SP: ARM_CPU(uc, mycpu)->env.xregs[31] = *(uint64_t *)value; break; } } return 0; }
int arm_reg_write(struct uc_struct *uc, unsigned int regid, const void *value) { CPUState *mycpu = first_cpu; if (regid >= UC_ARM_REG_R0 && regid <= UC_ARM_REG_R12) ARM_CPU(uc, mycpu)->env.regs[regid - UC_ARM_REG_R0] = *(uint32_t *)value; else { switch(regid) { //case UC_ARM_REG_SP: case UC_ARM_REG_R13: ARM_CPU(uc, mycpu)->env.regs[13] = *(uint32_t *)value; break; //case UC_ARM_REG_LR: case UC_ARM_REG_R14: ARM_CPU(uc, mycpu)->env.regs[14] = *(uint32_t *)value; break; //case UC_ARM_REG_PC: case UC_ARM_REG_R15: ARM_CPU(uc, mycpu)->env.pc = *(uint32_t *)value; ARM_CPU(uc, mycpu)->env.regs[15] = *(uint32_t *)value; // force to quit execution and flush TB uc->quit_request = true; uc_emu_stop(uc); break; } } return 0; }
int sparc_reg_write(struct uc_struct *uc, unsigned int regid, const void *value) { CPUState *mycpu = first_cpu; if (regid >= UC_SPARC_REG_G0 && regid <= UC_SPARC_REG_G7) SPARC_CPU(uc, mycpu)->env.gregs[regid - UC_SPARC_REG_G0] = *(uint32_t *)value; else if (regid >= UC_SPARC_REG_O0 && regid <= UC_SPARC_REG_O7) SPARC_CPU(uc, mycpu)->env.regwptr[regid - UC_SPARC_REG_O0] = *(uint32_t *)value; else if (regid >= UC_SPARC_REG_L0 && regid <= UC_SPARC_REG_L7) SPARC_CPU(uc, mycpu)->env.regwptr[8 + regid - UC_SPARC_REG_L0] = *(uint32_t *)value; else if (regid >= UC_SPARC_REG_I0 && regid <= UC_SPARC_REG_I7) SPARC_CPU(uc, mycpu)->env.regwptr[16 + regid - UC_SPARC_REG_I0] = *(uint32_t *)value; else { switch(regid) { default: break; case UC_SPARC_REG_PC: SPARC_CPU(uc, mycpu)->env.pc = *(uint32_t *)value; SPARC_CPU(uc, mycpu)->env.npc = *(uint32_t *)value + 4; // force to quit execution and flush TB uc->quit_request = true; uc_emu_stop(uc); break; } } return 0; }
int arm64_reg_write(struct uc_struct *uc, unsigned int *regs, void* const* vals, int count) { CPUState *mycpu = uc->cpu; int i; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; const void *value = vals[i]; if (regid >= UC_ARM64_REG_X0 && regid <= UC_ARM64_REG_X28) ARM_CPU(uc, mycpu)->env.xregs[regid - UC_ARM64_REG_X0] = *(uint64_t *)value; else { switch(regid) { default: break; case UC_ARM64_REG_X29: ARM_CPU(uc, mycpu)->env.xregs[29] = *(uint64_t *)value; break; case UC_ARM64_REG_X30: ARM_CPU(uc, mycpu)->env.xregs[30] = *(uint64_t *)value; break; case UC_ARM64_REG_PC: ARM_CPU(uc, mycpu)->env.pc = *(uint64_t *)value; // force to quit execution and flush TB uc->quit_request = true; uc_emu_stop(uc); break; case UC_ARM64_REG_SP: ARM_CPU(uc, mycpu)->env.xregs[31] = *(uint64_t *)value; break; } } } return 0; }
int mips_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, int count) { CPUState *mycpu = first_cpu; int i; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; const void *value = vals[i]; if (regid >= UC_MIPS_REG_0 && regid <= UC_MIPS_REG_31) MIPS_CPU(uc, mycpu)->env.active_tc.gpr[regid - UC_MIPS_REG_0] = *(uint32_t *)value; else { switch(regid) { default: break; case UC_MIPS_REG_PC: MIPS_CPU(uc, mycpu)->env.active_tc.PC = *(uint32_t *)value; // force to quit execution and flush TB uc->quit_request = true; uc_emu_stop(uc); break; } } } return 0; }
static void hook_count_cb(struct uc_struct *uc, uint64_t address, uint32_t size, void *user_data) { // count this instruction. ah ah ah. uc->emu_counter++; if (uc->emu_counter > uc->emu_count) uc_emu_stop(uc); }
// This hook is used to show that code is executing in the emulator. static void mips_codehook(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) { printf("Executing: %llX\n", address); if( address == 0x100008 ) { printf("Stopping at: %llX\n", address); uc_emu_stop(uc); } }
// callback for tracing instructions, detect HLT and terminate emulation static void hook_code(uc_engine *uc, uint64_t addr, uint32_t size, void *user_data) { uint8_t opcode; unsigned char buf[256]; insts_executed++; if (uc_mem_read(uc, addr, buf, size) != UC_ERR_OK) { printf("not ok - uc_mem_read fail during hook_code callback, addr: 0x%" PRIx64 "\n", addr); if (uc_emu_stop(uc) != UC_ERR_OK) { printf("not ok - uc_emu_stop fail during hook_code callback, addr: 0x%" PRIx64 "\n", addr); _exit(-1); } } opcode = buf[0]; switch (opcode) { case 0x41: // inc ecx if (uc_mem_protect(uc, 0x101000, 0x1000, UC_PROT_READ) != UC_ERR_OK) { printf("not ok - uc_mem_protect fail during hook_code callback, addr: 0x%" PRIx64 "\n", addr); _exit(-1); } break; case 0x42: // inc edx if (uc_mem_unmap(uc, 0x101000, 0x1000) != UC_ERR_OK) { printf("not ok - uc_mem_unmap fail during hook_code callback, addr: 0x%" PRIx64 "\n", addr); _exit(-1); } break; case 0xf4: // hlt if (uc_emu_stop(uc) != UC_ERR_OK) { printf("not ok - uc_emu_stop fail during hook_code callback, addr: 0x%" PRIx64 "\n", addr); _exit(-1); } break; default: // all others break; } }
// 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; } }
static void *_timeout_fn(void *arg) { struct uc_struct *uc = arg; int64_t current_time = get_clock(); do { usleep(TIMEOUT_STEP); // perhaps emulation is even done before timeout? if (uc->emulation_done) break; } while(get_clock() - current_time < uc->timeout); // timeout before emulation is done? if (!uc->emulation_done) { // force emulation to stop uc_emu_stop(uc); } return NULL; }
// 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; } }
UNICORN_EXPORT uc_err uc_mem_protect(struct uc_struct *uc, uint64_t address, size_t size, uint32_t perms) { MemoryRegion *mr; uint64_t addr = address; size_t count, len; bool remove_exec = false; if (size == 0) // trivial case, no change return UC_ERR_OK; // address must be aligned to uc->target_page_size if ((address & uc->target_page_align) != 0) return UC_ERR_ARG; // size must be multiple of uc->target_page_size if ((size & uc->target_page_align) != 0) return UC_ERR_ARG; // check for only valid permissions if ((perms & ~UC_PROT_ALL) != 0) return UC_ERR_ARG; if (uc->mem_redirect) { address = uc->mem_redirect(address); } // check that user's entire requested block is mapped if (!check_mem_area(uc, address, size)) return UC_ERR_NOMEM; // Now we know entire region is mapped, so change permissions // We may need to split regions if this area spans adjacent regions addr = address; count = 0; while(count < size) { mr = memory_mapping(uc, addr); len = MIN(size - count, mr->end - addr); if (!split_region(uc, mr, addr, len, false)) return UC_ERR_NOMEM; mr = memory_mapping(uc, addr); // will this remove EXEC permission? if (((mr->perms & UC_PROT_EXEC) != 0) && ((perms & UC_PROT_EXEC) == 0)) remove_exec = true; mr->perms = perms; uc->readonly_mem(mr, (perms & UC_PROT_WRITE) == 0); count += len; addr += len; } // if EXEC permission is removed, then quit TB and continue at the same place if (remove_exec) { uc->quit_request = true; uc_emu_stop(uc); } return UC_ERR_OK; }
int main(int argc, char **argv, char **envp) { uc_engine *uc; uc_err err; int ret; uc_hook hhc; uint32_t val; EmuStarterParam_t starter_params; #ifdef _WIN32 HANDLE th = (HANDLE)-1; #else pthread_t th; #endif // dynamically load shared library #ifdef DYNLOAD uc_dyn_load(NULL, 0); #endif // Initialize emulator in MIPS 32bit little endian mode printf("uc_open()\n"); err = uc_open(UC_ARCH_MIPS, UC_MODE_MIPS32, &uc); if (err) { printf("Failed on uc_open() with error returned: %u\n", err); return err; } // map in a page of mem printf("uc_mem_map()\n"); err = uc_mem_map(uc, addr, 0x1000, UC_PROT_ALL); if (err) { printf("Failed on uc_mem_map() with error returned: %u\n", err); return err; } // write machine code to be emulated to memory printf("uc_mem_write()\n"); err = uc_mem_write(uc, addr, loop_test_code, sizeof(loop_test_code)); if( err ) { printf("Failed on uc_mem_write() with error returned: %u\n", err); return err; } // hook all instructions by having @begin > @end printf("uc_hook_add()\n"); uc_hook_add(uc, &hhc, UC_HOOK_CODE, mips_codehook, NULL, 1, 0); if( err ) { printf("Failed on uc_hook_add(code) with error returned: %u\n", err); return err; } // start background thread printf("---- Thread Starting ----\n"); starter_params.uc = uc; starter_params.startAddr = addr; starter_params.endAddr = addr + sizeof(loop_test_code); #ifdef _WIN32 // create thread th = (HANDLE)_beginthreadex(NULL, 0, win32_emu_starter, &starter_params, CREATE_SUSPENDED, NULL); if(th == (HANDLE)-1) { printf("Failed on _beginthreadex() with error returned: %u\n", _errno()); return -1; } // start thread ret = ResumeThread(th); if( ret == -1 ) { printf("Failed on ResumeThread() with error returned: %u\n", _errno()); return -2; } // wait 3 seconds Sleep(3 * 1000); #else // add posix code to start the emu_starter() thread ret = pthread_create(&th, NULL, posix_emu_starter, &starter_params); if( ret ) { printf("Failed on pthread_create() with error returned: %u\n", err); return -2; } // wait 3 seconds sleep(3); #endif // Stop the thread after it has been let to run in the background for a while printf("---- Thread Stopping ----\n"); printf("uc_emu_stop()\n"); err = uc_emu_stop(uc); if( err ) { printf("Failed on uc_emu_stop() with error returned: %u\n", err); return err; } test_passed_ok = true; // done executing, print some reg values as a test uc_reg_read(uc, UC_MIPS_REG_PC, &val); printf("pc is %X\n", val); uc_reg_read(uc, UC_MIPS_REG_A0, &val); printf("a0 is %X\n", val); // free resources printf("uc_close()\n"); uc_close(uc); if( test_passed_ok ) printf("\n\nTEST PASSED!\n\n"); else printf("\n\nTEST FAILED!\n\n"); // dynamically free shared library #ifdef DYNLOAD uc_dyn_free(); #endif return 0; }
int x86_reg_write(struct uc_struct *uc, unsigned int regid, const void *value) { CPUState *mycpu = first_cpu; switch(uc->mode) { default: break; case UC_MODE_16: switch(regid) { default: break; case UC_X86_REG_ES: X86_CPU(uc, mycpu)->env.segs[R_ES].selector = *(uint16_t *)value; return 0; case UC_X86_REG_SS: X86_CPU(uc, mycpu)->env.segs[R_SS].selector = *(uint16_t *)value; return 0; case UC_X86_REG_DS: X86_CPU(uc, mycpu)->env.segs[R_DS].selector = *(uint16_t *)value; return 0; case UC_X86_REG_FS: X86_CPU(uc, mycpu)->env.segs[R_FS].selector = *(uint16_t *)value; return 0; case UC_X86_REG_GS: X86_CPU(uc, mycpu)->env.segs[R_GS].selector = *(uint16_t *)value; return 0; } // fall-thru case UC_MODE_32: switch(regid) { default: break; case UC_X86_REG_CR0 ... UC_X86_REG_CR4: X86_CPU(uc, mycpu)->env.cr[regid - UC_X86_REG_CR0] = *(uint32_t *)value; break; case UC_X86_REG_DR0 ... UC_X86_REG_DR7: X86_CPU(uc, mycpu)->env.dr[regid - UC_X86_REG_DR0] = *(uint32_t *)value; break; case UC_X86_REG_EFLAGS: X86_CPU(uc, mycpu)->env.eflags = *(uint32_t *)value; X86_CPU(uc, mycpu)->env.eflags0 = *(uint32_t *)value; break; case UC_X86_REG_EAX: X86_CPU(uc, mycpu)->env.regs[R_EAX] = *(uint32_t *)value; break; case UC_X86_REG_AX: WRITE_WORD(X86_CPU(uc, mycpu)->env.regs[R_EAX], *(uint16_t *)value); break; case UC_X86_REG_AH: WRITE_BYTE_H(X86_CPU(uc, mycpu)->env.regs[R_EAX], *(uint8_t *)value); break; case UC_X86_REG_AL: WRITE_BYTE_L(X86_CPU(uc, mycpu)->env.regs[R_EAX], *(uint8_t *)value); break; case UC_X86_REG_EBX: X86_CPU(uc, mycpu)->env.regs[R_EBX] = *(uint32_t *)value; break; case UC_X86_REG_BX: WRITE_WORD(X86_CPU(uc, mycpu)->env.regs[R_EBX], *(uint16_t *)value); break; case UC_X86_REG_BH: WRITE_BYTE_H(X86_CPU(uc, mycpu)->env.regs[R_EBX], *(uint8_t *)value); break; case UC_X86_REG_BL: WRITE_BYTE_L(X86_CPU(uc, mycpu)->env.regs[R_EBX], *(uint8_t *)value); break; case UC_X86_REG_ECX: X86_CPU(uc, mycpu)->env.regs[R_ECX] = *(uint32_t *)value; break; case UC_X86_REG_CX: WRITE_WORD(X86_CPU(uc, mycpu)->env.regs[R_ECX], *(uint16_t *)value); break; case UC_X86_REG_CH: WRITE_BYTE_H(X86_CPU(uc, mycpu)->env.regs[R_ECX], *(uint8_t *)value); break; case UC_X86_REG_CL: WRITE_BYTE_L(X86_CPU(uc, mycpu)->env.regs[R_ECX], *(uint8_t *)value); break; case UC_X86_REG_EDX: X86_CPU(uc, mycpu)->env.regs[R_EDX] = *(uint32_t *)value; break; case UC_X86_REG_DX: WRITE_WORD(X86_CPU(uc, mycpu)->env.regs[R_EDX], *(uint16_t *)value); break; case UC_X86_REG_DH: WRITE_BYTE_H(X86_CPU(uc, mycpu)->env.regs[R_EDX], *(uint8_t *)value); break; case UC_X86_REG_DL: WRITE_BYTE_L(X86_CPU(uc, mycpu)->env.regs[R_EDX], *(uint8_t *)value); break; case UC_X86_REG_ESP: X86_CPU(uc, mycpu)->env.regs[R_ESP] = *(uint32_t *)value; break; case UC_X86_REG_SP: WRITE_WORD(X86_CPU(uc, mycpu)->env.regs[R_ESP], *(uint16_t *)value); break; case UC_X86_REG_EBP: X86_CPU(uc, mycpu)->env.regs[R_EBP] = *(uint32_t *)value; break; case UC_X86_REG_BP: WRITE_WORD(X86_CPU(uc, mycpu)->env.regs[R_EBP], *(uint16_t *)value); break; case UC_X86_REG_ESI: X86_CPU(uc, mycpu)->env.regs[R_ESI] = *(uint32_t *)value; break; case UC_X86_REG_SI: WRITE_WORD(X86_CPU(uc, mycpu)->env.regs[R_ESI], *(uint16_t *)value); break; case UC_X86_REG_EDI: X86_CPU(uc, mycpu)->env.regs[R_EDI] = *(uint32_t *)value; break; case UC_X86_REG_DI: WRITE_WORD(X86_CPU(uc, mycpu)->env.regs[R_EDI], *(uint16_t *)value); break; case UC_X86_REG_EIP: X86_CPU(uc, mycpu)->env.eip = *(uint32_t *)value; // force to quit execution and flush TB uc->quit_request = true; uc_emu_stop(uc); break; case UC_X86_REG_IP: WRITE_WORD(X86_CPU(uc, mycpu)->env.eip, *(uint16_t *)value); // force to quit execution and flush TB uc->quit_request = true; uc_emu_stop(uc); break; case UC_X86_REG_CS: X86_CPU(uc, mycpu)->env.segs[R_CS].selector = *(uint16_t *)value; break; case UC_X86_REG_DS: X86_CPU(uc, mycpu)->env.segs[R_DS].selector = *(uint16_t *)value; break; case UC_X86_REG_SS: X86_CPU(uc, mycpu)->env.segs[R_SS].selector = *(uint16_t *)value; break; case UC_X86_REG_ES: X86_CPU(uc, mycpu)->env.segs[R_ES].selector = *(uint16_t *)value; break; case UC_X86_REG_FS: X86_CPU(uc, mycpu)->env.segs[R_FS].selector = *(uint16_t *)value; break; case UC_X86_REG_GS: X86_CPU(uc, mycpu)->env.segs[R_GS].selector = *(uint16_t *)value; break; case UC_X86_REG_IDTR: X86_CPU(uc, mycpu)->env.idt.limit = (uint16_t)((uc_x86_mmr *)value)->limit; X86_CPU(uc, mycpu)->env.idt.base = (uint32_t)((uc_x86_mmr *)value)->base; break; case UC_X86_REG_GDTR: X86_CPU(uc, mycpu)->env.gdt.limit = (uint16_t)((uc_x86_mmr *)value)->limit; X86_CPU(uc, mycpu)->env.gdt.base = (uint32_t)((uc_x86_mmr *)value)->base; break; case UC_X86_REG_LDTR: X86_CPU(uc, mycpu)->env.ldt.limit = ((uc_x86_mmr *)value)->limit; X86_CPU(uc, mycpu)->env.ldt.base = (uint32_t)((uc_x86_mmr *)value)->base; X86_CPU(uc, mycpu)->env.ldt.selector = (uint16_t)((uc_x86_mmr *)value)->selector; X86_CPU(uc, mycpu)->env.ldt.flags = ((uc_x86_mmr *)value)->flags; break; case UC_X86_REG_TR: X86_CPU(uc, mycpu)->env.tr.limit = ((uc_x86_mmr *)value)->limit; X86_CPU(uc, mycpu)->env.tr.base = (uint32_t)((uc_x86_mmr *)value)->base; X86_CPU(uc, mycpu)->env.tr.selector = (uint16_t)((uc_x86_mmr *)value)->selector; X86_CPU(uc, mycpu)->env.tr.flags = ((uc_x86_mmr *)value)->flags; break; } break; #ifdef TARGET_X86_64 case UC_MODE_64: switch(regid) { default: break; case UC_X86_REG_CR0 ... UC_X86_REG_CR4: X86_CPU(uc, mycpu)->env.cr[regid - UC_X86_REG_CR0] = *(uint64_t *)value; break; case UC_X86_REG_DR0 ... UC_X86_REG_DR7: X86_CPU(uc, mycpu)->env.dr[regid - UC_X86_REG_DR0] = *(uint64_t *)value; break; case UC_X86_REG_EFLAGS: X86_CPU(uc, mycpu)->env.eflags = *(uint64_t *)value; X86_CPU(uc, mycpu)->env.eflags0 = *(uint64_t *)value; break; case UC_X86_REG_RAX: X86_CPU(uc, mycpu)->env.regs[R_EAX] = *(uint64_t *)value; break; case UC_X86_REG_EAX: WRITE_DWORD(X86_CPU(uc, mycpu)->env.regs[R_EAX], *(uint32_t *)value); break; case UC_X86_REG_AX: WRITE_WORD(X86_CPU(uc, mycpu)->env.regs[R_EAX], *(uint16_t *)value); break; case UC_X86_REG_AH: WRITE_BYTE_H(X86_CPU(uc, mycpu)->env.regs[R_EAX], *(uint8_t *)value); break; case UC_X86_REG_AL: WRITE_BYTE_L(X86_CPU(uc, mycpu)->env.regs[R_EAX], *(uint8_t *)value); break; case UC_X86_REG_RBX: X86_CPU(uc, mycpu)->env.regs[R_EBX] = *(uint64_t *)value; break; case UC_X86_REG_EBX: WRITE_DWORD(X86_CPU(uc, mycpu)->env.regs[R_EBX], *(uint32_t *)value); break; case UC_X86_REG_BX: WRITE_WORD(X86_CPU(uc, mycpu)->env.regs[R_EBX], *(uint16_t *)value); break; case UC_X86_REG_BH: WRITE_BYTE_H(X86_CPU(uc, mycpu)->env.regs[R_EBX], *(uint8_t *)value); break; case UC_X86_REG_BL: WRITE_BYTE_L(X86_CPU(uc, mycpu)->env.regs[R_EBX], *(uint8_t *)value); break; case UC_X86_REG_RCX: X86_CPU(uc, mycpu)->env.regs[R_ECX] = *(uint64_t *)value; break; case UC_X86_REG_ECX: WRITE_DWORD(X86_CPU(uc, mycpu)->env.regs[R_ECX], *(uint32_t *)value); break; case UC_X86_REG_CX: WRITE_WORD(X86_CPU(uc, mycpu)->env.regs[R_ECX], *(uint16_t *)value); break; case UC_X86_REG_CH: WRITE_BYTE_H(X86_CPU(uc, mycpu)->env.regs[R_ECX], *(uint8_t *)value); break; case UC_X86_REG_CL: WRITE_BYTE_L(X86_CPU(uc, mycpu)->env.regs[R_ECX], *(uint8_t *)value); break; case UC_X86_REG_RDX: X86_CPU(uc, mycpu)->env.regs[R_EDX] = *(uint64_t *)value; break; case UC_X86_REG_EDX: WRITE_DWORD(X86_CPU(uc, mycpu)->env.regs[R_EDX], *(uint32_t *)value); break; case UC_X86_REG_DX: WRITE_WORD(X86_CPU(uc, mycpu)->env.regs[R_EDX], *(uint16_t *)value); break; case UC_X86_REG_DH: WRITE_BYTE_H(X86_CPU(uc, mycpu)->env.regs[R_EDX], *(uint8_t *)value); break; case UC_X86_REG_DL: WRITE_BYTE_L(X86_CPU(uc, mycpu)->env.regs[R_EDX], *(uint8_t *)value); break; case UC_X86_REG_RSP: X86_CPU(uc, mycpu)->env.regs[R_ESP] = *(uint64_t *)value; break; case UC_X86_REG_ESP: WRITE_DWORD(X86_CPU(uc, mycpu)->env.regs[R_ESP], *(uint32_t *)value); break; case UC_X86_REG_SP: WRITE_WORD(X86_CPU(uc, mycpu)->env.regs[R_ESP], *(uint16_t *)value); break; case UC_X86_REG_SPL: WRITE_BYTE_L(X86_CPU(uc, mycpu)->env.regs[R_ESP], *(uint8_t *)value); break; case UC_X86_REG_RBP: X86_CPU(uc, mycpu)->env.regs[R_EBP] = *(uint64_t *)value; break; case UC_X86_REG_EBP: WRITE_DWORD(X86_CPU(uc, mycpu)->env.regs[R_EBP], *(uint32_t *)value); break; case UC_X86_REG_BP: WRITE_WORD(X86_CPU(uc, mycpu)->env.regs[R_EBP], *(uint16_t *)value); break; case UC_X86_REG_BPL: WRITE_BYTE_L(X86_CPU(uc, mycpu)->env.regs[R_EBP], *(uint8_t *)value); break; case UC_X86_REG_RSI: X86_CPU(uc, mycpu)->env.regs[R_ESI] = *(uint64_t *)value; break; case UC_X86_REG_ESI: WRITE_DWORD(X86_CPU(uc, mycpu)->env.regs[R_ESI], *(uint32_t *)value); break; case UC_X86_REG_SI: WRITE_WORD(X86_CPU(uc, mycpu)->env.regs[R_ESI], *(uint16_t *)value); break; case UC_X86_REG_SIL: WRITE_BYTE_L(X86_CPU(uc, mycpu)->env.regs[R_ESI], *(uint8_t *)value); break; case UC_X86_REG_RDI: X86_CPU(uc, mycpu)->env.regs[R_EDI] = *(uint64_t *)value; break; case UC_X86_REG_EDI: WRITE_DWORD(X86_CPU(uc, mycpu)->env.regs[R_EDI], *(uint32_t *)value); break; case UC_X86_REG_DI: WRITE_WORD(X86_CPU(uc, mycpu)->env.regs[R_EDI], *(uint16_t *)value); break; case UC_X86_REG_DIL: WRITE_BYTE_L(X86_CPU(uc, mycpu)->env.regs[R_EDI], *(uint8_t *)value); break; case UC_X86_REG_RIP: X86_CPU(uc, mycpu)->env.eip = *(uint64_t *)value; // force to quit execution and flush TB uc->quit_request = true; uc_emu_stop(uc); break; case UC_X86_REG_EIP: WRITE_DWORD(X86_CPU(uc, mycpu)->env.eip, *(uint32_t *)value); // force to quit execution and flush TB uc->quit_request = true; uc_emu_stop(uc); break; case UC_X86_REG_IP: WRITE_WORD(X86_CPU(uc, mycpu)->env.eip, *(uint16_t *)value); // force to quit execution and flush TB uc->quit_request = true; uc_emu_stop(uc); break; case UC_X86_REG_CS: X86_CPU(uc, mycpu)->env.segs[R_CS].selector = *(uint16_t *)value; break; case UC_X86_REG_DS: X86_CPU(uc, mycpu)->env.segs[R_DS].selector = *(uint16_t *)value; break; case UC_X86_REG_SS: X86_CPU(uc, mycpu)->env.segs[R_SS].selector = *(uint16_t *)value; break; case UC_X86_REG_ES: X86_CPU(uc, mycpu)->env.segs[R_ES].selector = *(uint16_t *)value; break; case UC_X86_REG_FS: X86_CPU(uc, mycpu)->env.segs[R_FS].selector = *(uint16_t *)value; break; case UC_X86_REG_GS: X86_CPU(uc, mycpu)->env.segs[R_GS].selector = *(uint16_t *)value; break; case UC_X86_REG_R8: X86_CPU(uc, mycpu)->env.regs[8] = *(uint64_t *)value; break; case UC_X86_REG_R8D: WRITE_DWORD(X86_CPU(uc, mycpu)->env.regs[8], *(uint32_t *)value); break; case UC_X86_REG_R8W: WRITE_WORD(X86_CPU(uc, mycpu)->env.regs[8], *(uint16_t *)value); break; case UC_X86_REG_R8B: WRITE_BYTE_L(X86_CPU(uc, mycpu)->env.regs[8], *(uint8_t *)value); break; case UC_X86_REG_R9: X86_CPU(uc, mycpu)->env.regs[9] = *(uint64_t *)value; break; case UC_X86_REG_R9D: WRITE_DWORD(X86_CPU(uc, mycpu)->env.regs[9], *(uint32_t *)value); break; case UC_X86_REG_R9W: WRITE_WORD(X86_CPU(uc, mycpu)->env.regs[9], *(uint16_t *)value); break; case UC_X86_REG_R9B: WRITE_BYTE_L(X86_CPU(uc, mycpu)->env.regs[9], *(uint8_t *)value); break; case UC_X86_REG_R10: X86_CPU(uc, mycpu)->env.regs[10] = *(uint64_t *)value; break; case UC_X86_REG_R10D: WRITE_DWORD(X86_CPU(uc, mycpu)->env.regs[10], *(uint32_t *)value); break; case UC_X86_REG_R10W: WRITE_WORD(X86_CPU(uc, mycpu)->env.regs[10], *(uint16_t *)value); break; case UC_X86_REG_R10B: WRITE_BYTE_L(X86_CPU(uc, mycpu)->env.regs[10], *(uint8_t *)value); break; case UC_X86_REG_R11: X86_CPU(uc, mycpu)->env.regs[11] = *(uint64_t *)value; break; case UC_X86_REG_R11D: WRITE_DWORD(X86_CPU(uc, mycpu)->env.regs[11], *(uint32_t *)value); break; case UC_X86_REG_R11W: WRITE_WORD(X86_CPU(uc, mycpu)->env.regs[11], *(uint16_t *)value); break; case UC_X86_REG_R11B: WRITE_BYTE_L(X86_CPU(uc, mycpu)->env.regs[11], *(uint8_t *)value); break; case UC_X86_REG_R12: X86_CPU(uc, mycpu)->env.regs[12] = *(uint64_t *)value; break; case UC_X86_REG_R12D: WRITE_DWORD(X86_CPU(uc, mycpu)->env.regs[12], *(uint32_t *)value); break; case UC_X86_REG_R12W: WRITE_WORD(X86_CPU(uc, mycpu)->env.regs[12], *(uint16_t *)value); break; case UC_X86_REG_R12B: WRITE_BYTE_L(X86_CPU(uc, mycpu)->env.regs[12], *(uint8_t *)value); break; case UC_X86_REG_R13: X86_CPU(uc, mycpu)->env.regs[13] = *(uint64_t *)value; break; case UC_X86_REG_R13D: WRITE_DWORD(X86_CPU(uc, mycpu)->env.regs[13], *(uint32_t *)value); break; case UC_X86_REG_R13W: WRITE_WORD(X86_CPU(uc, mycpu)->env.regs[13], *(uint16_t *)value); break; case UC_X86_REG_R13B: WRITE_BYTE_L(X86_CPU(uc, mycpu)->env.regs[13], *(uint8_t *)value); break; case UC_X86_REG_R14: X86_CPU(uc, mycpu)->env.regs[14] = *(uint64_t *)value; break; case UC_X86_REG_R14D: WRITE_DWORD(X86_CPU(uc, mycpu)->env.regs[14], *(uint32_t *)value); break; case UC_X86_REG_R14W: WRITE_WORD(X86_CPU(uc, mycpu)->env.regs[14], *(uint16_t *)value); break; case UC_X86_REG_R14B: WRITE_BYTE_L(X86_CPU(uc, mycpu)->env.regs[14], *(uint8_t *)value); break; case UC_X86_REG_R15: X86_CPU(uc, mycpu)->env.regs[15] = *(uint64_t *)value; break; case UC_X86_REG_R15D: WRITE_DWORD(X86_CPU(uc, mycpu)->env.regs[15], *(uint32_t *)value); break; case UC_X86_REG_R15W: WRITE_WORD(X86_CPU(uc, mycpu)->env.regs[15], *(uint16_t *)value); break; case UC_X86_REG_R15B: WRITE_BYTE_L(X86_CPU(uc, mycpu)->env.regs[15], *(uint8_t *)value); break; case UC_X86_REG_IDTR: X86_CPU(uc, mycpu)->env.idt.limit = (uint16_t)((uc_x86_mmr *)value)->limit; X86_CPU(uc, mycpu)->env.idt.base = ((uc_x86_mmr *)value)->base; break; case UC_X86_REG_GDTR: X86_CPU(uc, mycpu)->env.gdt.limit = (uint16_t)((uc_x86_mmr *)value)->limit; X86_CPU(uc, mycpu)->env.gdt.base = ((uc_x86_mmr *)value)->base; break; case UC_X86_REG_LDTR: X86_CPU(uc, mycpu)->env.ldt.limit = ((uc_x86_mmr *)value)->limit; X86_CPU(uc, mycpu)->env.ldt.base = ((uc_x86_mmr *)value)->base; X86_CPU(uc, mycpu)->env.ldt.selector = (uint16_t)((uc_x86_mmr *)value)->selector; X86_CPU(uc, mycpu)->env.ldt.flags = ((uc_x86_mmr *)value)->flags; break; case UC_X86_REG_TR: X86_CPU(uc, mycpu)->env.tr.limit = ((uc_x86_mmr *)value)->limit; X86_CPU(uc, mycpu)->env.tr.base = ((uc_x86_mmr *)value)->base; X86_CPU(uc, mycpu)->env.tr.selector = (uint16_t)((uc_x86_mmr *)value)->selector; X86_CPU(uc, mycpu)->env.tr.flags = ((uc_x86_mmr *)value)->flags; break; } break; #endif } return 0; }