forked from tpltnt/libemu
-
Notifications
You must be signed in to change notification settings - Fork 0
/
libemu.3
213 lines (209 loc) · 6.3 KB
/
libemu.3
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
.TH EMU 3 "04 September 2007"
.SH NAME
libemu - emulate x86 shellcodes
.SH SYNOPSIS
.nf
.ft B
#include <emu/emu.h>
#include <emu/emu_memory.h>
#include <emu/emu_cpu.h>
.ft
.LP
.nf
.LP
.ft B
struct emu * emu_new ()
void emu_free (struct emu *e)
struct emu_memory * emu_memory_get (struct emu *e)
struct emu_logging * emu_logging_get (struct emu *e)
struct emu_cpu * emu_cpu_get (struct emu *e)
void emu_errno_set (struct emu *e, int err)
int emu_errno (struct emu *c)
void emu_strerror_set (struct emu *e,
.ti +8
const char *format,...)
const char * emu_strerror (struct emu *e)
.ft
.LP
.ft B
void emu_memory_clear (struct emu_memory *em)
int32_t emu_memory_read_byte (struct emu_memory *m,
.ti +8
uint32_t addr, uint8_t *byte)
int32_t emu_memory_read_word (struct emu_memory *m,
.ti +8
uint32_t addr, uint16_t *word)
int32_t emu_memory_read_dword (struct emu_memory *m,
.ti +8
uint32_t addr, uint32_t *dword)
int32_t emu_memory_read_block (struct emu_memory *m,
.ti +8
uint32_t addr, void *dest, size_t len)
int32_t emu_memory_read_string (struct emu_memory *m,
.ti +8
uint32_t addr, struct emu_string *s, uint32_t maxsize)
int32_t emu_memory_write_byte (struct emu_memory *m,
.ti +8
uint32_t addr, uint8_t byte)
int32_t emu_memory_write_word (struct emu_memory *m,
.ti +8
uint32_t addr, uint16_t word)
int32_t emu_memory_write_dword (struct emu_memory *m,
.ti +8
uint32_t addr, uint32_t dword)
int32_t emu_memory_write_block (struct emu_memory *m,
.ti +8
uint32_t addr, void *src, size_t len)
void emu_memory_segment_select (struct emu_memory *m,
.ti +8
enum emu_segment s)
enum emu_segment emu_memory_segment_get (struct emu_memory *m)
int32_t emu_memory_alloc (struct emu_memory *m,
.ti +8
uint32_t *addr, size_t len)
uint32_t emu_memory_get_usage (struct emu_memory *m)
void emu_memory_mode_ro (struct emu_memory *m)
void emu_memory_mode_rw (struct emu_memory *m)
.ft
.LP
.ft B
uint32_t emu_cpu_reg32_get (struct emu_cpu *cpu_p, enum emu_reg32 reg)
uint16_t emu_cpu_reg16_get (struct emu_cpu *cpu_p, enum emu_reg16 reg)
uint8_t emu_cpu_reg8_get (struct emu_cpu *cpu_p, enum emu_reg8 reg)
void emu_cpu_reg16_set (struct emu_cpu *cpu_p, enum emu_reg16 reg, uint16_t val)
void emu_cpu_reg32_set (struct emu_cpu *cpu_p, enum emu_reg32 reg, uint32_t val)
void emu_cpu_reg8_set (struct emu_cpu *cpu_p, enum emu_reg8 reg, uint8_t val)
uint32_t emu_cpu_eflags_get (struct emu_cpu *c)
void emu_cpu_eflags_set (struct emu_cpu *c, uint32_t val)
void emu_cpu_eip_set (struct emu_cpu *c, uint32_t eip)
uint32_t emu_cpu_eip_get (struct emu_cpu *c)
int32_t emu_cpu_parse (struct emu_cpu *c)
int32_t emu_cpu_step (struct emu_cpu *c)
int32_t emu_cpu_run (struct emu_cpu *c)
void emu_cpu_debug_print (struct emu_cpu *c)
.ft
.LP
.ft B
int32_t emu_shellcode_test(struct emu *e, uint8_t *data, uint16_t size)
.ft
.LP
.ft B
struct emu_env_w32 *emu_env_w32_new(struct emu *e)
void emu_env_w32_free(struct emu_env_w32 *env)
struct emu_env_w32_dll_export *emu_env_w32_eip_check(struct emu_env_w32 *env)
int32_t emu_env_w32_export_hook(struct emu_env_w32 *env,
.ti +8
const char *dllname,
.ti +8
const char *exportname,
.ti +8
int32_t (*fnhook) (struct emu_env_w32 *env, struct emu_env_w32_dll_export *ex)
.ti +8
);
.ft
.fi
.SH DESCRIPTION
libemu provides basic x86 emulation including memory access and registers.
.PP
.SH ROUTINES
.B emu_new()
is used to create a new emulation entity, use
.B emu_free()
to free all associated memory.
.B emu_memory_get()
,
.B emu_logging_get()
and
.B emu_cpu_get()
can be used to obtain pointers to different parts of the emulation.
For errorhandling, use
.B emu_errno()
or
.B emu_strerror()
returning either a POSIX errno or a string describing the error.
When writing extensions
.B emu_errno_set()
and
.B emu_strerror_set()
will come handy too.
.PP
The
.B emu_memory
is split up in pages, therefore there are functions to access the memory without taking care of page borders.
.B emu_memory_read_byte()
,
.B emu_memory_read_word()
,
.B emu_memory_read_dword()
,
.B emu_memory_read_string()
and
.B emu_memory_read_block()
can be used to read values from the emu memory.
.B emu_memory_read_string()
will allocate the required memory for the string within the
.B emu_string
provided by itself, as you won't be able to know the strings length,
in all other cases, the pointer to the location has to provide enough space
to write the data.
.PP
Once the emulation is created, code is written to the memory,
we need to set the registers to the initial values, the cpuflags to the start values
and EIP to the point where to start code execution.
.B emu_cpu
provides functions to access all registers, the flags and EIP for read and write.
To access the 32bit registers use
.B emu_cpu_reg32_get()
and
.B emu_cpu_reg32_set()
where
.I reg
is one of eax, ecx, edx, ebx, esp, ebp, esi, edi.
To access the 16bit registers use
.B emu_cpu_reg16_get()
and
.B emu_cpu_reg16_set()
with ax, cx, dx, bx, sp, bp, si, di as valid values for
.IR reg.
In case of 8bit register access use
.B emu_cpu_reg8_get()
and
.B emu_cpu_reg8_set()
with al, cl, dl, bl, ah, ch, dh, bh as values for
.IR reg .
Accessing the cpu's flags is possible using
.B emu_cpu_eflags_get()
and
.BR emu_cpu_eflags_set() .
Accessing EIP can be done using
.B emu_cpu_eip_set()
and
.BR emu_cpu_eip_get() .
Once everything is setup, parse the first instruction using
.B emu_cpu_parse()
, on success it will return 0, on failure use
.B emu_strerror()
to get a description of the error.
If parsing was successfull, step the first instruction using
.BR emu_cpu_step() .
.PP
If you want to detect shellcodes in buffers, use
.B emu_shellcode_test()
, the emu will copy the buffer to it's pages and try to detect a shellcode.
If a possible shellcode gets detected, the guessed starting offset is returned, else -1.
.PP
To be able to run shellcodes using windows api, one has to provide parts of the
windows process environment to the emulation, as well as some kind of emulation for the used api calls.
.B emu_env_w32_new()
will created a minimalistic process environment in
.I e
and using
.B emu_env_w32_eip_check()
after step allows you intercepting calls to exported api.
If the return value of
.B emu_env_w32_eip_check()
is not NULL, the dll exports information is returned, including the calls name and hook.
If you want to hook calls to api exports, use
.BR emu_env_w32_export_hook() .
.SH AUTHOR
Markus Koetter <[email protected]>