mirror of
https://github.com/ptitSeb/box86.git
synced 2025-05-08 21:08:57 +08: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/elfload_dump.c
|
||||||
src/librarian.c
|
src/librarian.c
|
||||||
src/stack.c
|
src/stack.c
|
||||||
|
src/threads.c
|
||||||
src/wrapper.c
|
src/wrapper.c
|
||||||
src/x86emu.c
|
src/x86emu.c
|
||||||
src/x86run.c
|
src/x86run.c
|
||||||
@ -50,7 +51,7 @@ SET(ELFLOADER_SRC
|
|||||||
)
|
)
|
||||||
|
|
||||||
add_executable(box86 ${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
|
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
|
-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
|
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_ARGS=${CMAKE_SOURCE_DIR}/tests/test05 -D TEST_ARGS2=7 -D TEST_OUTPUT=tmpfile.txt
|
||||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref05.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 )
|
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
@ -8,6 +8,7 @@ typedef struct elfheader_s elfheader_t;
|
|||||||
typedef struct x86emu_s x86emu_t;
|
typedef struct x86emu_s x86emu_t;
|
||||||
typedef struct zydis_s zydis_t;
|
typedef struct zydis_s zydis_t;
|
||||||
typedef struct lib_s lib_t;
|
typedef struct lib_s lib_t;
|
||||||
|
typedef struct bridge_s bridge_t;
|
||||||
|
|
||||||
typedef struct box86context_s {
|
typedef struct box86context_s {
|
||||||
path_collection_t box86_path; // PATH env. variable
|
path_collection_t box86_path; // PATH env. variable
|
||||||
@ -36,6 +37,8 @@ typedef struct box86context_s {
|
|||||||
|
|
||||||
lib_t *maplib; // lib and symbols handling
|
lib_t *maplib; // lib and symbols handling
|
||||||
|
|
||||||
|
bridge_t *threads; // threads
|
||||||
|
|
||||||
} box86context_t;
|
} box86context_t;
|
||||||
|
|
||||||
box86context_t *NewBox86Context(int argc);
|
box86context_t *NewBox86Context(int argc);
|
||||||
|
11
src/bridge.c
11
src/bridge.c
@ -3,18 +3,9 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "bridge.h"
|
#include "bridge.h"
|
||||||
|
#include "bridge_private.h"
|
||||||
#include "wrapper.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
|
#define NBRICK 16
|
||||||
typedef struct brick_s brick_t;
|
typedef struct brick_s brick_t;
|
||||||
typedef struct brick_s {
|
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)) {
|
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;
|
const char * symname = h->StrTab+h->SymTab[i].st_name;
|
||||||
uintptr_t offs = h->SymTab[i].st_value + h->delta;
|
uintptr_t offs = h->SymTab[i].st_value + h->delta;
|
||||||
printf_log(LOG_DUMP, "Adding Symbol \"%s\" with offset=%p\n", symname, offs);
|
uint32_t sz = h->SymTab[i].st_size;
|
||||||
AddSymbol(maplib, symname, offs);
|
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 <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "librarian.h"
|
#include "librarian.h"
|
||||||
#include "librarian_private.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),
|
int argc, char * * ubp_av, void (*init) (void), void (*fini) (void),
|
||||||
void (*rtld_fini) (void), void (* stack_end)); // implemented in x86run_private.c
|
void (*rtld_fini) (void), void (* stack_end)); // implemented in x86run_private.c
|
||||||
uint32_t LibSyscall(x86emu_t *emu); // implemented in x86syscall.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)
|
uintptr_t CreateSymbol(lib_t *maplib, const char* name)
|
||||||
{
|
{
|
||||||
// look for symbols that can be created
|
// look for symbols that can be created
|
||||||
uintptr_t addr = 0;
|
uintptr_t addr = 0;
|
||||||
|
// libc
|
||||||
if(strcmp(name, "__stack_chk_fail")==0) {
|
if(strcmp(name, "__stack_chk_fail")==0) {
|
||||||
addr = AddBridge(maplib->bridge, vFE, my__stack_chk_fail);
|
addr = AddBridge(maplib->bridge, vFE, my__stack_chk_fail);
|
||||||
} else if(strcmp(name, "__libc_start_main")==0) {
|
} 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);
|
addr = AddBridge(maplib->bridge, iFi, putchar);
|
||||||
} else if(strcmp(name, "strtol")==0) {
|
} else if(strcmp(name, "strtol")==0) {
|
||||||
addr = AddBridge(maplib->bridge, iFppi, strtol);
|
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)
|
if(addr)
|
||||||
AddSymbol(maplib, name, addr);
|
AddSymbol(maplib, name, addr, 12);
|
||||||
return addr;
|
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;
|
int ret;
|
||||||
khint_t k = kh_put(maplib_t, maplib->maplib, name, &ret);
|
khint_t k = kh_put(maplib_t, maplib->maplib, name, &ret);
|
||||||
kh_value(maplib->maplib, k).offs = addr;
|
kh_value(maplib->maplib, k).offs = addr;
|
||||||
|
kh_value(maplib->maplib, k).sz = sz;
|
||||||
}
|
}
|
||||||
uintptr_t FindSymbol(lib_t *maplib, const char* name)
|
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 CreateSymbol(maplib, name);
|
||||||
return kh_val(maplib->maplib, k).offs;
|
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();
|
lib_t *NewLibrarian();
|
||||||
void FreeLibrarian(lib_t **maplib);
|
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);
|
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_
|
#endif //__LIBRARIAN_H_
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uintptr_t offs;
|
uintptr_t offs;
|
||||||
|
uint32_t sz;
|
||||||
// need to track type of symbol?
|
// need to track type of symbol?
|
||||||
// need to track origin?
|
// need to track origin?
|
||||||
} onelib_t;
|
} 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
|
// init random seed
|
||||||
srandom(time(NULL));
|
srandom(time(NULL));
|
||||||
|
|
||||||
// check BOX86_loG debug level
|
// check BOX86_LOG debug level
|
||||||
LoadLogEnv();
|
LoadLogEnv();
|
||||||
|
|
||||||
// Create a new context
|
// Create a new context
|
||||||
@ -153,8 +153,7 @@ int main(int argc, const char **argv, const char **env) {
|
|||||||
|
|
||||||
p = getenv("BOX86_TRACE");
|
p = getenv("BOX86_TRACE");
|
||||||
if(p) {
|
if(p) {
|
||||||
setbuf(stdout, NULL);
|
if (strcmp(p, "0"))
|
||||||
if (strcmp(p, "1")==0)
|
|
||||||
context->x86trace = 1;
|
context->x86trace = 1;
|
||||||
}
|
}
|
||||||
if(context->x86trace) {
|
if(context->x86trace) {
|
||||||
@ -243,9 +242,20 @@ int main(int argc, const char **argv, const char **env) {
|
|||||||
// setup the stack...
|
// setup the stack...
|
||||||
Push(context->emu, (uint32_t)context->argv);
|
Push(context->emu, (uint32_t)context->argv);
|
||||||
Push(context->emu, context->argc);
|
Push(context->emu, context->argc);
|
||||||
SetupX86Emu(context->emu);
|
SetupX86Emu(context->emu, NULL, NULL);
|
||||||
SetEAX(context->emu, context->argc);
|
SetEAX(context->emu, context->argc);
|
||||||
SetEBX(context->emu, (uint32_t)context->argv);
|
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!
|
// emulate!
|
||||||
printf_log(LOG_DEBUG, "Start x86emu on Main\n");
|
printf_log(LOG_DEBUG, "Start x86emu on Main\n");
|
||||||
Run(context->emu);
|
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 (*vFp_t)(void*);
|
||||||
typedef void (*vFE_t)(x86emu_t*);
|
typedef void (*vFE_t)(x86emu_t*);
|
||||||
typedef int32_t (*iFv_t)();
|
typedef int32_t (*iFv_t)();
|
||||||
|
typedef uint32_t (*uFv_t)();
|
||||||
|
typedef void* (*pFv_t)();
|
||||||
typedef uint32_t (*uFE_t)(x86emu_t*);
|
typedef uint32_t (*uFE_t)(x86emu_t*);
|
||||||
typedef void (*vFi_t)(int32_t);
|
typedef void (*vFi_t)(int32_t);
|
||||||
typedef int32_t (*iFi_t)(int32_t);
|
typedef int32_t (*iFi_t)(int32_t);
|
||||||
typedef int32_t (*iFp_t)(void*);
|
typedef int32_t (*iFp_t)(void*);
|
||||||
|
typedef void* (*pFp_t)(void*);
|
||||||
typedef int32_t (*iFpp_t)(void*, 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 int32_t (*iFppi_t)(void*, void*, int32_t);
|
||||||
typedef void* (*pFuu_t)(uint32_t, uint32_t);
|
typedef void* (*pFuu_t)(uint32_t, uint32_t);
|
||||||
typedef int32_t (*iFipp_t)(int, void*, void*);
|
typedef int32_t (*iFipp_t)(int, void*, void*);
|
||||||
typedef int32_t (*iFppp_t)(void*, 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*);
|
typedef int32_t (*iFEpippppp_t)(x86emu_t*, void*, int32_t, void*, void*, void*, void*, void*);
|
||||||
|
|
||||||
#define DEF(A) A f = (A)fnc
|
#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)
|
void iFv(x86emu_t *emu, uintptr_t fnc)
|
||||||
{
|
{
|
||||||
DEF(iFv_t);
|
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)
|
void uFE(x86emu_t *emu, uintptr_t fnc)
|
||||||
{
|
{
|
||||||
@ -66,6 +79,11 @@ void vFi(x86emu_t *emu, uintptr_t fnc)
|
|||||||
DEF(vFi_t);
|
DEF(vFi_t);
|
||||||
f(i32(0));
|
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)
|
void iFi(x86emu_t *emu, uintptr_t fnc)
|
||||||
{
|
{
|
||||||
DEF(iFi_t);
|
DEF(iFi_t);
|
||||||
@ -76,6 +94,11 @@ void iFp(x86emu_t *emu, uintptr_t fnc)
|
|||||||
DEF(iFp_t);
|
DEF(iFp_t);
|
||||||
R_EAX = (uint32_t)f(p(0));
|
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)
|
void iFpp(x86emu_t *emu, uintptr_t fnc)
|
||||||
{
|
{
|
||||||
DEF(iFpp_t);
|
DEF(iFpp_t);
|
||||||
@ -91,6 +114,26 @@ void pFuu(x86emu_t *emu, uintptr_t fnc)
|
|||||||
DEF(pFuu_t);
|
DEF(pFuu_t);
|
||||||
R_EAX = (uintptr_t)f(u32(0), u32(4));
|
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)
|
void iFpV(x86emu_t *emu, uintptr_t fnc)
|
||||||
{
|
{
|
||||||
DEF(iFpp_t);
|
DEF(iFpp_t);
|
||||||
@ -111,6 +154,11 @@ void iFvopV(x86emu_t *emu, uintptr_t fnc)
|
|||||||
DEF(iFppp_t);
|
DEF(iFppp_t);
|
||||||
R_EAX = (uint32_t)f((void*)stdout, p(4), (void*)stack(8));
|
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)
|
void iFEpippppp(x86emu_t *emu, uintptr_t fnc)
|
||||||
{
|
{
|
||||||
DEF(iFEpippppp_t);
|
DEF(iFEpippppp_t);
|
||||||
|
@ -20,16 +20,24 @@ void vFp(x86emu_t *emu, uintptr_t fnc);
|
|||||||
void vFE(x86emu_t *emu, uintptr_t fnc);
|
void vFE(x86emu_t *emu, uintptr_t fnc);
|
||||||
void uFE(x86emu_t *emu, uintptr_t fnc);
|
void uFE(x86emu_t *emu, uintptr_t fnc);
|
||||||
void iFv(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 vFi(x86emu_t *emu, uintptr_t fnc);
|
||||||
void iFi(x86emu_t *emu, uintptr_t fnc);
|
void iFi(x86emu_t *emu, uintptr_t fnc);
|
||||||
void iFp(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 iFpp(x86emu_t *emu, uintptr_t fnc);
|
||||||
void iFppi(x86emu_t *emu, uintptr_t fnc);
|
void iFppi(x86emu_t *emu, uintptr_t fnc);
|
||||||
void pFuu(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 iFpv(x86emu_t *emu, uintptr_t fnc);
|
||||||
void iF1pV(x86emu_t *emu, uintptr_t fnc);
|
void iF1pV(x86emu_t *emu, uintptr_t fnc);
|
||||||
void iFopV(x86emu_t *emu, uintptr_t fnc);
|
void iFopV(x86emu_t *emu, uintptr_t fnc);
|
||||||
void iFvopV(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
|
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;
|
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");
|
printf_log(LOG_DEBUG, "Setup X86 Emu\n");
|
||||||
|
|
||||||
// push "end emu" marker address
|
// push "end emu" marker address
|
||||||
PushExit(emu);
|
PushExit(emu);
|
||||||
// Setup the GS segment:
|
// Setup the GS segment:
|
||||||
emu->globals = calloc(1, 256); // arbitrary 256 byte size?
|
if(shared_global) {
|
||||||
// calc canary...
|
emu->globals = globals;
|
||||||
uint8_t canary[4];
|
emu->shared_global = shared_global;
|
||||||
for (int i=0; i<4; ++i) canary[i] = 1 + getrand(255);
|
} else {
|
||||||
canary[getrand(4)] = 0;
|
emu->globals = calloc(1, 256); // arbitrary 256 byte size?
|
||||||
memcpy(emu->globals+0x14, canary, sizeof(canary)); // put canary in place
|
// calc canary...
|
||||||
printf_log(LOG_DEBUG, "Setting up canary (for Stack protector) at GS:0x14, value:%08X\n", *(uint32_t*)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)
|
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);
|
printf_log(LOG_DEBUG, "Free a X86 Emu (%p)\n", *x86emu);
|
||||||
if((*x86emu)->dec)
|
if((*x86emu)->dec)
|
||||||
DeleteX86TraceDecoder(&(*x86emu)->dec);
|
DeleteX86TraceDecoder(&(*x86emu)->dec);
|
||||||
if((*x86emu)->globals)
|
if((*x86emu)->shared_global && !(*(*x86emu)->shared_global)--) {
|
||||||
free((*x86emu)->globals);
|
if((*x86emu)->globals)
|
||||||
|
free((*x86emu)->globals);
|
||||||
|
free((*x86emu)->shared_global);
|
||||||
|
}
|
||||||
free(*x86emu);
|
free(*x86emu);
|
||||||
*x86emu = NULL;
|
*x86emu = NULL;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,8 @@ typedef struct x86emu_s x86emu_t;
|
|||||||
typedef struct box86context_s box86context_t;
|
typedef struct box86context_s box86context_t;
|
||||||
|
|
||||||
x86emu_t *NewX86Emu(box86context_t *context, uintptr_t start, uintptr_t stack, int stacksize);
|
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);
|
void FreeX86Emu(x86emu_t **x86emu);
|
||||||
|
|
||||||
uint32_t GetEAX(x86emu_t *emu);
|
uint32_t GetEAX(x86emu_t *emu);
|
||||||
|
@ -34,8 +34,10 @@ typedef struct x86emu_s {
|
|||||||
int error;
|
int error;
|
||||||
// trace
|
// trace
|
||||||
zydis_dec_t *dec;
|
zydis_dec_t *dec;
|
||||||
|
uintptr_t trace_start, trace_end;
|
||||||
// global stuffs, pointed with GS: segment
|
// global stuffs, pointed with GS: segment
|
||||||
void *globals;
|
void *globals;
|
||||||
|
int *shared_global;
|
||||||
// parent context
|
// parent context
|
||||||
box86context_t *context;
|
box86context_t *context;
|
||||||
} x86emu_t;
|
} x86emu_t;
|
||||||
|
20
src/x86run.c
20
src/x86run.c
@ -13,10 +13,13 @@
|
|||||||
|
|
||||||
int Run(x86emu_t *emu)
|
int Run(x86emu_t *emu)
|
||||||
{
|
{
|
||||||
|
printf_log(LOG_DEBUG, "Run X86, EIP=%p\n", emu, R_EIP);
|
||||||
emu->quit = 0;
|
emu->quit = 0;
|
||||||
while (!emu->quit)
|
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));
|
printf_log(LOG_NONE, "%s", DumpCPURegs(emu));
|
||||||
if(Peek(emu, 0)==0xcc && Peek(emu, 1)=='S' && Peek(emu, 2)=='C') {
|
if(Peek(emu, 0)==0xcc && Peek(emu, 1)=='S' && Peek(emu, 2)=='C') {
|
||||||
uint32_t a = *(uint32_t*)(R_EIP+3);
|
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);
|
printf_log(LOG_NONE, "%08p: Native call to %p\n", R_EIP, a);
|
||||||
}
|
}
|
||||||
} else {
|
} 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);
|
uint8_t opcode = Fetch8(emu);
|
||||||
@ -242,6 +245,16 @@ int Run(x86emu_t *emu)
|
|||||||
if(!ACCESS_FLAG(F_ZF))
|
if(!ACCESS_FLAG(F_ZF))
|
||||||
R_EIP += tmp8s;
|
R_EIP += tmp8s;
|
||||||
break;
|
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 */
|
case 0x7C: /* JL Ib */
|
||||||
tmp8s = Fetch8s(emu);
|
tmp8s = Fetch8s(emu);
|
||||||
if(ACCESS_FLAG(F_SF) != ACCESS_FLAG(F_OF))
|
if(ACCESS_FLAG(F_SF) != ACCESS_FLAG(F_OF))
|
||||||
@ -326,6 +339,9 @@ int Run(x86emu_t *emu)
|
|||||||
GetG(emu, &op2, nextop);
|
GetG(emu, &op2, nextop);
|
||||||
op2->dword[0] = (uint32_t)&op1->dword[0];
|
op2->dword[0] = (uint32_t)&op1->dword[0];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x90: /* NOP */
|
||||||
|
break;
|
||||||
|
|
||||||
case 0xA1: /* MOV EAX, Od */
|
case 0xA1: /* MOV EAX, Od */
|
||||||
R_EAX = *(uint32_t*)Fetch32(emu);
|
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…
x
Reference in New Issue
Block a user