diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-02 14:49:36 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-02 14:49:36 +0100 |
| commit | 1b9d1dc6093028ceb0f2eeeccf9cfbc5610fcf30 (patch) | |
| tree | a63aca8dd2f11ea86ef7dfe066c3942e8b5e2dfe /src/emu/x64trace.c | |
| parent | a6143f33ce443c16a773816c2255936a39aee129 (diff) | |
| download | box64-1b9d1dc6093028ceb0f2eeeccf9cfbc5610fcf30.tar.gz box64-1b9d1dc6093028ceb0f2eeeccf9cfbc5610fcf30.zip | |
Added Zydis lib support for Trace enabled build
Diffstat (limited to 'src/emu/x64trace.c')
| -rwxr-xr-x | src/emu/x64trace.c | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/src/emu/x64trace.c b/src/emu/x64trace.c new file mode 100755 index 00000000..b2f52179 --- /dev/null +++ b/src/emu/x64trace.c @@ -0,0 +1,111 @@ +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <dlfcn.h> + +#include "debug.h" +#include "x64trace.h" +#include "box64context.h" +#include "x86zydis.h" +#include "x64emu_private.h" + +typedef ZyanStatus (*PFNZydisDecoderInit)(ZydisDecoder* decoder, ZydisMachineMode machine_mode, + ZydisAddressWidth address_width); + +typedef ZyanStatus (*PFNZydisFormatterInit)(ZydisFormatter* formatter, ZydisFormatterStyle style); + +typedef ZyanStatus (*PFNZydisDecoderDecodeBuffer)(const ZydisDecoder* decoder, + const void* buffer, ZyanUSize length, ZydisDecodedInstruction* instruction); + +typedef ZyanStatus (*PFNZydisFormatterFormatInstruction)(const ZydisFormatter* formatter, + const ZydisDecodedInstruction* instruction, char* buffer, ZyanUSize length, + ZyanU64 runtime_address); + +typedef struct zydis_s { + void* lib; + PFNZydisDecoderInit ZydisDecoderInit; + PFNZydisFormatterInit ZydisFormatterInit; + PFNZydisDecoderDecodeBuffer ZydisDecoderDecodeBuffer; + PFNZydisFormatterFormatInstruction ZydisFormatterFormatInstruction; +} zydis_t; + +typedef struct zydis_dec_s { + ZydisDecoder decoder; + ZydisFormatter formatter; + ZydisDecodedInstruction instruction; + PFNZydisDecoderDecodeBuffer ZydisDecoderDecodeBuffer; + PFNZydisFormatterFormatInstruction ZydisFormatterFormatInstruction; +} zydis_dec_t; + +int InitX64Trace(box64context_t *context) +{ + if(context->zydis) + return 0; + context->zydis = (zydis_t*)calloc(1, sizeof(zydis_t)); + if(!context->zydis) + return 1; + context->zydis->lib = dlopen("libZydis.so", RTLD_LAZY); + if(!context->zydis->lib) { + printf_log(LOG_INFO, "Failed to open libZydis: %s\n", dlerror()); + return 1; + } + #define GO(f) context->zydis->f = (PFN##f)dlsym(context->zydis->lib, #f);\ + if(!context->zydis->f) {printf_log(LOG_INFO, "Fail to load Zydis function %s\n", #f); dlclose(context->zydis->lib); context->zydis->lib=NULL; return 1;} + + GO(ZydisDecoderInit); + GO(ZydisFormatterInit); + GO(ZydisDecoderDecodeBuffer); + GO(ZydisFormatterFormatInstruction); + #undef GO + + context->dec = InitX64TraceDecoder(context); + + return 0; +} + +void DeleteX64Trace(box64context_t *context) +{ + if(!context->zydis) + return; + if(context->zydis->lib) + dlclose(context->zydis->lib); + free(context->zydis); + context->zydis = NULL; +} + +zydis_dec_t* InitX64TraceDecoder(box64context_t *context) +{ + if(!context->zydis) + return NULL; + zydis_dec_t *dec = (zydis_dec_t*)calloc(1, sizeof(zydis_dec_t)); + dec->ZydisDecoderDecodeBuffer = context->zydis->ZydisDecoderDecodeBuffer; + dec->ZydisFormatterFormatInstruction = context->zydis->ZydisFormatterFormatInstruction; + context->zydis->ZydisDecoderInit(&dec->decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64); + context->zydis->ZydisFormatterInit(&dec->formatter, ZYDIS_FORMATTER_STYLE_INTEL); + + return dec; +} +void DeleteX64TraceDecoder(zydis_dec_t **dec) +{ + free(*dec); + *dec = NULL; +} + +const char* DecodeX64Trace(zydis_dec_t *dec, uintptr_t p) +{ + static char buff[256]; + if(ZYAN_SUCCESS(dec->ZydisDecoderDecodeBuffer(&dec->decoder, (char*)p, 15, + &dec->instruction))) { + char tmp[255]; + buff[0]='\0'; + for (int i=0; i<dec->instruction.length; ++i) { + sprintf(tmp, "%02X ", *((unsigned char*)p+i)); + strcat(buff, tmp); + } + dec->ZydisFormatterFormatInstruction(&dec->formatter, &dec->instruction, tmp, sizeof(tmp),p); + strcat(buff, tmp); + } else { + sprintf(buff, "Decoder failed @%p", (void*)p); + } + return buff; +} |