diff --git a/src/emu/x86emu.c b/src/emu/x86emu.c index 0be1e14b..a846a7ce 100755 --- a/src/emu/x86emu.c +++ b/src/emu/x86emu.c @@ -40,6 +40,11 @@ void PushExit(x86emu_t* emu) Push(emu, (uint32_t)&EndEmuMarker); } +void* GetExit() +{ + return &EndEmuMarker; +} + x86emu_t *NewX86Emu(box86context_t *context, uintptr_t start, uintptr_t stack, int stacksize, int ownstack) { printf_log(LOG_DEBUG, "Allocate a new X86 Emu, with EIP=%p and Stack=%p/0x%X\n", (void*)start, (void*)stack, stacksize); diff --git a/src/emu/x86emu_private.h b/src/emu/x86emu_private.h index 8d57d729..fdb20612 100755 --- a/src/emu/x86emu_private.h +++ b/src/emu/x86emu_private.h @@ -5,6 +5,7 @@ typedef struct zydis_dec_s zydis_dec_t; typedef struct box86context_s box86context_t; +typedef struct i386_ucontext_s i386_ucontext_t; #define ERR_UNIMPL 1 #define ERR_DIVBY0 2 @@ -76,6 +77,8 @@ typedef struct x86emu_s { void* init_stack; // initial stack (owned or not) uint32_t size_stack; // stack size (owned or not) + i386_ucontext_t *uc_link; // to handle setcontext + } x86emu_t; //#define INTR_RAISE_DIV0(emu) {emu->error |= ERR_DIVBY0; emu->quit=1;} diff --git a/src/emu/x86run.c b/src/emu/x86run.c index c2703977..a8f2a045 100755 --- a/src/emu/x86run.c +++ b/src/emu/x86run.c @@ -1351,6 +1351,7 @@ stepout: fini: // PackFlags(emu); + // fork handling if(emu->fork) { if(step) return 0; @@ -1360,5 +1361,11 @@ fini: emu = x86emu_fork(emu, forktype); goto x86emurun; } + // setcontext handling + else if(emu->uc_link) { + emu->quit = 0; + my_setcontext(emu, emu->uc_link); + goto x86emurun; + } return 0; } diff --git a/src/include/x86emu.h b/src/include/x86emu.h index ed04b256..7e03a042 100755 --- a/src/include/x86emu.h +++ b/src/include/x86emu.h @@ -29,6 +29,7 @@ const char* DumpCPURegs(x86emu_t* emu, uintptr_t ip); void StopEmu(x86emu_t* emu, const char* reason); void PushExit(x86emu_t* emu); +void* GetExit(); void EmuCall(x86emu_t* emu, uintptr_t addr); void AddCleanup(x86emu_t *emu, void *p); void AddCleanup1Arg(x86emu_t *emu, void *p, void* a); diff --git a/src/libtools/signals.c b/src/libtools/signals.c index 65bc4d6f..007ee452 100755 --- a/src/libtools/signals.c +++ b/src/libtools/signals.c @@ -94,10 +94,10 @@ typedef struct typedef uint32_t i386_sigset_t; -typedef struct i386_ucontext_t +typedef struct i386_ucontext_s { uint32_t uc_flags; - struct i386_ucontext_t *uc_link; + struct i386_ucontext_s *uc_link; i386_stack_t uc_stack; i386_mcontext_t uc_mcontext; i386_sigset_t uc_sigmask; @@ -203,8 +203,11 @@ __attribute__((alias("my_sigaction"))); EXPORT int my_getcontext(x86emu_t* emu, void* ucp) { - printf_log(LOG_NONE, "Warning: call to partially implemented getcontext\n"); - struct i386_ucontext_t *u = (struct i386_ucontext_t*)ucp; +// printf_log(LOG_NONE, "Warning: call to partially implemented getcontext\n"); + i386_ucontext_t *u = (i386_ucontext_t*)ucp; + // stack traking + u->uc_stack.ss_sp = NULL; + u->uc_stack.ss_size = 0; // this need to filled // get general register u->uc_mcontext.gregs[REG_EAX] = R_EAX; u->uc_mcontext.gregs[REG_ECX] = R_ECX; @@ -226,8 +229,11 @@ EXPORT int my_getcontext(x86emu_t* emu, void* ucp) EXPORT int my_setcontext(x86emu_t* emu, void* ucp) { - printf_log(LOG_NONE, "Warning: call to partially implemented setcontext\n"); - struct i386_ucontext_t *u = (struct i386_ucontext_t*)ucp; +// printf_log(LOG_NONE, "Warning: call to partially implemented setcontext\n"); + i386_ucontext_t *u = (i386_ucontext_t*)ucp; + // stack tracking + emu->init_stack = u->uc_stack.ss_sp; + emu->size_stack = u->uc_stack.ss_size; // set general register R_EAX = u->uc_mcontext.gregs[REG_EAX]; R_ECX = u->uc_mcontext.gregs[REG_ECX]; @@ -243,12 +249,41 @@ EXPORT int my_setcontext(x86emu_t* emu, void* ucp) // set FloatPoint status // set signal mask //sigprocmask(SIG_SETMASK, NULL, (sigset_t*)&u->uc_sigmask); + // set uc_link + emu->uc_link = u->uc_link; return R_EAX; } -EXPORT int my_makecontext(x86emu_t* emu, void* ucp, void* fnc, int32_t argc, void* argv) +EXPORT int my_makecontext(x86emu_t* emu, void* ucp, void* fnc, int32_t argc, int32_t* argv) { - printf_log(LOG_NONE, "Warning: call to unimplemented makecontext\n"); +// printf_log(LOG_NONE, "Warning: call to unimplemented makecontext\n"); + i386_ucontext_t *u = (i386_ucontext_t*)ucp; + // setup stack + u->uc_mcontext.gregs[REG_ESP] = (uintptr_t)u->uc_stack.ss_sp + u->uc_stack.ss_size - 4; + // setup the function + u->uc_mcontext.gregs[REG_EIP] = (intptr_t)fnc; + // setup args + uint32_t* esp = (uint32_t*)u->uc_mcontext.gregs[REG_ESP]; + for (int i=0; iuc_mcontext.gregs[REG_ESP] = (uintptr_t)esp; + return 0; } + +EXPORT int my_swapcontext(x86emu_t* emu, void* ucp1, void* ucp2) +{ +// printf_log(LOG_NONE, "Warning: call to unimplemented swapcontext\n"); + // grab current context in ucp1 + my_getcontext(emu, ucp1); + // activate ucp2 + my_setcontext(emu, ucp2); + return 0; +} \ No newline at end of file diff --git a/src/wrapped/generated/wrapper.c b/src/wrapped/generated/wrapper.c index e31eea43..e80baa8b 100644 --- a/src/wrapped/generated/wrapper.c +++ b/src/wrapped/generated/wrapper.c @@ -517,8 +517,8 @@ typedef int32_t (*iFEippp_t)(x86emu_t*, int32_t, void*, void*, void*); typedef int32_t (*iFEpipp_t)(x86emu_t*, void*, int32_t, void*, void*); typedef int32_t (*iFEpupV_t)(x86emu_t*, void*, uint32_t, void*, void*); typedef int32_t (*iFEppii_t)(x86emu_t*, void*, void*, int32_t, int32_t); +typedef int32_t (*iFEppiV_t)(x86emu_t*, void*, void*, int32_t, void*); typedef int32_t (*iFEpppp_t)(x86emu_t*, void*, void*, void*, void*); -typedef int32_t (*iFEpppV_t)(x86emu_t*, void*, void*, void*, void*); typedef int32_t (*iFEppVV_t)(x86emu_t*, void*, void*, void*, void*); typedef int32_t (*iFiiipu_t)(int32_t, int32_t, int32_t, void*, uint32_t); typedef int32_t (*iFiiipp_t)(int32_t, int32_t, int32_t, void*, void*); @@ -1441,8 +1441,8 @@ void iFEippp(x86emu_t *emu, uintptr_t fcn) { iFEippp_t fn = (iFEippp_t)fcn; R_EA void iFEpipp(x86emu_t *emu, uintptr_t fcn) { iFEpipp_t fn = (iFEpipp_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16)); } void iFEpupV(x86emu_t *emu, uintptr_t fcn) { iFEpupV_t fn = (iFEpupV_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(uint32_t*)(R_ESP + 8), *(void**)(R_ESP + 12), (void*)(R_ESP + 16)); } void iFEppii(x86emu_t *emu, uintptr_t fcn) { iFEppii_t fn = (iFEppii_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16)); } +void iFEppiV(x86emu_t *emu, uintptr_t fcn) { iFEppiV_t fn = (iFEppiV_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12), (void*)(R_ESP + 16)); } void iFEpppp(x86emu_t *emu, uintptr_t fcn) { iFEpppp_t fn = (iFEpppp_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16)); } -void iFEpppV(x86emu_t *emu, uintptr_t fcn) { iFEpppV_t fn = (iFEpppV_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), (void*)(R_ESP + 16)); } void iFEppVV(x86emu_t *emu, uintptr_t fcn) { iFEppVV_t fn = (iFEppVV_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 8), (void*)(R_ESP + 12), (void*)(R_ESP + 12)); } void iFiiipu(x86emu_t *emu, uintptr_t fcn) { iFiiipu_t fn = (iFiiipu_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(uint32_t*)(R_ESP + 20)); } void iFiiipp(x86emu_t *emu, uintptr_t fcn) { iFiiipp_t fn = (iFiiipp_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20)); } diff --git a/src/wrapped/generated/wrapper.h b/src/wrapped/generated/wrapper.h index 046d805a..35503584 100644 --- a/src/wrapped/generated/wrapper.h +++ b/src/wrapped/generated/wrapper.h @@ -513,8 +513,8 @@ void iFEippp(x86emu_t *emu, uintptr_t fnc); void iFEpipp(x86emu_t *emu, uintptr_t fnc); void iFEpupV(x86emu_t *emu, uintptr_t fnc); void iFEppii(x86emu_t *emu, uintptr_t fnc); +void iFEppiV(x86emu_t *emu, uintptr_t fnc); void iFEpppp(x86emu_t *emu, uintptr_t fnc); -void iFEpppV(x86emu_t *emu, uintptr_t fnc); void iFEppVV(x86emu_t *emu, uintptr_t fnc); void iFiiipu(x86emu_t *emu, uintptr_t fnc); void iFiiipp(x86emu_t *emu, uintptr_t fnc); diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c index ef5cb350..3e3c0f8b 100755 --- a/src/wrapped/wrappedlibc.c +++ b/src/wrapped/wrappedlibc.c @@ -139,6 +139,7 @@ int EXPORT my_atexit(x86emu_t* emu, void *p) int my_getcontext(x86emu_t* emu, void* ucp); int my_setcontext(x86emu_t* emu, void* ucp); int my_makecontext(x86emu_t* emu, void* ucp, void* fnc, int32_t argc, void* argv); +int my_swapcontext(x86emu_t* emu, void* ucp1, void* ucp2); // All signal and context functions defined in signals.c diff --git a/src/wrapped/wrappedlibc_private.h b/src/wrapped/wrappedlibc_private.h index 1dc1c8e3..05ce0dc9 100755 --- a/src/wrapped/wrappedlibc_private.h +++ b/src/wrapped/wrappedlibc_private.h @@ -1046,7 +1046,7 @@ GO(lsetxattr, iFpppui) GO(__lxstat, iFipp) GOM(__lxstat64, iFEipp) GO(madvise, iFpui) -GOM(makecontext, iFEpppV) +GOM(makecontext, iFEppiV) GOW(mallinfo, pFv) GO(malloc, pFu) // malloc_get_state // Weak @@ -1728,7 +1728,7 @@ GO(strxfrm_l, uFppup) // svcunixfd_create // svc_unregister GO(swab, vFppi) -GO(swapcontext, iFpp) +GOM(swapcontext, iFEpp) // swapoff // Weak // swapon // Weak GOM(swprintf, iFEpupV)