Added real support for getcontext / setcontext / makecontext and swapcontext (and now DotT Remastered wboots)

This commit is contained in:
ptitSeb 2019-11-16 13:52:25 +01:00
parent 3110ed8df7
commit 577c5ac45b
9 changed files with 65 additions and 13 deletions

View File

@ -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);

View File

@ -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;}

View File

@ -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;
}

View File

@ -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);

View File

@ -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; i<argc; ++i) {
// push value
--esp;
*esp = argv[(argc-1)-i];
}
// push the return value
--esp;
*esp = (uintptr_t)GetExit();
u->uc_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;
}

View File

@ -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)); }

View File

@ -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);

View File

@ -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

View File

@ -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)