Created
February 7, 2023 02:12
-
-
Save cseagle/7d76181e26d581b605391bccdba75fad to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Emulate 16-bit code | |
>>> Execution begins --- cs:ip is 0x13c8:0x1d (0x13c9d) | |
>>> Tracing basic block at 0x13c9d, block size = 0xf | |
--- cs:ip is 0x13c8:0x1d (0x13c9d) | |
>>> Tracing instruction at 0x13c9d, instruction size = 0x3 | |
--- cs:ip is 0x13c8:0x3c9d (0x1791d) | |
>>> Tracing instruction at 0x13ca0, instruction size = 0x4 | |
--- cs:ip is 0x13c8:0x3ca0 (0x17920) | |
>>> Tracing instruction at 0x13ca4, instruction size = 0x2 | |
--- cs:ip is 0x13c8:0x3ca4 (0x17924) | |
>>> Tracing instruction at 0x13ca6, instruction size = 0x4 | |
--- cs:ip is 0x13c8:0x3ca6 (0x17926) | |
>>> Tracing instruction at 0x13caa, instruction size = 0x2 | |
--- cs:ip is 0x13c8:0x3caa (0x1792a) | |
>>> Tracing basic block at 0x13cac, block size = 0x6 | |
--- cs:ip is 0x13c8:0x2c (0x13cac) | |
>>> Tracing instruction at 0x13cac, instruction size = 0x3 | |
--- cs:ip is 0x13c8:0x3cac (0x1792c) | |
>>> Tracing instruction at 0x13caf, instruction size = 0x1 | |
--- cs:ip is 0x13c8:0x3caf (0x1792f) | |
>>> Tracing instruction at 0x13cb0, instruction size = 0x2 | |
--- cs:ip is 0x13c8:0x3cb0 (0x17930) | |
>>> Tracing basic block at 0x13cb2, block size = 0x4 | |
--- cs:ip is 0x13c8:0x32 (0x13cb2) | |
>>> Tracing instruction at 0x13cb2, instruction size = 0x4 | |
--- cs:ip is 0x13c8:0x3cb2 (0x17932) | |
>>> Tracing basic block at 0x13cb6, block size = 0x1 | |
--- cs:ip is 0x13c8:0x36 (0x13cb6) | |
>>> Tracing instruction at 0x13cb6, instruction size = 0x1 | |
--- cs:ip is 0x13c8:0x3cb6 (0x17936) | |
>>> Tracing basic block at 0x13cb7, block size = 0x2 | |
--- cs:ip is 0x13c8:0x37 (0x13cb7) | |
>>> Tracing instruction at 0x13cb7, instruction size = 0x2 | |
--- cs:ip is 0x13c8:0x3cb7 (0x17937) | |
>>> Tracing basic block at 0x13ccb, block size = 0x40 | |
--- cs:ip is 0x13c8:0x4b (0x13ccb) | |
>>> Tracing instruction at 0x13ccb, instruction size = 0x2 | |
--- cs:ip is 0x13c8:0x3ccb (0x1794b) | |
>>> Tracing instruction at 0x13ccd, instruction size = 0x2 | |
--- cs:ip is 0x13c8:0x3ccd (0x1794d) | |
>>> Tracing instruction at 0x13ccf, instruction size = 0x2 | |
--- cs:ip is 0x13c8:0x3ccf (0x1794f) | |
>>> Tracing instruction at 0x13cd1, instruction size = 0x1 | |
--- cs:ip is 0x13c8:0x3cd1 (0x17951) | |
>>> Tracing instruction at 0x13cd2, instruction size = 0x4 | |
--- cs:ip is 0x13c8:0x3cd2 (0x17952) | |
>>> Tracing instruction at 0x13cd6, instruction size = 0x3 | |
--- cs:ip is 0x13c8:0x3cd6 (0x17956) | |
>>> Tracing instruction at 0x13cd9, instruction size = 0x3 | |
--- cs:ip is 0x13c8:0x3cd9 (0x17959) | |
>>> Tracing instruction at 0x13cdc, instruction size = 0x3 | |
--- cs:ip is 0x13c8:0x3cdc (0x1795c) | |
>>> Tracing instruction at 0x13cdf, instruction size = 0x4 | |
--- cs:ip is 0x13c8:0x3cdf (0x1795f) | |
>>> Tracing instruction at 0x13ce3, instruction size = 0x3 | |
--- cs:ip is 0x13c8:0x3ce3 (0x17963) | |
>>> Tracing instruction at 0x13ce6, instruction size = 0x1 | |
--- cs:ip is 0x13c8:0x3ce6 (0x17966) | |
>>> Tracing instruction at 0x13ce7, instruction size = 0x4 | |
--- cs:ip is 0x13c8:0x3ce7 (0x17967) | |
>>> Tracing instruction at 0x13ceb, instruction size = 0x2 | |
--- cs:ip is 0x13c8:0x3ceb (0x1796b) | |
>>> Tracing instruction at 0x13ced, instruction size = 0x1 | |
--- cs:ip is 0x13c8:0x3ced (0x1796d) | |
>>> Tracing instruction at 0x13cee, instruction size = 0x4 | |
--- cs:ip is 0x13c8:0x3cee (0x1796e) | |
>>> Tracing instruction at 0x13cf2, instruction size = 0x4 | |
--- cs:ip is 0x13c8:0x3cf2 (0x17972) | |
>>> Tracing instruction at 0x13cf6, instruction size = 0x5 | |
--- cs:ip is 0x13c8:0x3cf6 (0x17976) | |
>>> Tracing instruction at 0x13cfb, instruction size = 0x2 | |
--- cs:ip is 0x13c8:0x3cfb (0x1797b) | |
>>> Tracing instruction at 0x13cfd, instruction size = 0x4 | |
--- cs:ip is 0x13c8:0x3cfd (0x1797d) | |
>>> Tracing instruction at 0x13d01, instruction size = 0x2 | |
--- cs:ip is 0x13c8:0x3d01 (0x17981) | |
>>> Tracing instruction at 0x13d03, instruction size = 0x2 | |
--- cs:ip is 0x13c8:0x3d03 (0x17983) | |
>>> Tracing instruction at 0x13d05, instruction size = 0x2 | |
--- cs:ip is 0x13c8:0x3d05 (0x17985) | |
>>> Tracing instruction at 0x13d07, instruction size = 0x2 | |
--- cs:ip is 0x13c8:0x3d07 (0x17987) | |
>>> Tracing instruction at 0x13d09, instruction size = 0x2 | |
--- cs:ip is 0x13c8:0x3d09 (0x17989) | |
Failed on uc_emu_start() with error returned 21: Unhandled CPU exception (UC_ERR_EXCEPTION) | |
>>> Emulation done. Below is the CPU context | |
>>> CS = 0x13c8 | |
>>> IP = 0x8b |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <unicorn/unicorn.h> | |
#include <string.h> | |
// callback for tracing basic blocks | |
static void hook_block(uc_engine *uc, uint64_t address, uint32_t size, | |
void *user_data) | |
{ | |
unsigned short ip; | |
unsigned short cs; | |
printf(">>> Tracing basic block at 0x%" PRIx64 ", block size = 0x%x\n", | |
address, size); | |
uc_reg_read(uc, UC_X86_REG_IP, &ip); | |
uc_reg_read(uc, UC_X86_REG_CS, &cs); | |
printf(" --- cs:ip is 0x%x:0x%x (0x%x)\n", cs, ip, 16 * cs + ip); | |
} | |
// callback for tracing instruction | |
static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, | |
void *user_data) | |
{ | |
unsigned short ip; | |
unsigned short cs; | |
printf(" >>> Tracing instruction at 0x%" PRIx64 | |
", instruction size = 0x%x\n", | |
address, size); | |
uc_reg_read(uc, UC_X86_REG_IP, &ip); | |
uc_reg_read(uc, UC_X86_REG_CS, &cs); | |
printf(" --- cs:ip is 0x%x:0x%x (0x%x)\n", cs, ip, 16 * cs + ip); | |
} | |
// callback for SYSCALL instruction (X86). | |
static void hook_syscall(uc_engine *uc, void *user_data) | |
{ | |
uint32_t eax; | |
uc_reg_read(uc, UC_X86_REG_IP, &eax); | |
printf("syscall eax=0x%x\n", eax); | |
} | |
static void test_x86_16(const char *input, uint32_t loadaddr) | |
{ | |
uc_engine *uc; | |
uc_err err; | |
uint32_t tmp; | |
uc_hook trace1, trace2; | |
FILE *f; | |
f = fopen(input, "rb"); | |
if (f == NULL) { | |
return; | |
} | |
uint32_t sz; | |
fseek(f, 0, SEEK_END); | |
sz = ftell(f); | |
fseek(f, 0, SEEK_SET); | |
char *b = (char*)malloc(sz); | |
fread(b, 1, sz, f); | |
fclose(f); | |
uint16_t r_cs = 0x13c8; | |
uint16_t r_ip = 0x1d; | |
printf("Emulate 16-bit code\n"); | |
// Initialize emulator in X86-16bit mode | |
err = uc_open(UC_ARCH_X86, UC_MODE_16, &uc); | |
if (err) { | |
printf("Failed on uc_open() with error returned: %u\n", err); | |
return; | |
} | |
// map 1MB memory for this emulation | |
uc_mem_map(uc, 0, 1024 * 1024, UC_PROT_ALL); | |
// write machine code to be emulated to memory | |
if (uc_mem_write(uc, loadaddr, b, sz)) { | |
printf("Failed to write emulation code to memory, quit!\n"); | |
return; | |
} | |
// initialize machine registers | |
uc_reg_write(uc, UC_X86_REG_CS, &r_cs); | |
uc_reg_write(uc, UC_X86_REG_IP, &r_ip); | |
// tracing all basic blocks with customized callback | |
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, 1, 0); | |
// tracing all instruction by having @begin > @end | |
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0); | |
uc_reg_read(uc, UC_X86_REG_IP, &r_ip); | |
uc_reg_read(uc, UC_X86_REG_CS, &r_cs); | |
printf(">>> Execution begins --- cs:ip is 0x%x:0x%x (0x%x)\n", r_cs, r_ip, 16 * r_cs + r_ip); | |
// emulate machine code in infinite time | |
err = uc_emu_start(uc, 0x13C9D, 0x10000 + sz, 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_CS, &r_cs); | |
uc_reg_read(uc, UC_X86_REG_IP, &r_ip); | |
printf(">>> CS = 0x%x\n", r_cs); | |
printf(">>> IP = 0x%x\n", r_ip); | |
uc_close(uc); | |
} | |
int main(int argc, char **argv, char **envp) | |
{ | |
test_x86_16(argv[1], 0x10000); | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment