-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathx86-32_engine.c
116 lines (102 loc) · 3.21 KB
/
x86-32_engine.c
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
#include "mcp_forth.h"
#define MAX_CALLBACKS 8
typedef int (*callback_target_t)();
typedef struct {
m4_stack_t stack;
uint8_t * memory;
const uint8_t * data;
uint8_t * callback_info;
const uint8_t ** callback_word_locations;
int * stack_base;
void * edi_table;
void (*call_runtime_word)(void);
const callback_target_t * callback_targets;
void * (*memset)(void *, int, size_t);
void * (*memmove)(void *, const void *, size_t);
int (*compare)(void * a1, unsigned u1, void * a2, unsigned u2);
} ctx_t;
void m4_x86_32_engine_run_asm(ctx_t * asm_struct, const uint8_t * program_start);
void m4_x86_32_engine_call_runtime_word(void);
int m4_x86_32_engine_callback_target_0();
int m4_x86_32_engine_callback_target_1();
int m4_x86_32_engine_callback_target_2();
int m4_x86_32_engine_callback_target_3();
int m4_x86_32_engine_callback_target_4();
int m4_x86_32_engine_callback_target_5();
int m4_x86_32_engine_callback_target_6();
int m4_x86_32_engine_callback_target_7();
#ifdef M4_NO_TLS
static ctx_t * g_ctx;
#else
static __thread ctx_t * g_ctx;
#endif
static const callback_target_t callback_targets[MAX_CALLBACKS] = {
m4_x86_32_engine_callback_target_0,
m4_x86_32_engine_callback_target_1,
m4_x86_32_engine_callback_target_2,
m4_x86_32_engine_callback_target_3,
m4_x86_32_engine_callback_target_4,
m4_x86_32_engine_callback_target_5,
m4_x86_32_engine_callback_target_6,
m4_x86_32_engine_callback_target_7,
};
static int compare(void * a1, unsigned u1, void * a2, unsigned u2)
{
int result = memcmp(a1, a2, u1 < u2 ? u1 : u2);
if(result == 0) {
return u1 < u2 ? -1 : u1 > u2 ? 1 : 0;
}
return result < 0 ? -1 : 1;
}
int m4_x86_32_engine_run(
const uint8_t * bin,
int bin_len,
uint8_t * memory_start,
int memory_len,
const m4_runtime_cb_array_t ** cb_arrays,
const char ** missing_runtime_word_dst
) {
uint8_t * memory_p = m4_align(memory_start);
ctx_t * c = (ctx_t *) memory_p;
memory_p += sizeof(ctx_t);
if(m4_bytes_remaining(memory_start, memory_p, memory_len) < 0) return M4_OUT_OF_MEMORY_ERROR;
g_ctx = c;
c->stack.data = (int *) memory_p;
c->stack_base = (int *) memory_p;
memory_p += 100 * 4;
if(m4_bytes_remaining(memory_start, memory_p, memory_len) < 0) return M4_OUT_OF_MEMORY_ERROR;
c->stack.max = 100;
c->stack.len = 0;
int ** variables;
const m4_runtime_cb_pair_t ** runtime_cbs;
const uint8_t * program_start;
int res = m4_unpack_binary_header(
bin,
bin_len,
memory_p,
m4_bytes_remaining(memory_start, memory_p, memory_len),
cb_arrays,
missing_runtime_word_dst,
MAX_CALLBACKS,
&variables,
&runtime_cbs,
&c->data,
&c->callback_info,
&c->callback_word_locations,
&program_start,
&c->memory
);
if(res) return res;
c->edi_table = runtime_cbs - 1;
c->call_runtime_word = m4_x86_32_engine_call_runtime_word;
c->callback_targets = callback_targets;
c->memset = memset;
c->memmove = memmove;
c->compare = compare;
m4_x86_32_engine_run_asm(c, program_start);
return 0;
}
ctx_t * m4_x86_32_engine_get_ctx(void)
{
return g_ctx;
}