mirror of
https://github.com/ptitSeb/box86.git
synced 2024-11-23 06:39:55 +00:00
Starting some threads
This commit is contained in:
parent
bef89e80e1
commit
f1bd98e603
@ -37,6 +37,7 @@ SET(ELFLOADER_SRC
|
||||
src/elfload_dump.c
|
||||
src/librarian.c
|
||||
src/stack.c
|
||||
src/threads.c
|
||||
src/wrapper.c
|
||||
src/x86emu.c
|
||||
src/x86run.c
|
||||
@ -50,7 +51,7 @@ SET(ELFLOADER_SRC
|
||||
)
|
||||
|
||||
add_executable(box86 ${ELFLOADER_SRC})
|
||||
target_link_libraries(box86 m dl rt)
|
||||
target_link_libraries(box86 m dl rt pthread)
|
||||
|
||||
add_test(test01 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/box86
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test01 -D TEST_OUTPUT=tmpfile.txt
|
||||
@ -75,4 +76,9 @@ add_test(test04 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/box86
|
||||
add_test(test05 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/box86
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test05 -D TEST_ARGS2=7 -D TEST_OUTPUT=tmpfile.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref05.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
add_test(test06 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/box86
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test06 -D TEST_OUTPUT=tmpfile.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref06.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
@ -8,6 +8,7 @@ typedef struct elfheader_s elfheader_t;
|
||||
typedef struct x86emu_s x86emu_t;
|
||||
typedef struct zydis_s zydis_t;
|
||||
typedef struct lib_s lib_t;
|
||||
typedef struct bridge_s bridge_t;
|
||||
|
||||
typedef struct box86context_s {
|
||||
path_collection_t box86_path; // PATH env. variable
|
||||
@ -36,6 +37,8 @@ typedef struct box86context_s {
|
||||
|
||||
lib_t *maplib; // lib and symbols handling
|
||||
|
||||
bridge_t *threads; // threads
|
||||
|
||||
} box86context_t;
|
||||
|
||||
box86context_t *NewBox86Context(int argc);
|
||||
|
11
src/bridge.c
11
src/bridge.c
@ -3,18 +3,9 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "bridge.h"
|
||||
#include "bridge_private.h"
|
||||
#include "wrapper.h"
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct onebridge_s {
|
||||
uint8_t CC; // CC int 0x3
|
||||
uint8_t S, C; // 'S' 'C', just a signature
|
||||
wrapper_t w; // wrapper
|
||||
uintptr_t f; // the function for the wrapper
|
||||
uint8_t C3; // C3 ret
|
||||
} onebridge_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
#define NBRICK 16
|
||||
typedef struct brick_s brick_t;
|
||||
typedef struct brick_s {
|
||||
|
17
src/bridge_private.h
Executable file
17
src/bridge_private.h
Executable file
@ -0,0 +1,17 @@
|
||||
#ifndef __BRIDGE_PRIVATE_H_
|
||||
#define __BRIDGE_PRIVATE_H_
|
||||
#include <stdint.h>
|
||||
|
||||
#include "wrapper.h"
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct onebridge_s {
|
||||
uint8_t CC; // CC int 0x3
|
||||
uint8_t S, C; // 'S' 'C', just a signature
|
||||
wrapper_t w; // wrapper
|
||||
uintptr_t f; // the function for the wrapper
|
||||
uint8_t C3; // C3 ret
|
||||
} onebridge_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif //__BRIDGE_PRIVATE_H_
|
@ -301,8 +301,9 @@ void AddGlobalsSymbols(lib_t* maplib, elfheader_t* h)
|
||||
if(((h->SymTab[i].st_info == 18) || h->SymTab[i].st_info == 17) && (h->SymTab[i].st_other==0) && (h->SymTab[i].st_shndx!=0)) {
|
||||
const char * symname = h->StrTab+h->SymTab[i].st_name;
|
||||
uintptr_t offs = h->SymTab[i].st_value + h->delta;
|
||||
printf_log(LOG_DUMP, "Adding Symbol \"%s\" with offset=%p\n", symname, offs);
|
||||
AddSymbol(maplib, symname, offs);
|
||||
uint32_t sz = h->SymTab[i].st_size;
|
||||
printf_log(LOG_DUMP, "Adding Symbol \"%s\" with offset=%p sz=%d\n", symname, offs, sz);
|
||||
AddSymbol(maplib, symname, offs, sz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "librarian.h"
|
||||
#include "librarian_private.h"
|
||||
@ -39,11 +41,13 @@ int32_t my__libc_start_main(x86emu_t* emu, int *(main) (int, char * *, char * *)
|
||||
int argc, char * * ubp_av, void (*init) (void), void (*fini) (void),
|
||||
void (*rtld_fini) (void), void (* stack_end)); // implemented in x86run_private.c
|
||||
uint32_t LibSyscall(x86emu_t *emu); // implemented in x86syscall.c
|
||||
int my_pthread_create(x86emu_t *emu, void* t, void* attr, void* start_routine, void* arg); //implemented in thread.c
|
||||
|
||||
uintptr_t CreateSymbol(lib_t *maplib, const char* name)
|
||||
{
|
||||
// look for symbols that can be created
|
||||
uintptr_t addr = 0;
|
||||
// libc
|
||||
if(strcmp(name, "__stack_chk_fail")==0) {
|
||||
addr = AddBridge(maplib->bridge, vFE, my__stack_chk_fail);
|
||||
} else if(strcmp(name, "__libc_start_main")==0) {
|
||||
@ -64,17 +68,30 @@ uintptr_t CreateSymbol(lib_t *maplib, const char* name)
|
||||
addr = AddBridge(maplib->bridge, iFi, putchar);
|
||||
} else if(strcmp(name, "strtol")==0) {
|
||||
addr = AddBridge(maplib->bridge, iFppi, strtol);
|
||||
} else if(strcmp(name, "strerror")==0) {
|
||||
addr = AddBridge(maplib->bridge, pFv, strerror);
|
||||
} //pthread
|
||||
else if(strcmp(name, "pthread_self")==0) {
|
||||
addr = AddBridge(maplib->bridge, uFv, pthread_self);
|
||||
} else if(strcmp(name, "pthread_create")==0) {
|
||||
addr = AddBridge(maplib->bridge, iFEpppp, my_pthread_create);
|
||||
} else if(strcmp(name, "pthread_equal")==0) {
|
||||
addr = AddBridge(maplib->bridge, iFuu, pthread_equal);
|
||||
} else if(strcmp(name, "pthread_join")==0) {
|
||||
addr = AddBridge(maplib->bridge, iFup, pthread_join);
|
||||
}
|
||||
|
||||
if(addr)
|
||||
AddSymbol(maplib, name, addr);
|
||||
AddSymbol(maplib, name, addr, 12);
|
||||
return addr;
|
||||
}
|
||||
|
||||
void AddSymbol(lib_t *maplib, const char* name, uintptr_t addr)
|
||||
void AddSymbol(lib_t *maplib, const char* name, uintptr_t addr, uint32_t sz)
|
||||
{
|
||||
int ret;
|
||||
khint_t k = kh_put(maplib_t, maplib->maplib, name, &ret);
|
||||
kh_value(maplib->maplib, k).offs = addr;
|
||||
kh_value(maplib->maplib, k).sz = sz;
|
||||
}
|
||||
uintptr_t FindSymbol(lib_t *maplib, const char* name)
|
||||
{
|
||||
@ -83,3 +100,13 @@ uintptr_t FindSymbol(lib_t *maplib, const char* name)
|
||||
return CreateSymbol(maplib, name);
|
||||
return kh_val(maplib->maplib, k).offs;
|
||||
}
|
||||
|
||||
int GetSymbolStartEnd(lib_t* maplib, const char* name, uintptr_t* start, uintptr_t* end)
|
||||
{
|
||||
khint_t k = kh_get(maplib_t, maplib->maplib, name);
|
||||
if(k==kh_end(maplib->maplib))
|
||||
return 0;
|
||||
*start = kh_val(maplib->maplib, k).offs;
|
||||
*end = *start + kh_val(maplib->maplib, k).sz;
|
||||
return 1;
|
||||
}
|
@ -8,7 +8,8 @@ typedef struct bridge_s bridge_t;
|
||||
lib_t *NewLibrarian();
|
||||
void FreeLibrarian(lib_t **maplib);
|
||||
|
||||
void AddSymbol(lib_t *maplib, const char* name, uintptr_t addr);
|
||||
void AddSymbol(lib_t *maplib, const char* name, uintptr_t addr, uint32_t sz);
|
||||
uintptr_t FindSymbol(lib_t *maplib, const char* name);
|
||||
int GetSymbolStartEnd(lib_t* maplib, const char* name, uintptr_t* start, uintptr_t* end);
|
||||
|
||||
#endif //__LIBRARIAN_H_
|
@ -5,6 +5,7 @@
|
||||
|
||||
typedef struct {
|
||||
uintptr_t offs;
|
||||
uint32_t sz;
|
||||
// need to track type of symbol?
|
||||
// need to track origin?
|
||||
} onelib_t;
|
||||
|
18
src/main.c
18
src/main.c
@ -129,7 +129,7 @@ int main(int argc, const char **argv, const char **env) {
|
||||
// init random seed
|
||||
srandom(time(NULL));
|
||||
|
||||
// check BOX86_loG debug level
|
||||
// check BOX86_LOG debug level
|
||||
LoadLogEnv();
|
||||
|
||||
// Create a new context
|
||||
@ -153,8 +153,7 @@ int main(int argc, const char **argv, const char **env) {
|
||||
|
||||
p = getenv("BOX86_TRACE");
|
||||
if(p) {
|
||||
setbuf(stdout, NULL);
|
||||
if (strcmp(p, "1")==0)
|
||||
if (strcmp(p, "0"))
|
||||
context->x86trace = 1;
|
||||
}
|
||||
if(context->x86trace) {
|
||||
@ -243,9 +242,20 @@ int main(int argc, const char **argv, const char **env) {
|
||||
// setup the stack...
|
||||
Push(context->emu, (uint32_t)context->argv);
|
||||
Push(context->emu, context->argc);
|
||||
SetupX86Emu(context->emu);
|
||||
SetupX86Emu(context->emu, NULL, NULL);
|
||||
SetEAX(context->emu, context->argc);
|
||||
SetEBX(context->emu, (uint32_t)context->argv);
|
||||
|
||||
p = getenv("BOX86_TRACE");
|
||||
if(p) {
|
||||
setbuf(stdout, NULL);
|
||||
uintptr_t trace_start, trace_end;
|
||||
if (strcmp(p, "1")==0)
|
||||
SetTraceEmu(context->emu, 0, 0);
|
||||
else if (GetSymbolStartEnd(context->maplib, p, &trace_start, &trace_end))
|
||||
SetTraceEmu(context->emu, trace_start, trace_end);
|
||||
}
|
||||
|
||||
// emulate!
|
||||
printf_log(LOG_DEBUG, "Start x86emu on Main\n");
|
||||
Run(context->emu);
|
||||
|
57
src/threads.c
Executable file
57
src/threads.c
Executable file
@ -0,0 +1,57 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "box86context.h"
|
||||
#include "threads.h"
|
||||
#include "x86emu_private.h"
|
||||
#include "bridge_private.h"
|
||||
#include "x86run.h"
|
||||
#include "x86emu.h"
|
||||
#include "stack.h"
|
||||
|
||||
// memory handling to be perfected...
|
||||
// keep a hash thread_t -> emu to set emu->quit to 1 on pthread_cancel
|
||||
|
||||
typedef struct emuthread_s {
|
||||
x86emu_t *emu;
|
||||
onebridge_t routine;
|
||||
int stacksize;
|
||||
void *stack;
|
||||
} emuthread_t;
|
||||
|
||||
void* pthread_routine(void* p)
|
||||
{
|
||||
emuthread_t *et = (emuthread_t*)p;
|
||||
Run(et->emu);
|
||||
void* r = (void*)GetEAX(et->emu);
|
||||
FreeX86Emu(&et->emu);
|
||||
free(et->stack);
|
||||
free(et);
|
||||
return r;
|
||||
}
|
||||
|
||||
int my_pthread_create(x86emu_t *emu, void* t, void* attr, void* start_routine, void* arg)
|
||||
{
|
||||
emuthread_t *emuthread = (emuthread_t*)calloc(1, sizeof(emuthread_t));
|
||||
emuthread->routine.CC = 0xCC;
|
||||
emuthread->routine.S = 'S'; emuthread->routine.C = 'C';
|
||||
emuthread->routine.w = pFp;
|
||||
emuthread->routine.f = (uintptr_t)start_routine;
|
||||
emuthread->routine.C3 = 0xC3;
|
||||
|
||||
emuthread->stacksize = 2*1024*1024; //default stack size is 2Mo
|
||||
// TODO: get stack size inside attr
|
||||
emuthread->stack = calloc(1, emuthread->stacksize);
|
||||
emuthread->emu = NewX86Emu(emu->context, (uintptr_t)start_routine, (uintptr_t)emuthread->stack,
|
||||
emuthread->stacksize);
|
||||
SetupX86Emu(emuthread->emu, emu->shared_global, emu->globals);
|
||||
emuthread->emu->trace_start = emu->trace_start;
|
||||
emuthread->emu->trace_end = emu->trace_end;
|
||||
Push(emuthread->emu, (uintptr_t)arg);
|
||||
PushExit(emuthread->emu);
|
||||
|
||||
// create thread
|
||||
return pthread_create((pthread_t*)t, (const pthread_attr_t *)attr,
|
||||
pthread_routine, emuthread);
|
||||
}
|
7
src/threads.h
Executable file
7
src/threads.h
Executable file
@ -0,0 +1,7 @@
|
||||
#ifndef _THREADS_H_
|
||||
#define _THREADS_H_
|
||||
|
||||
#include "bridge.h"
|
||||
|
||||
|
||||
#endif //_THREADS_H_
|
@ -23,15 +23,23 @@ typedef void (*vFv_t)();
|
||||
typedef void (*vFp_t)(void*);
|
||||
typedef void (*vFE_t)(x86emu_t*);
|
||||
typedef int32_t (*iFv_t)();
|
||||
typedef uint32_t (*uFv_t)();
|
||||
typedef void* (*pFv_t)();
|
||||
typedef uint32_t (*uFE_t)(x86emu_t*);
|
||||
typedef void (*vFi_t)(int32_t);
|
||||
typedef int32_t (*iFi_t)(int32_t);
|
||||
typedef int32_t (*iFp_t)(void*);
|
||||
typedef void* (*pFp_t)(void*);
|
||||
typedef int32_t (*iFpp_t)(void*, void*);
|
||||
typedef int32_t (*iFii_t)(int32_t, int32_t);
|
||||
typedef int32_t (*iFip_t)(int32_t, void*);
|
||||
typedef int32_t (*iFuu_t)(uint32_t, uint32_t);
|
||||
typedef int32_t (*iFup_t)(uint32_t, void*);
|
||||
typedef int32_t (*iFppi_t)(void*, void*, int32_t);
|
||||
typedef void* (*pFuu_t)(uint32_t, uint32_t);
|
||||
typedef int32_t (*iFipp_t)(int, void*, void*);
|
||||
typedef int32_t (*iFppp_t)(void*, void*, void*);
|
||||
typedef int32_t (*iFEpppp_t)(x86emu_t*, void*, void*, void*, void*);
|
||||
typedef int32_t (*iFEpippppp_t)(x86emu_t*, void*, int32_t, void*, void*, void*, void*, void*);
|
||||
|
||||
#define DEF(A) A f = (A)fnc
|
||||
@ -54,7 +62,12 @@ void vFE(x86emu_t *emu, uintptr_t fnc)
|
||||
void iFv(x86emu_t *emu, uintptr_t fnc)
|
||||
{
|
||||
DEF(iFv_t);
|
||||
*(int32_t*)&R_EAX = f();
|
||||
R_EAX = *(uint32_t*)f();
|
||||
}
|
||||
void uFv(x86emu_t *emu, uintptr_t fnc)
|
||||
{
|
||||
DEF(uFv_t);
|
||||
R_EAX = f();
|
||||
}
|
||||
void uFE(x86emu_t *emu, uintptr_t fnc)
|
||||
{
|
||||
@ -66,6 +79,11 @@ void vFi(x86emu_t *emu, uintptr_t fnc)
|
||||
DEF(vFi_t);
|
||||
f(i32(0));
|
||||
}
|
||||
void pFv(x86emu_t *emu, uintptr_t fnc)
|
||||
{
|
||||
DEF(pFv_t);
|
||||
R_EAX = *(uint32_t*)f();
|
||||
}
|
||||
void iFi(x86emu_t *emu, uintptr_t fnc)
|
||||
{
|
||||
DEF(iFi_t);
|
||||
@ -76,6 +94,11 @@ void iFp(x86emu_t *emu, uintptr_t fnc)
|
||||
DEF(iFp_t);
|
||||
R_EAX = (uint32_t)f(p(0));
|
||||
}
|
||||
void pFp(x86emu_t *emu, uintptr_t fnc)
|
||||
{
|
||||
DEF(pFp_t);
|
||||
R_EAX = (uint32_t)f(p(0));
|
||||
}
|
||||
void iFpp(x86emu_t *emu, uintptr_t fnc)
|
||||
{
|
||||
DEF(iFpp_t);
|
||||
@ -91,6 +114,26 @@ void pFuu(x86emu_t *emu, uintptr_t fnc)
|
||||
DEF(pFuu_t);
|
||||
R_EAX = (uintptr_t)f(u32(0), u32(4));
|
||||
}
|
||||
void iFii(x86emu_t *emu, uintptr_t fnc)
|
||||
{
|
||||
DEF(iFii_t);
|
||||
R_EAX = (uint32_t)f(i32(0), i32(4));
|
||||
}
|
||||
void iFip(x86emu_t *emu, uintptr_t fnc)
|
||||
{
|
||||
DEF(iFip_t);
|
||||
R_EAX = (uint32_t)f(i32(0), p(4));
|
||||
}
|
||||
void iFuu(x86emu_t *emu, uintptr_t fnc)
|
||||
{
|
||||
DEF(iFuu_t);
|
||||
R_EAX = (uint32_t)f(u32(0), u32(4));
|
||||
}
|
||||
void iFup(x86emu_t *emu, uintptr_t fnc)
|
||||
{
|
||||
DEF(iFup_t);
|
||||
R_EAX = (uint32_t)f(u32(0), p(4));
|
||||
}
|
||||
void iFpV(x86emu_t *emu, uintptr_t fnc)
|
||||
{
|
||||
DEF(iFpp_t);
|
||||
@ -111,6 +154,11 @@ void iFvopV(x86emu_t *emu, uintptr_t fnc)
|
||||
DEF(iFppp_t);
|
||||
R_EAX = (uint32_t)f((void*)stdout, p(4), (void*)stack(8));
|
||||
}
|
||||
void iFEpppp(x86emu_t *emu, uintptr_t fnc)
|
||||
{
|
||||
DEF(iFEpppp_t);
|
||||
R_EAX = (uint32_t)f(emu, p(0), p(4), p(8), p(12));
|
||||
}
|
||||
void iFEpippppp(x86emu_t *emu, uintptr_t fnc)
|
||||
{
|
||||
DEF(iFEpippppp_t);
|
||||
|
@ -20,16 +20,24 @@ void vFp(x86emu_t *emu, uintptr_t fnc);
|
||||
void vFE(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFE(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFv(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFv(x86emu_t *emu, uintptr_t fnc);
|
||||
void pFv(x86emu_t *emu, uintptr_t fnc);
|
||||
void vFi(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFi(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFp(x86emu_t *emu, uintptr_t fnc);
|
||||
void pFp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFpp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFppi(x86emu_t *emu, uintptr_t fnc);
|
||||
void pFuu(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFii(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFip(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFuu(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFup(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFpv(x86emu_t *emu, uintptr_t fnc);
|
||||
void iF1pV(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFopV(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFvopV(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEpppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEpippppp(x86emu_t *emu, uintptr_t fnc); // this is __libc_start_main basically
|
||||
|
||||
|
||||
|
37
src/x86emu.c
37
src/x86emu.c
@ -51,20 +51,34 @@ x86emu_t *NewX86Emu(box86context_t *context, uintptr_t start, uintptr_t stack, i
|
||||
return emu;
|
||||
}
|
||||
|
||||
void SetupX86Emu(x86emu_t *emu)
|
||||
void SetupX86Emu(x86emu_t *emu, int* shared_global, void* globals)
|
||||
{
|
||||
printf_log(LOG_DEBUG, "Setup X86 Emu\n");
|
||||
|
||||
// push "end emu" marker address
|
||||
PushExit(emu);
|
||||
// Setup the GS segment:
|
||||
emu->globals = calloc(1, 256); // arbitrary 256 byte size?
|
||||
// calc canary...
|
||||
uint8_t canary[4];
|
||||
for (int i=0; i<4; ++i) canary[i] = 1 + getrand(255);
|
||||
canary[getrand(4)] = 0;
|
||||
memcpy(emu->globals+0x14, canary, sizeof(canary)); // put canary in place
|
||||
printf_log(LOG_DEBUG, "Setting up canary (for Stack protector) at GS:0x14, value:%08X\n", *(uint32_t*)canary);
|
||||
if(shared_global) {
|
||||
emu->globals = globals;
|
||||
emu->shared_global = shared_global;
|
||||
} else {
|
||||
emu->globals = calloc(1, 256); // arbitrary 256 byte size?
|
||||
// calc canary...
|
||||
uint8_t canary[4];
|
||||
for (int i=0; i<4; ++i) canary[i] = 1 + getrand(255);
|
||||
canary[getrand(4)] = 0;
|
||||
memcpy(emu->globals+0x14, canary, sizeof(canary)); // put canary in place
|
||||
printf_log(LOG_DEBUG, "Setting up canary (for Stack protector) at GS:0x14, value:%08X\n", *(uint32_t*)canary);
|
||||
emu->shared_global = (int*)calloc(1, sizeof(int));
|
||||
}
|
||||
(*emu->shared_global)++;
|
||||
}
|
||||
|
||||
void SetTraceEmu(x86emu_t *emu, uintptr_t trace_start, uintptr_t trace_end)
|
||||
{
|
||||
printf_log(LOG_INFO, "Setting trace only between %p and %p\n", trace_start, trace_end);
|
||||
emu->trace_start = trace_start;
|
||||
emu->trace_end = trace_end;
|
||||
}
|
||||
|
||||
void FreeX86Emu(x86emu_t **x86emu)
|
||||
@ -74,8 +88,11 @@ void FreeX86Emu(x86emu_t **x86emu)
|
||||
printf_log(LOG_DEBUG, "Free a X86 Emu (%p)\n", *x86emu);
|
||||
if((*x86emu)->dec)
|
||||
DeleteX86TraceDecoder(&(*x86emu)->dec);
|
||||
if((*x86emu)->globals)
|
||||
free((*x86emu)->globals);
|
||||
if((*x86emu)->shared_global && !(*(*x86emu)->shared_global)--) {
|
||||
if((*x86emu)->globals)
|
||||
free((*x86emu)->globals);
|
||||
free((*x86emu)->shared_global);
|
||||
}
|
||||
free(*x86emu);
|
||||
*x86emu = NULL;
|
||||
}
|
||||
|
@ -5,7 +5,8 @@ typedef struct x86emu_s x86emu_t;
|
||||
typedef struct box86context_s box86context_t;
|
||||
|
||||
x86emu_t *NewX86Emu(box86context_t *context, uintptr_t start, uintptr_t stack, int stacksize);
|
||||
void SetupX86Emu(x86emu_t *emu);
|
||||
void SetupX86Emu(x86emu_t *emu, int* shared_gloabl, void* globals);
|
||||
void SetTraceEmu(x86emu_t *emu, uintptr_t trace_start, uintptr_t trace_end);
|
||||
void FreeX86Emu(x86emu_t **x86emu);
|
||||
|
||||
uint32_t GetEAX(x86emu_t *emu);
|
||||
|
@ -34,8 +34,10 @@ typedef struct x86emu_s {
|
||||
int error;
|
||||
// trace
|
||||
zydis_dec_t *dec;
|
||||
uintptr_t trace_start, trace_end;
|
||||
// global stuffs, pointed with GS: segment
|
||||
void *globals;
|
||||
int *shared_global;
|
||||
// parent context
|
||||
box86context_t *context;
|
||||
} x86emu_t;
|
||||
|
20
src/x86run.c
20
src/x86run.c
@ -13,10 +13,13 @@
|
||||
|
||||
int Run(x86emu_t *emu)
|
||||
{
|
||||
printf_log(LOG_DEBUG, "Run X86, EIP=%p\n", emu, R_EIP);
|
||||
emu->quit = 0;
|
||||
while (!emu->quit)
|
||||
{
|
||||
if(emu->dec) {
|
||||
if(emu->dec && (
|
||||
(emu->trace_end == 0)
|
||||
|| ((R_EIP >= emu->trace_start) && (R_EIP < emu->trace_end))) ) {
|
||||
printf_log(LOG_NONE, "%s", DumpCPURegs(emu));
|
||||
if(Peek(emu, 0)==0xcc && Peek(emu, 1)=='S' && Peek(emu, 2)=='C') {
|
||||
uint32_t a = *(uint32_t*)(R_EIP+3);
|
||||
@ -26,7 +29,7 @@ int Run(x86emu_t *emu)
|
||||
printf_log(LOG_NONE, "%08p: Native call to %p\n", R_EIP, a);
|
||||
}
|
||||
} else {
|
||||
printf_log(LOG_NONE, "%08p: %s\n", R_EIP, DecodeX86Trace(emu->dec, R_EIP));
|
||||
printf_log(LOG_NONE, "%s\n", DecodeX86Trace(emu->dec, R_EIP));
|
||||
}
|
||||
}
|
||||
uint8_t opcode = Fetch8(emu);
|
||||
@ -242,6 +245,16 @@ int Run(x86emu_t *emu)
|
||||
if(!ACCESS_FLAG(F_ZF))
|
||||
R_EIP += tmp8s;
|
||||
break;
|
||||
case 0x76: /* JBE Ib */
|
||||
tmp8s = Fetch8s(emu);
|
||||
if((ACCESS_FLAG(F_ZF) || ACCESS_FLAG(F_CF)))
|
||||
R_EIP += tmp8s;
|
||||
break;
|
||||
case 0x77: /* JNBE Ib */
|
||||
tmp8s = Fetch8s(emu);
|
||||
if(!(ACCESS_FLAG(F_ZF) || ACCESS_FLAG(F_CF)))
|
||||
R_EIP += tmp8s;
|
||||
break;
|
||||
case 0x7C: /* JL Ib */
|
||||
tmp8s = Fetch8s(emu);
|
||||
if(ACCESS_FLAG(F_SF) != ACCESS_FLAG(F_OF))
|
||||
@ -326,6 +339,9 @@ int Run(x86emu_t *emu)
|
||||
GetG(emu, &op2, nextop);
|
||||
op2->dword[0] = (uint32_t)&op1->dword[0];
|
||||
break;
|
||||
|
||||
case 0x90: /* NOP */
|
||||
break;
|
||||
|
||||
case 0xA1: /* MOV EAX, Od */
|
||||
R_EAX = *(uint32_t*)Fetch32(emu);
|
||||
|
4
tests/ref06.txt
Executable file
4
tests/ref06.txt
Executable file
@ -0,0 +1,4 @@
|
||||
[02] Second thread executing
|
||||
[02] Thread done.
|
||||
|
||||
[00] Done.
|
BIN
tests/test06
Executable file
BIN
tests/test06
Executable file
Binary file not shown.
55
tests/test06.c
Executable file
55
tests/test06.c
Executable file
@ -0,0 +1,55 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
const int thread_count = 2;
|
||||
pthread_t tid[2];
|
||||
const char *thread_messages[2] = {
|
||||
"First thread executing",
|
||||
"Second thread executing"
|
||||
};
|
||||
|
||||
void *doSomething(void *arg)
|
||||
{
|
||||
pthread_t id = pthread_self();
|
||||
int num = -1;
|
||||
|
||||
for (int i = 0 ; i < thread_count ; ++i)
|
||||
{
|
||||
if (pthread_equal(id, tid[i]))
|
||||
{
|
||||
num = i + 1;
|
||||
if (num == 2) printf("[%02d] %s\n", num, thread_messages[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0 ; i < 0x10000 ; ++i);
|
||||
if (num == 2) printf("[%02d] Thread done.\n", num);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
int err;
|
||||
|
||||
for (int i = 0 ; i < thread_count ; ++i)
|
||||
{
|
||||
//printf("[00] Thread %d starting\n", i + 1);
|
||||
err = pthread_create(&tid[i], NULL, doSomething, NULL);
|
||||
if (err)
|
||||
{
|
||||
printf("[00] Couldn't create thread %d: %s\n", i + 1, strerror(err));
|
||||
}
|
||||
for (unsigned int i = 0 ; i < 0x1000 ; ++i);
|
||||
}
|
||||
|
||||
//printf("[00] Waiting for all threads to end...\n");
|
||||
for (int i = 0 ; i < thread_count ; ++i)
|
||||
pthread_join(tid[i], NULL);
|
||||
printf("\n[00] Done.\n");
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user