1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
#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[512];
if(ZYAN_SUCCESS(dec->ZydisDecoderDecodeBuffer(&dec->decoder, (char*)p, 15,
&dec->instruction))) {
char tmp[511];
buff[0]='\0';
for (int i=0; i<dec->instruction.length; ++i) {
sprintf(tmp, "%02X ", *((unsigned char*)p+i));
strcat(buff, tmp);
}
#if 0
const /*ZydisFormatterToken*/void* token;
dec->ZydisFormatterTokenizeInstruction(&dec->formatter, &dec->instruction, tmp, sizeof(tmp), p, &token);
dec->PrintTokenizedInstruction(token);
#else
dec->ZydisFormatterFormatInstruction(&dec->formatter, &dec->instruction, tmp, sizeof(tmp),p);
#endif
strcat(buff, tmp);
} else {
sprintf(buff, "Decoder failed @%p", (void*)p);
}
return buff;
}
|