duran 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
- data/README.rdoc +11 -0
- data/Rakefile +29 -0
- data/VERSION +1 -0
- data/client_src/dr_include/dr_api.h +102 -0
- data/client_src/dr_include/dr_app.h +92 -0
- data/client_src/dr_include/dr_config.h +650 -0
- data/client_src/dr_include/dr_defines.h +391 -0
- data/client_src/dr_include/dr_events.h +1057 -0
- data/client_src/dr_include/dr_ir_instr.h +1214 -0
- data/client_src/dr_include/dr_ir_instrlist.h +149 -0
- data/client_src/dr_include/dr_ir_macros.h +2426 -0
- data/client_src/dr_include/dr_ir_opcodes.h +768 -0
- data/client_src/dr_include/dr_ir_opnd.h +1170 -0
- data/client_src/dr_include/dr_ir_utils.h +708 -0
- data/client_src/dr_include/dr_proc.h +327 -0
- data/client_src/dr_include/dr_tools.h +1304 -0
- data/client_src/duran.c +57 -0
- data/client_src/extconf.rb +28 -0
- data/lib/duran.rb +18 -0
- data/lib/duran/app.rb +8 -0
- data/lib/duran/defines.rb +39 -0
- data/lib/duran/events.rb +156 -0
- data/lib/duran/ir_opcodes.rb +616 -0
- data/lib/duran/ir_opnd.rb +329 -0
- data/lib/duran/ir_utils.rb +133 -0
- data/lib/duran/proc.rb +49 -0
- data/lib/duran/structs.rb +20 -0
- data/lib/duran/structs/exception.rb +23 -0
- data/lib/duran/structs/fault_fragment_info.rb +34 -0
- data/lib/duran/structs/instruction.rb +15 -0
- data/lib/duran/structs/machine_context.rb +80 -0
- data/lib/duran/structs/memory_info.rb +12 -0
- data/lib/duran/structs/module_data.rb +61 -0
- data/lib/duran/structs/module_names.rb +24 -0
- data/lib/duran/structs/operand.rb +15 -0
- data/lib/duran/structs/restore_state_info.rb +30 -0
- data/lib/duran/structs/signal_info.rb +41 -0
- data/lib/duran/structs/tracedump.rb +50 -0
- data/lib/duran/tools.rb +214 -0
- metadata +104 -0
@@ -0,0 +1,1214 @@
|
|
1
|
+
/* **********************************************************
|
2
|
+
* Copyright (c) 2002-2009 VMware, Inc. All rights reserved.
|
3
|
+
* **********************************************************/
|
4
|
+
|
5
|
+
/*
|
6
|
+
* Redistribution and use in source and binary forms, with or without
|
7
|
+
* modification, are permitted provided that the following conditions are met:
|
8
|
+
*
|
9
|
+
* * Redistributions of source code must retain the above copyright notice,
|
10
|
+
* this list of conditions and the following disclaimer.
|
11
|
+
*
|
12
|
+
* * Redistributions in binary form must reproduce the above copyright notice,
|
13
|
+
* this list of conditions and the following disclaimer in the documentation
|
14
|
+
* and/or other materials provided with the distribution.
|
15
|
+
*
|
16
|
+
* * Neither the name of VMware, Inc. nor the names of its contributors may be
|
17
|
+
* used to endorse or promote products derived from this software without
|
18
|
+
* specific prior written permission.
|
19
|
+
*
|
20
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
21
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
22
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
23
|
+
* ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE
|
24
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
25
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
26
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
27
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
28
|
+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
29
|
+
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
30
|
+
* DAMAGE.
|
31
|
+
*/
|
32
|
+
|
33
|
+
#ifndef _DR_IR_INSTR_H_
|
34
|
+
#define _DR_IR_INSTR_H_ 1
|
35
|
+
|
36
|
+
/****************************************************************************
|
37
|
+
* INSTR ROUTINES
|
38
|
+
*/
|
39
|
+
/**
|
40
|
+
* @file dr_ir_instr.h
|
41
|
+
* @brief Functions to create and manipulate instructions.
|
42
|
+
*/
|
43
|
+
|
44
|
+
|
45
|
+
|
46
|
+
/**
|
47
|
+
* Returns an initialized instr_t allocated on the thread-local heap.
|
48
|
+
* Sets the x86/x64 mode of the returned instr_t to the mode of dcontext.
|
49
|
+
*/
|
50
|
+
instr_t*
|
51
|
+
instr_create(void *drcontext);
|
52
|
+
|
53
|
+
/** Initializes \p instr.
|
54
|
+
* Sets the x86/x64 mode of \p instr to the mode of dcontext.
|
55
|
+
*/
|
56
|
+
void
|
57
|
+
instr_init(void *drcontext, instr_t *instr);
|
58
|
+
|
59
|
+
/**
|
60
|
+
* Deallocates all memory that was allocated by \p instr. This
|
61
|
+
* includes raw bytes allocated by instr_allocate_raw_bits() and
|
62
|
+
* operands allocated by instr_set_num_opnds(). Does not deallocate
|
63
|
+
* the storage for \p instr itself.
|
64
|
+
*/
|
65
|
+
void
|
66
|
+
instr_free(void *drcontext, instr_t *instr);
|
67
|
+
|
68
|
+
/**
|
69
|
+
* Performs both instr_free() and instr_init().
|
70
|
+
* \p instr must have been initialized.
|
71
|
+
*/
|
72
|
+
void
|
73
|
+
instr_reset(void *drcontext, instr_t *instr);
|
74
|
+
|
75
|
+
/**
|
76
|
+
* Frees all dynamically allocated storage that was allocated by \p instr,
|
77
|
+
* except for allocated bits.
|
78
|
+
* Also zeroes out \p instr's fields, except for raw bit fields,
|
79
|
+
* whether \p instr is instr_ok_to_mangle(), and the x86 mode of \p instr.
|
80
|
+
* \p instr must have been initialized.
|
81
|
+
*/
|
82
|
+
void
|
83
|
+
instr_reuse(void *drcontext, instr_t *instr);
|
84
|
+
|
85
|
+
/**
|
86
|
+
* Performs instr_free() and then deallocates the thread-local heap
|
87
|
+
* storage for \p instr.
|
88
|
+
*/
|
89
|
+
void
|
90
|
+
instr_destroy(void *drcontext, instr_t *instr);
|
91
|
+
|
92
|
+
/**
|
93
|
+
* Returns the next instr_t in the instrlist_t that contains \p instr.
|
94
|
+
* \note The next pointer for an instr_t is inside the instr_t data
|
95
|
+
* structure itself, making it impossible to have on instr_t in
|
96
|
+
* two different InstrLists (but removing the need for an extra data
|
97
|
+
* structure for each element of the instrlist_t).
|
98
|
+
*/
|
99
|
+
instr_t*
|
100
|
+
instr_get_next(instr_t *instr);
|
101
|
+
|
102
|
+
/** Returns the previous instr_t in the instrlist_t that contains \p instr. */
|
103
|
+
instr_t*
|
104
|
+
instr_get_prev(instr_t *instr);
|
105
|
+
|
106
|
+
/** Sets the next field of \p instr to point to \p next. */
|
107
|
+
void
|
108
|
+
instr_set_next(instr_t *instr, instr_t *next);
|
109
|
+
|
110
|
+
/** Sets the prev field of \p instr to point to \p prev. */
|
111
|
+
void
|
112
|
+
instr_set_prev(instr_t *instr, instr_t *prev);
|
113
|
+
|
114
|
+
/**
|
115
|
+
* Gets the value of the user-controlled note field in \p instr.
|
116
|
+
* \note Important: is also used when emitting for targets that are other
|
117
|
+
* instructions, so make sure to clear or set appropriately the note field
|
118
|
+
* prior to emitting.
|
119
|
+
*/
|
120
|
+
void *
|
121
|
+
instr_get_note(instr_t *instr);
|
122
|
+
|
123
|
+
/** Sets the user-controlled note field in \p instr to \p value. */
|
124
|
+
void
|
125
|
+
instr_set_note(instr_t *instr, void *value);
|
126
|
+
|
127
|
+
/** Return the taken target pc of the (direct branch) instruction. */
|
128
|
+
app_pc
|
129
|
+
instr_get_branch_target_pc(instr_t *cti_instr);
|
130
|
+
|
131
|
+
/** Set the taken target pc of the (direct branch) instruction. */
|
132
|
+
void
|
133
|
+
instr_set_branch_target_pc(instr_t *cti_instr, app_pc pc);
|
134
|
+
|
135
|
+
/**
|
136
|
+
* Returns true iff \p instr is a conditional branch, unconditional branch,
|
137
|
+
* or indirect branch with a program address target (NOT an instr_t address target)
|
138
|
+
* and \p instr is ok to mangle.
|
139
|
+
*/
|
140
|
+
bool
|
141
|
+
instr_is_exit_cti(instr_t *instr);
|
142
|
+
|
143
|
+
/** Return true iff \p instr's opcode is OP_int, OP_into, or OP_int3. */
|
144
|
+
bool
|
145
|
+
instr_is_interrupt(instr_t *instr);
|
146
|
+
|
147
|
+
/**
|
148
|
+
* Return true iff \p instr is not a meta-instruction
|
149
|
+
* (see instr_set_ok_to_mangle() for more information).
|
150
|
+
*/
|
151
|
+
bool
|
152
|
+
instr_ok_to_mangle(instr_t *instr);
|
153
|
+
|
154
|
+
/**
|
155
|
+
* Sets \p instr to "ok to mangle" if \p val is true and "not ok to
|
156
|
+
* mangle" if \p val is false. An instruction that is "not ok to
|
157
|
+
* mangle" is treated by DR as a "meta-instruction", distinct from
|
158
|
+
* normal application instructions, and is not mangled in any way.
|
159
|
+
* This is necessary to have DR not create an exit stub for a direct
|
160
|
+
* jump. All non-meta instructions that are added to basic blocks or
|
161
|
+
* traces should have their translation fields set (via
|
162
|
+
* #instr_set_translation(), or the convenience routine
|
163
|
+
* #instr_set_meta_no_translation()) when recreating state at a fault;
|
164
|
+
* meta instructions should not fault and are not considered
|
165
|
+
* application instructions but rather added instrumentation code (see
|
166
|
+
* #dr_register_bb_event() for further information on recreating).
|
167
|
+
*
|
168
|
+
* \note For meta-instructions that can fault but only when accessing
|
169
|
+
* client memory and that never access application memory, the
|
170
|
+
* "meta-instruction that can fault" property can be set via
|
171
|
+
* #instr_set_meta_may_fault to avoid incurring the cost of added
|
172
|
+
* sandboxing checks that look for changes to application code.
|
173
|
+
*/
|
174
|
+
void
|
175
|
+
instr_set_ok_to_mangle(instr_t *instr, bool val);
|
176
|
+
|
177
|
+
/**
|
178
|
+
* A convenience routine that calls both
|
179
|
+
* #instr_set_ok_to_mangle (instr, false) and
|
180
|
+
* #instr_set_translation (instr, NULL).
|
181
|
+
*/
|
182
|
+
void
|
183
|
+
instr_set_meta_no_translation(instr_t *instr);
|
184
|
+
|
185
|
+
/** Return true iff \p instr is to be emitted into the cache. */
|
186
|
+
bool
|
187
|
+
instr_ok_to_emit(instr_t *instr);
|
188
|
+
|
189
|
+
/**
|
190
|
+
* Set \p instr to "ok to emit" if \p val is true and "not ok to emit"
|
191
|
+
* if \p val is false. An instruction that should not be emitted is
|
192
|
+
* treated normally by DR for purposes of exits but is not placed into
|
193
|
+
* the cache. It is used for final jumps that are to be elided.
|
194
|
+
*/
|
195
|
+
void
|
196
|
+
instr_set_ok_to_emit(instr_t *instr, bool val);
|
197
|
+
|
198
|
+
/**
|
199
|
+
* Returns the length of \p instr.
|
200
|
+
* As a side effect, if instr_ok_to_mangle(instr) and \p instr's raw bits
|
201
|
+
* are invalid, encodes \p instr into bytes allocated with
|
202
|
+
* instr_allocate_raw_bits(), after which instr is marked as having
|
203
|
+
* valid raw bits.
|
204
|
+
*/
|
205
|
+
int
|
206
|
+
instr_length(void *drcontext, instr_t *instr);
|
207
|
+
|
208
|
+
/** Returns true iff \p instr can be encoding as a valid IA-32 instruction. */
|
209
|
+
bool
|
210
|
+
instr_is_encoding_possible(instr_t *instr);
|
211
|
+
|
212
|
+
/**
|
213
|
+
* Encodes \p instr into the memory at \p pc.
|
214
|
+
* Uses the x86/x64 mode stored in instr, not the mode of the current thread.
|
215
|
+
* Returns the pc after the encoded instr, or NULL if the encoding failed.
|
216
|
+
* If instr is a cti with an instr_t target, the note fields of instr and
|
217
|
+
* of the target must be set with the respective offsets of each instr_t!
|
218
|
+
* (instrlist_encode does this automatically, if the target is in the list).
|
219
|
+
*/
|
220
|
+
byte *
|
221
|
+
instr_encode(void *drcontext, instr_t *instr, byte *pc);
|
222
|
+
|
223
|
+
/** Returns number of bytes of heap used by \p instr. */
|
224
|
+
int
|
225
|
+
instr_mem_usage(instr_t *instr);
|
226
|
+
|
227
|
+
/**
|
228
|
+
* Returns a copy of \p orig with separately allocated memory for
|
229
|
+
* operands and raw bytes if they were present in \p orig.
|
230
|
+
*/
|
231
|
+
instr_t *
|
232
|
+
instr_clone(void *drcontext, instr_t *orig);
|
233
|
+
|
234
|
+
/**
|
235
|
+
* Convenience routine: calls
|
236
|
+
* - instr_create(dcontext)
|
237
|
+
* - instr_set_opcode(opcode)
|
238
|
+
* - instr_set_num_opnds(dcontext, instr, num_dsts, num_srcs)
|
239
|
+
*
|
240
|
+
* and returns the resulting instr_t.
|
241
|
+
*/
|
242
|
+
instr_t *
|
243
|
+
instr_build(void *drcontext, int opcode, int num_dsts, int num_srcs);
|
244
|
+
|
245
|
+
/**
|
246
|
+
* Convenience routine: calls
|
247
|
+
* - instr_create(dcontext)
|
248
|
+
* - instr_set_opcode(instr, opcode)
|
249
|
+
* - instr_allocate_raw_bits(dcontext, instr, num_bytes)
|
250
|
+
*
|
251
|
+
* and returns the resulting instr_t.
|
252
|
+
*/
|
253
|
+
instr_t *
|
254
|
+
instr_build_bits(void *drcontext, int opcode, uint num_bytes);
|
255
|
+
|
256
|
+
/**
|
257
|
+
* Returns true iff \p instr's opcode is NOT OP_INVALID.
|
258
|
+
* Not to be confused with an invalid opcode, which can be OP_INVALID or
|
259
|
+
* OP_UNDECODED. OP_INVALID means an instruction with no valid fields:
|
260
|
+
* raw bits (may exist but do not correspond to a valid instr), opcode,
|
261
|
+
* eflags, or operands. It could be an uninitialized
|
262
|
+
* instruction or the result of decoding an invalid sequence of bytes.
|
263
|
+
*/
|
264
|
+
bool
|
265
|
+
instr_valid(instr_t *instr);
|
266
|
+
|
267
|
+
/** Get the original application PC of \p instr if it exists. */
|
268
|
+
app_pc
|
269
|
+
instr_get_app_pc(instr_t *instr);
|
270
|
+
|
271
|
+
/** Returns \p instr's opcode (an OP_ constant). */
|
272
|
+
int
|
273
|
+
instr_get_opcode(instr_t *instr);
|
274
|
+
|
275
|
+
/** Assumes \p opcode is an OP_ constant and sets it to be instr's opcode. */
|
276
|
+
void
|
277
|
+
instr_set_opcode(instr_t *instr, int opcode);
|
278
|
+
|
279
|
+
/**
|
280
|
+
* Returns the number of source operands of \p instr.
|
281
|
+
*
|
282
|
+
* \note Addressing registers used in destination memory references
|
283
|
+
* (i.e., base, index, or segment registers) are not separately listed
|
284
|
+
* as source operands.
|
285
|
+
*/
|
286
|
+
int
|
287
|
+
instr_num_srcs(instr_t *instr);
|
288
|
+
|
289
|
+
/**
|
290
|
+
* Returns the number of destination operands of \p instr.
|
291
|
+
*/
|
292
|
+
int
|
293
|
+
instr_num_dsts(instr_t *instr);
|
294
|
+
|
295
|
+
/**
|
296
|
+
* Assumes that \p instr has been initialized but does not have any
|
297
|
+
* operands yet. Allocates storage for \p num_srcs source operands
|
298
|
+
* and \p num_dsts destination operands.
|
299
|
+
*/
|
300
|
+
void
|
301
|
+
instr_set_num_opnds(void *drcontext, instr_t *instr, int num_dsts, int num_srcs);
|
302
|
+
|
303
|
+
/**
|
304
|
+
* Returns \p instr's source operand at position \p pos (0-based).
|
305
|
+
*/
|
306
|
+
opnd_t
|
307
|
+
instr_get_src(instr_t *instr, uint pos);
|
308
|
+
|
309
|
+
/**
|
310
|
+
* Returns \p instr's destination operand at position \p pos (0-based).
|
311
|
+
*/
|
312
|
+
opnd_t
|
313
|
+
instr_get_dst(instr_t *instr, uint pos);
|
314
|
+
|
315
|
+
/**
|
316
|
+
* Sets \p instr's source operand at position \p pos to be \p opnd.
|
317
|
+
* Also calls instr_set_raw_bits_valid(\p instr, false) and
|
318
|
+
* instr_set_operands_valid(\p instr, true).
|
319
|
+
*/
|
320
|
+
void
|
321
|
+
instr_set_src(instr_t *instr, uint pos, opnd_t opnd);
|
322
|
+
|
323
|
+
/**
|
324
|
+
* Sets \p instr's destination operand at position \p pos to be \p opnd.
|
325
|
+
* Also calls instr_set_raw_bits_valid(\p instr, false) and
|
326
|
+
* instr_set_operands_valid(\p instr, true).
|
327
|
+
*/
|
328
|
+
void
|
329
|
+
instr_set_dst(instr_t *instr, uint pos, opnd_t opnd);
|
330
|
+
|
331
|
+
/**
|
332
|
+
* Assumes that \p cti_instr is a control transfer instruction
|
333
|
+
* Returns the first source operand of \p cti_instr (its target).
|
334
|
+
*/
|
335
|
+
opnd_t
|
336
|
+
instr_get_target(instr_t *cti_instr);
|
337
|
+
|
338
|
+
/**
|
339
|
+
* Assumes that \p cti_instr is a control transfer instruction.
|
340
|
+
* Sets the first source operand of \p cti_instr to be \p target.
|
341
|
+
* Also calls instr_set_raw_bits_valid(\p instr, false) and
|
342
|
+
* instr_set_operands_valid(\p instr, true).
|
343
|
+
*/
|
344
|
+
void
|
345
|
+
instr_set_target(instr_t *cti_instr, opnd_t target);
|
346
|
+
|
347
|
+
/** Returns true iff \p instr's operands are up to date. */
|
348
|
+
bool
|
349
|
+
instr_operands_valid(instr_t *instr);
|
350
|
+
|
351
|
+
/** Sets \p instr's operands to be valid if \p valid is true, invalid otherwise. */
|
352
|
+
void
|
353
|
+
instr_set_operands_valid(instr_t *instr, bool valid);
|
354
|
+
|
355
|
+
/**
|
356
|
+
* Returns true iff \p instr's opcode is valid.
|
357
|
+
* If the opcode is ever set to other than OP_INVALID or OP_UNDECODED it is assumed
|
358
|
+
* to be valid. However, calling instr_get_opcode() will attempt to
|
359
|
+
* decode a valid opcode, hence the purpose of this routine.
|
360
|
+
*/
|
361
|
+
bool
|
362
|
+
instr_opcode_valid(instr_t *instr);
|
363
|
+
|
364
|
+
/** Returns \p instr's eflags use as EFLAGS_ constants or'ed together. */
|
365
|
+
uint
|
366
|
+
instr_get_eflags(instr_t *instr);
|
367
|
+
|
368
|
+
/** Returns the eflags usage of instructions with opcode \p opcode,
|
369
|
+
* as EFLAGS_ constants or'ed together.
|
370
|
+
*/
|
371
|
+
uint
|
372
|
+
instr_get_opcode_eflags(int opcode);
|
373
|
+
|
374
|
+
/**
|
375
|
+
* Returns \p instr's arithmetic flags (bottom 6 eflags) use
|
376
|
+
* as EFLAGS_ constants or'ed together.
|
377
|
+
* If \p instr's eflags behavior has not been calculated yet or is
|
378
|
+
* invalid, the entire eflags use is calculated and returned (not
|
379
|
+
* just the arithmetic flags).
|
380
|
+
*/
|
381
|
+
uint
|
382
|
+
instr_get_arith_flags(instr_t *instr);
|
383
|
+
|
384
|
+
/**
|
385
|
+
* Assumes that \p instr does not currently have any raw bits allocated.
|
386
|
+
* Sets \p instr's raw bits to be \p length bytes starting at \p addr.
|
387
|
+
* Does not set the operands invalid.
|
388
|
+
*/
|
389
|
+
void
|
390
|
+
instr_set_raw_bits(instr_t *instr, byte * addr, uint length);
|
391
|
+
|
392
|
+
/** Sets \p instr's raw bits to be valid if \p valid is true, invalid otherwise. */
|
393
|
+
void
|
394
|
+
instr_set_raw_bits_valid(instr_t *instr, bool valid);
|
395
|
+
|
396
|
+
/** Returns true iff \p instr's raw bits are a valid encoding of instr. */
|
397
|
+
bool
|
398
|
+
instr_raw_bits_valid(instr_t *instr);
|
399
|
+
|
400
|
+
/** Returns true iff \p instr has its own allocated memory for raw bits. */
|
401
|
+
bool
|
402
|
+
instr_has_allocated_bits(instr_t *instr);
|
403
|
+
|
404
|
+
/** Returns true iff \p instr's raw bits are not a valid encoding of \p instr. */
|
405
|
+
bool
|
406
|
+
instr_needs_encoding(instr_t *instr);
|
407
|
+
|
408
|
+
/**
|
409
|
+
* Return true iff \p instr is not a meta-instruction that can fault
|
410
|
+
* (see instr_set_meta_may_fault() for more information).
|
411
|
+
*/
|
412
|
+
bool
|
413
|
+
instr_is_meta_may_fault(instr_t *instr);
|
414
|
+
|
415
|
+
/**
|
416
|
+
* Sets \p instr as a "meta-instruction that can fault" if \p val is
|
417
|
+
* true and clears that property if \p val is false. This property is
|
418
|
+
* only meaningful for instructions that are marked as "ok to mangle"
|
419
|
+
* (see instr_set_ok_to_mangle()). Normally such instructions are
|
420
|
+
* treated as application instructions (i.e., not as
|
421
|
+
* meta-instructions). The "meta-instruction that can fault" property
|
422
|
+
* indicates that an instruction should be treated as an application
|
423
|
+
* instruction for purposes of fault translation, but not for purposes
|
424
|
+
* of mangling. The property should only be set for instructions that
|
425
|
+
* do not access application memory and therefore do not need
|
426
|
+
* sandboxing to ensure they do not change application code, yet do
|
427
|
+
* access client memory and may deliberately fault (usually to move a
|
428
|
+
* rare case out of the code path and to a fault-based path).
|
429
|
+
*/
|
430
|
+
void
|
431
|
+
instr_set_meta_may_fault(instr_t *instr, bool val);
|
432
|
+
|
433
|
+
/**
|
434
|
+
* Allocates \p num_bytes of memory for \p instr's raw bits.
|
435
|
+
* If \p instr currently points to raw bits, the allocated memory is
|
436
|
+
* initialized with the bytes pointed to.
|
437
|
+
* \p instr is then set to point to the allocated memory.
|
438
|
+
*/
|
439
|
+
void
|
440
|
+
instr_allocate_raw_bits(void *drcontext, instr_t *instr, uint num_bytes);
|
441
|
+
|
442
|
+
/**
|
443
|
+
* Sets the translation pointer for \p instr, used to recreate the
|
444
|
+
* application address corresponding to this instruction. When adding
|
445
|
+
* or modifying instructions that are to be considered application
|
446
|
+
* instructions (i.e., non meta-instructions: see
|
447
|
+
* #instr_ok_to_mangle), the translation should always be set. Pick
|
448
|
+
* the application address that if executed will be equivalent to
|
449
|
+
* restarting \p instr.
|
450
|
+
* Returns the supplied \p instr (for easy chaining). Use
|
451
|
+
* #instr_get_app_pc to see the current value of the translation.
|
452
|
+
*/
|
453
|
+
instr_t *
|
454
|
+
instr_set_translation(instr_t *instr, app_pc addr);
|
455
|
+
|
456
|
+
/**
|
457
|
+
* Calling this function with \p instr makes it safe to keep the
|
458
|
+
* instruction around indefinitely when its raw bits point into the
|
459
|
+
* cache. The function allocates memory local to \p instr to hold a
|
460
|
+
* copy of the raw bits. If this was not done, the original raw bits
|
461
|
+
* could be deleted at some point. Making an instruction persistent
|
462
|
+
* is neccesary if you want to keep it beyond returning from the call
|
463
|
+
* that produced the instruction.
|
464
|
+
*/
|
465
|
+
void
|
466
|
+
instr_make_persistent(void *drcontext, instr_t *instr);
|
467
|
+
|
468
|
+
/**
|
469
|
+
* Assumes that \p instr's raw bits are valid.
|
470
|
+
* Returns a pointer to \p instr's raw bits.
|
471
|
+
* \note A freshly-decoded instruction has valid raw bits that point to the
|
472
|
+
* address from which it was decoded.
|
473
|
+
*/
|
474
|
+
byte *
|
475
|
+
instr_get_raw_bits(instr_t *instr);
|
476
|
+
|
477
|
+
/** If \p instr has raw bits allocated, frees them. */
|
478
|
+
void
|
479
|
+
instr_free_raw_bits(void *drcontext, instr_t *instr);
|
480
|
+
|
481
|
+
/**
|
482
|
+
* Assumes that \p instr's raw bits are valid and have > \p pos bytes.
|
483
|
+
* Returns a pointer to \p instr's raw byte at position \p pos (beginning with 0).
|
484
|
+
*/
|
485
|
+
byte
|
486
|
+
instr_get_raw_byte(instr_t *instr, uint pos);
|
487
|
+
|
488
|
+
/**
|
489
|
+
* Assumes that \p instr's raw bits are valid and allocated by \p instr
|
490
|
+
* and have > \p pos bytes.
|
491
|
+
* Sets instr's raw byte at position \p pos (beginning with 0) to the value \p byte.
|
492
|
+
*/
|
493
|
+
void
|
494
|
+
instr_set_raw_byte(instr_t *instr, uint pos, byte byte);
|
495
|
+
|
496
|
+
/**
|
497
|
+
* Assumes that \p instr's raw bits are valid and allocated by \p instr
|
498
|
+
* and have >= num_bytes bytes.
|
499
|
+
* Copies the \p num_bytes beginning at start to \p instr's raw bits.
|
500
|
+
*/
|
501
|
+
void
|
502
|
+
instr_set_raw_bytes(instr_t *instr, byte *start, uint num_bytes);
|
503
|
+
|
504
|
+
/**
|
505
|
+
* Assumes that \p instr's raw bits are valid and allocated by \p instr
|
506
|
+
* and have > pos+3 bytes.
|
507
|
+
* Sets the 4 bytes beginning at position \p pos (0-based) to the value word.
|
508
|
+
*/
|
509
|
+
void
|
510
|
+
instr_set_raw_word(instr_t *instr, uint pos, uint word);
|
511
|
+
|
512
|
+
/**
|
513
|
+
* Assumes that \p instr's raw bits are valid and have > \p pos + 3 bytes.
|
514
|
+
* Returns the 4 bytes beginning at position \p pos (0-based).
|
515
|
+
*/
|
516
|
+
uint
|
517
|
+
instr_get_raw_word(instr_t *instr, uint pos);
|
518
|
+
|
519
|
+
/**
|
520
|
+
* Assumes that \p prefix is a PREFIX_ constant.
|
521
|
+
* Ors \p instr's prefixes with \p prefix.
|
522
|
+
* Returns the supplied instr (for easy chaining).
|
523
|
+
*/
|
524
|
+
instr_t *
|
525
|
+
instr_set_prefix_flag(instr_t *instr, uint prefix);
|
526
|
+
|
527
|
+
/**
|
528
|
+
* Assumes that \p prefix is a PREFIX_ constant.
|
529
|
+
* Returns true if \p instr's prefixes contain the flag \p prefix.
|
530
|
+
*/
|
531
|
+
bool
|
532
|
+
instr_get_prefix_flag(instr_t *instr, uint prefix);
|
533
|
+
#ifdef X64
|
534
|
+
|
535
|
+
|
536
|
+
/**
|
537
|
+
* Each instruction stores whether it should be interpreted in 32-bit
|
538
|
+
* (x86) or 64-bit (x64) mode. This routine sets the mode for \p instr.
|
539
|
+
*
|
540
|
+
* \note For 64-bit DR builds only.
|
541
|
+
*/
|
542
|
+
void
|
543
|
+
instr_set_x86_mode(instr_t *instr, bool x86);
|
544
|
+
|
545
|
+
/**
|
546
|
+
* Returns true if \p instr is an x86 instruction (32-bit) and false
|
547
|
+
* if \p instr is an x64 instruction (64-bit).
|
548
|
+
*
|
549
|
+
* \note For 64-bit DR builds only.
|
550
|
+
*/
|
551
|
+
bool
|
552
|
+
instr_get_x86_mode(instr_t *instr);
|
553
|
+
#endif
|
554
|
+
|
555
|
+
|
556
|
+
/**
|
557
|
+
* Shrinks all registers not used as addresses, and all immed integer and
|
558
|
+
* address sizes, to 16 bits.
|
559
|
+
* Does not shrink REG_ESI or REG_EDI used in string instructions.
|
560
|
+
*/
|
561
|
+
void
|
562
|
+
instr_shrink_to_16_bits(instr_t *instr);
|
563
|
+
#ifdef X64
|
564
|
+
|
565
|
+
|
566
|
+
/**
|
567
|
+
* Shrinks all registers, including addresses, and all immed integer and
|
568
|
+
* address sizes, to 32 bits.
|
569
|
+
*
|
570
|
+
* \note For 64-bit DR builds only.
|
571
|
+
*/
|
572
|
+
void
|
573
|
+
instr_shrink_to_32_bits(instr_t *instr);
|
574
|
+
#endif
|
575
|
+
|
576
|
+
|
577
|
+
/**
|
578
|
+
* Assumes that \p reg is a REG_ constant.
|
579
|
+
* Returns true iff at least one of \p instr's operands references a
|
580
|
+
* register that overlaps \p reg.
|
581
|
+
*/
|
582
|
+
bool
|
583
|
+
instr_uses_reg(instr_t *instr, reg_id_t reg);
|
584
|
+
|
585
|
+
/**
|
586
|
+
* Returns true iff at least one of \p instr's operands references a floating
|
587
|
+
* point register.
|
588
|
+
*/
|
589
|
+
bool
|
590
|
+
instr_uses_fp_reg(instr_t *instr);
|
591
|
+
|
592
|
+
/**
|
593
|
+
* Assumes that \p reg is a REG_ constant.
|
594
|
+
* Returns true iff at least one of \p instr's source operands references \p reg.
|
595
|
+
*
|
596
|
+
* \note Use instr_reads_from_reg() to also consider addressing
|
597
|
+
* registers in destination operands.
|
598
|
+
*/
|
599
|
+
bool
|
600
|
+
instr_reg_in_src(instr_t *instr, reg_id_t reg);
|
601
|
+
|
602
|
+
/**
|
603
|
+
* Assumes that \p reg is a REG_ constant.
|
604
|
+
* Returns true iff at least one of \p instr's destination operands references \p reg.
|
605
|
+
*/
|
606
|
+
bool
|
607
|
+
instr_reg_in_dst(instr_t *instr, reg_id_t reg);
|
608
|
+
|
609
|
+
/**
|
610
|
+
* Assumes that \p reg is a REG_ constant.
|
611
|
+
* Returns true iff at least one of \p instr's destination operands is
|
612
|
+
* a register operand for a register that overlaps \p reg.
|
613
|
+
*/
|
614
|
+
bool
|
615
|
+
instr_writes_to_reg(instr_t *instr, reg_id_t reg);
|
616
|
+
|
617
|
+
/**
|
618
|
+
* Assumes that reg is a REG_ constant.
|
619
|
+
* Returns true iff at least one of instr's operands reads
|
620
|
+
* from a register that overlaps reg (checks both source operands
|
621
|
+
* and addressing registers used in destination operands).
|
622
|
+
*/
|
623
|
+
bool
|
624
|
+
instr_reads_from_reg(instr_t *instr, reg_id_t reg);
|
625
|
+
|
626
|
+
/**
|
627
|
+
* Assumes that \p reg is a REG_ constant.
|
628
|
+
* Returns true iff at least one of \p instr's destination operands is
|
629
|
+
* the same register (not enough to just overlap) as \p reg.
|
630
|
+
*/
|
631
|
+
bool
|
632
|
+
instr_writes_to_exact_reg(instr_t *instr, reg_id_t reg);
|
633
|
+
|
634
|
+
/**
|
635
|
+
* Replaces all instances of \p old_opnd in \p instr's source operands with
|
636
|
+
* \p new_opnd (uses opnd_same() to detect sameness).
|
637
|
+
*/
|
638
|
+
bool
|
639
|
+
instr_replace_src_opnd(instr_t *instr, opnd_t old_opnd, opnd_t new_opnd);
|
640
|
+
|
641
|
+
/**
|
642
|
+
* Returns true iff \p instr1 and \p instr2 have the same opcode, prefixes,
|
643
|
+
* and source and destination operands (uses opnd_same() to compare the operands).
|
644
|
+
*/
|
645
|
+
bool
|
646
|
+
instr_same(instr_t *instr1, instr_t *instr2);
|
647
|
+
|
648
|
+
/** Returns true iff any of \p instr's source operands is a memory reference. */
|
649
|
+
bool
|
650
|
+
instr_reads_memory(instr_t *instr);
|
651
|
+
|
652
|
+
/** Returns true iff any of \p instr's destination operands is a memory reference. */
|
653
|
+
bool
|
654
|
+
instr_writes_memory(instr_t *instr);
|
655
|
+
#ifdef X64
|
656
|
+
|
657
|
+
|
658
|
+
/**
|
659
|
+
* Returns true iff any of \p instr's operands is a rip-relative memory reference.
|
660
|
+
*
|
661
|
+
* \note For 64-bit DR builds only.
|
662
|
+
*/
|
663
|
+
bool
|
664
|
+
instr_has_rel_addr_reference(instr_t *instr);
|
665
|
+
|
666
|
+
/**
|
667
|
+
* If any of \p instr's operands is a rip-relative memory reference, returns the
|
668
|
+
* address that reference targets. Else returns false.
|
669
|
+
*
|
670
|
+
* \note For 64-bit DR builds only.
|
671
|
+
*/
|
672
|
+
bool
|
673
|
+
instr_get_rel_addr_target(instr_t *instr, /*OUT*/ app_pc *target);
|
674
|
+
|
675
|
+
/**
|
676
|
+
* If any of \p instr's destination operands is a rip-relative memory
|
677
|
+
* reference, returns the operand position. If there is no such
|
678
|
+
* destination operand, returns -1.
|
679
|
+
*
|
680
|
+
* \note For 64-bit DR builds only.
|
681
|
+
*/
|
682
|
+
int
|
683
|
+
instr_get_rel_addr_dst_idx(instr_t *instr);
|
684
|
+
|
685
|
+
/**
|
686
|
+
* If any of \p instr's source operands is a rip-relative memory
|
687
|
+
* reference, returns the operand position. If there is no such
|
688
|
+
* source operand, returns -1.
|
689
|
+
*
|
690
|
+
* \note For 64-bit DR builds only.
|
691
|
+
*/
|
692
|
+
int
|
693
|
+
instr_get_rel_addr_src_idx(instr_t *instr);
|
694
|
+
#endif /* X64 */
|
695
|
+
|
696
|
+
|
697
|
+
/**
|
698
|
+
* Returns NULL if none of \p instr's operands is a memory reference.
|
699
|
+
* Otherwise, returns the effective address of the first memory operand
|
700
|
+
* when the operands are considered in this order: destinations and then
|
701
|
+
* sources. The address is computed using the passed-in registers.
|
702
|
+
*/
|
703
|
+
app_pc
|
704
|
+
instr_compute_address(instr_t *instr, dr_mcontext_t *mc);
|
705
|
+
|
706
|
+
/**
|
707
|
+
* Performs address calculation in the same manner as
|
708
|
+
* instr_compute_address() but handles multiple memory operands. The
|
709
|
+
* \p index parameter should be initially set to 0 and then
|
710
|
+
* incremented with each successive call until this routine returns
|
711
|
+
* false, which indicates that there are no more memory operands. The
|
712
|
+
* address of each is computed in the same manner as
|
713
|
+
* instr_compute_address() and returned in \p addr; whether it is a
|
714
|
+
* write is returned in \p is_write. Either or both OUT variables can
|
715
|
+
* be NULL.
|
716
|
+
*/
|
717
|
+
bool
|
718
|
+
instr_compute_address_ex(instr_t *instr, dr_mcontext_t *mc, uint index,
|
719
|
+
OUT app_pc *addr, OUT bool *write);
|
720
|
+
|
721
|
+
/**
|
722
|
+
* Calculates the size, in bytes, of the memory read or write of \p instr.
|
723
|
+
* If \p instr does not reference memory, or is invalid, returns 0.
|
724
|
+
* If \p instr is a repeated string instruction, considers only one iteration.
|
725
|
+
*/
|
726
|
+
uint
|
727
|
+
instr_memory_reference_size(instr_t *instr);
|
728
|
+
|
729
|
+
/**
|
730
|
+
* Returns true iff \p instr is an IA-32 "mov" instruction: either OP_mov_st,
|
731
|
+
* OP_mov_ld, OP_mov_imm, OP_mov_seg, or OP_mov_priv.
|
732
|
+
*/
|
733
|
+
bool
|
734
|
+
instr_is_mov(instr_t *instr);
|
735
|
+
|
736
|
+
/**
|
737
|
+
* Returns true iff \p instr's opcode is OP_call, OP_call_far, OP_call_ind,
|
738
|
+
* or OP_call_far_ind.
|
739
|
+
*/
|
740
|
+
bool
|
741
|
+
instr_is_call(instr_t *instr);
|
742
|
+
|
743
|
+
/** Returns true iff \p instr's opcode is OP_call or OP_call_far. */
|
744
|
+
bool
|
745
|
+
instr_is_call_direct(instr_t *instr);
|
746
|
+
|
747
|
+
/** Returns true iff \p instr's opcode is OP_call_ind or OP_call_far_ind. */
|
748
|
+
bool
|
749
|
+
instr_is_call_indirect(instr_t *instr);
|
750
|
+
|
751
|
+
/** Returns true iff \p instr's opcode is OP_ret, OP_ret_far, or OP_iret. */
|
752
|
+
bool
|
753
|
+
instr_is_return(instr_t *instr);
|
754
|
+
|
755
|
+
/**
|
756
|
+
* Returns true iff \p instr is a control transfer instruction of any kind
|
757
|
+
* This includes OP_jcc, OP_jcc_short, OP_loop*, OP_jecxz, OP_call*, and OP_jmp*.
|
758
|
+
*/
|
759
|
+
bool
|
760
|
+
instr_is_cti(instr_t *instr);
|
761
|
+
|
762
|
+
/**
|
763
|
+
* Returns true iff \p instr is a control transfer instruction that takes an
|
764
|
+
* 8-bit offset: OP_loop*, OP_jecxz, OP_jmp_short, or OP_jcc_short
|
765
|
+
*/
|
766
|
+
bool
|
767
|
+
instr_is_cti_short(instr_t *instr);
|
768
|
+
|
769
|
+
/** Returns true iff \p instr is one of OP_loop* or OP_jecxz. */
|
770
|
+
bool
|
771
|
+
instr_is_cti_loop(instr_t *instr);
|
772
|
+
|
773
|
+
/**
|
774
|
+
* Returns true iff \p instr's opcode is OP_loop* or OP_jecxz and instr has
|
775
|
+
* been transformed to a sequence of instruction that will allow a 32-bit
|
776
|
+
* offset.
|
777
|
+
* If \p pc != NULL, \p pc is expected to point the the beginning of the encoding of
|
778
|
+
* \p instr, and the following instructions are assumed to be encoded in sequence
|
779
|
+
* after \p instr.
|
780
|
+
* Otherwise, the encoding is expected to be found in \p instr's allocated bits.
|
781
|
+
*/
|
782
|
+
bool
|
783
|
+
instr_is_cti_short_rewrite(instr_t *instr, byte *pc);
|
784
|
+
|
785
|
+
/**
|
786
|
+
* Returns true iff \p instr is a conditional branch: OP_jcc, OP_jcc_short,
|
787
|
+
* OP_loop*, or OP_jecxz.
|
788
|
+
*/
|
789
|
+
bool
|
790
|
+
instr_is_cbr(instr_t *instr);
|
791
|
+
|
792
|
+
/**
|
793
|
+
* Returns true iff \p instr is a multi-way (indirect) branch: OP_jmp_ind,
|
794
|
+
* OP_call_ind, OP_ret, OP_jmp_far_ind, OP_call_far_ind, OP_ret_far, or
|
795
|
+
* OP_iret.
|
796
|
+
*/
|
797
|
+
bool
|
798
|
+
instr_is_mbr(instr_t *instr);
|
799
|
+
|
800
|
+
/**
|
801
|
+
* Returns true iff \p instr is an unconditional direct branch: OP_jmp,
|
802
|
+
* OP_jmp_short, or OP_jmp_far.
|
803
|
+
*/
|
804
|
+
bool
|
805
|
+
instr_is_ubr(instr_t *instr);
|
806
|
+
|
807
|
+
/**
|
808
|
+
* Returns true iff \p instr is a far control transfer instruction: OP_jmp_far,
|
809
|
+
* OP_call_far, OP_jmp_far_ind, OP_call_far_ind, OP_ret_far, or OP_iret.
|
810
|
+
*/
|
811
|
+
bool
|
812
|
+
instr_is_far_cti(instr_t *instr);
|
813
|
+
|
814
|
+
/** Returns true if \p instr is an absolute call or jmp that is far. */
|
815
|
+
bool
|
816
|
+
instr_is_far_abs_cti(instr_t *instr);
|
817
|
+
|
818
|
+
/**
|
819
|
+
* Returns true iff \p instr is used to implement system calls: OP_int with a
|
820
|
+
* source operand of 0x80 on linux or 0x2e on windows, or OP_sysenter,
|
821
|
+
* or OP_syscall, or #instr_is_wow64_syscall() for WOW64.
|
822
|
+
*/
|
823
|
+
bool
|
824
|
+
instr_is_syscall(instr_t *instr);
|
825
|
+
#ifdef WINDOWS
|
826
|
+
|
827
|
+
|
828
|
+
/**
|
829
|
+
* Returns true iff \p instr is the indirect transfer from the 32-bit
|
830
|
+
* ntdll.dll to the wow64 system call emulation layer. This
|
831
|
+
* instruction will also return true for instr_is_syscall, as well as
|
832
|
+
* appear as an indirect call, so clients modifying indirect calls may
|
833
|
+
* want to avoid modifying this type.
|
834
|
+
*
|
835
|
+
* \note Windows-only
|
836
|
+
*/
|
837
|
+
bool
|
838
|
+
instr_is_wow64_syscall(instr_t *instr);
|
839
|
+
#endif
|
840
|
+
|
841
|
+
|
842
|
+
/**
|
843
|
+
* Returns true iff \p instr is a prefetch instruction: OP_prefetchnta,
|
844
|
+
* OP_prefetchnt0, OP_prefetchnt1, OP_prefetchnt2, OP_prefetch, or
|
845
|
+
* OP_prefetchw.
|
846
|
+
*/
|
847
|
+
bool
|
848
|
+
instr_is_prefetch(instr_t *instr);
|
849
|
+
|
850
|
+
/**
|
851
|
+
* Tries to identify common cases of moving a constant into either a
|
852
|
+
* register or a memory address.
|
853
|
+
* Returns true and sets \p *value to the constant being moved for the following
|
854
|
+
* cases: mov_imm, mov_st, and xor where the source equals the destination.
|
855
|
+
*/
|
856
|
+
bool
|
857
|
+
instr_is_mov_constant(instr_t *instr, ptr_int_t *value);
|
858
|
+
|
859
|
+
/** Returns true iff \p instr is a floating point instruction. */
|
860
|
+
bool
|
861
|
+
instr_is_floating(instr_t *instr);
|
862
|
+
|
863
|
+
/** Returns true iff \p instr is part of Intel's MMX instructions. */
|
864
|
+
bool
|
865
|
+
instr_is_mmx(instr_t *instr);
|
866
|
+
|
867
|
+
/** Returns true iff \p instr is part of Intel's SSE or SSE2 instructions. */
|
868
|
+
bool
|
869
|
+
instr_is_sse_or_sse2(instr_t *instr);
|
870
|
+
|
871
|
+
/** Returns true iff \p instr is a "mov $imm -> (%esp)". */
|
872
|
+
bool
|
873
|
+
instr_is_mov_imm_to_tos(instr_t *instr);
|
874
|
+
|
875
|
+
/** Returns true iff \p instr is a label meta-instruction. */
|
876
|
+
bool
|
877
|
+
instr_is_label(instr_t *instr);
|
878
|
+
|
879
|
+
/**
|
880
|
+
* Assumes that \p instr's opcode is OP_int and that either \p instr's
|
881
|
+
* operands or its raw bits are valid.
|
882
|
+
* Returns the first source operand if \p instr's operands are valid,
|
883
|
+
* else if \p instr's raw bits are valid returns the first raw byte.
|
884
|
+
*/
|
885
|
+
int
|
886
|
+
instr_get_interrupt_number(instr_t *instr);
|
887
|
+
|
888
|
+
/**
|
889
|
+
* Assumes that \p instr is a conditional branch instruction
|
890
|
+
* Reverses the logic of \p instr's conditional
|
891
|
+
* e.g., changes OP_jb to OP_jnb.
|
892
|
+
* Works on cti_short_rewrite as well.
|
893
|
+
*/
|
894
|
+
void
|
895
|
+
instr_invert_cbr(instr_t *instr);
|
896
|
+
|
897
|
+
/**
|
898
|
+
* Assumes that instr is a meta instruction (!instr_ok_to_mangle())
|
899
|
+
* and an instr_is_cti_short() (8-bit reach). Converts instr's opcode
|
900
|
+
* to a long form (32-bit reach). If instr's opcode is OP_loop* or
|
901
|
+
* OP_jecxz, converts it to a sequence of multiple instructions (which
|
902
|
+
* is different from instr_is_cti_short_rewrite()). Each added instruction
|
903
|
+
* is marked !instr_ok_to_mangle().
|
904
|
+
* Returns the long form of the instruction, which is identical to \p instr
|
905
|
+
* unless \p instr is OP_loop* or OP_jecxz, in which case the return value
|
906
|
+
* is the final instruction in the sequence, the one that has long reach.
|
907
|
+
* \note DR automatically converts non-meta short ctis to long form.
|
908
|
+
*/
|
909
|
+
instr_t *
|
910
|
+
instr_convert_short_meta_jmp_to_long(void *drcontext, instrlist_t *ilist,
|
911
|
+
instr_t *instr);
|
912
|
+
|
913
|
+
/**
|
914
|
+
* Given \p eflags, returns whether or not the conditional branch, \p
|
915
|
+
* instr, would be taken.
|
916
|
+
*/
|
917
|
+
bool
|
918
|
+
instr_jcc_taken(instr_t *instr, reg_t eflags);
|
919
|
+
|
920
|
+
/**
|
921
|
+
* Returns true if \p instr is one of a class of common nops.
|
922
|
+
* currently checks:
|
923
|
+
* - xchg reg, reg
|
924
|
+
* - mov reg, reg
|
925
|
+
* - lea reg, (reg)
|
926
|
+
*/
|
927
|
+
bool
|
928
|
+
instr_is_nop(instr_t *instr);
|
929
|
+
|
930
|
+
/**
|
931
|
+
* Convenience routine that returns an initialized instr_t allocated on the
|
932
|
+
* thread-local heap with opcode \p opcode and no sources or destinations.
|
933
|
+
*/
|
934
|
+
instr_t *
|
935
|
+
instr_create_0dst_0src(void *drcontext, int opcode);
|
936
|
+
|
937
|
+
/**
|
938
|
+
* Convenience routine that returns an initialized instr_t allocated on the
|
939
|
+
* thread-local heap with opcode \p opcode and a single source (\p src).
|
940
|
+
*/
|
941
|
+
instr_t *
|
942
|
+
instr_create_0dst_1src(void *drcontext, int opcode,
|
943
|
+
opnd_t src);
|
944
|
+
|
945
|
+
/**
|
946
|
+
* Convenience routine that returns an initialized instr_t allocated on the
|
947
|
+
* thread-local heap with opcode \p opcode and two sources (\p src1, \p src2).
|
948
|
+
*/
|
949
|
+
instr_t *
|
950
|
+
instr_create_0dst_2src(void *drcontext, int opcode,
|
951
|
+
opnd_t src1, opnd_t src2);
|
952
|
+
|
953
|
+
/**
|
954
|
+
* Convenience routine that returns an initialized instr_t allocated
|
955
|
+
* on the thread-local heap with opcode \p opcode and three sources
|
956
|
+
* (\p src1, \p src2, \p src3).
|
957
|
+
*/
|
958
|
+
instr_t *
|
959
|
+
instr_create_0dst_3src(void *drcontext, int opcode,
|
960
|
+
opnd_t src1, opnd_t src2, opnd_t src3);
|
961
|
+
|
962
|
+
/**
|
963
|
+
* Convenience routine that returns an initialized instr_t allocated on the
|
964
|
+
* thread-local heap with opcode \p opcode and one destination (\p dst).
|
965
|
+
*/
|
966
|
+
instr_t *
|
967
|
+
instr_create_1dst_0src(void *drcontext, int opcode,
|
968
|
+
opnd_t dst);
|
969
|
+
|
970
|
+
/**
|
971
|
+
* Convenience routine that returns an initialized instr_t allocated on the
|
972
|
+
* thread-local heap with opcode \p opcode, one destination(\p dst),
|
973
|
+
* and one source (\p src).
|
974
|
+
*/
|
975
|
+
instr_t *
|
976
|
+
instr_create_1dst_1src(void *drcontext, int opcode,
|
977
|
+
opnd_t dst, opnd_t src);
|
978
|
+
|
979
|
+
/**
|
980
|
+
* Convenience routine that returns an initialized instr_t allocated on the
|
981
|
+
* thread-local heap with opcode \p opcode, one destination (\p dst),
|
982
|
+
* and two sources (\p src1, \p src2).
|
983
|
+
*/
|
984
|
+
instr_t *
|
985
|
+
instr_create_1dst_2src(void *drcontext, int opcode,
|
986
|
+
opnd_t dst, opnd_t src1, opnd_t src2);
|
987
|
+
|
988
|
+
/**
|
989
|
+
* Convenience routine that returns an initialized instr_t allocated on the
|
990
|
+
* thread-local heap with opcode \p opcode, one destination (\p dst),
|
991
|
+
* and three sources (\p src1, \p src2, \p src3).
|
992
|
+
*/
|
993
|
+
instr_t *
|
994
|
+
instr_create_1dst_3src(void *drcontext, int opcode,
|
995
|
+
opnd_t dst, opnd_t src1, opnd_t src2, opnd_t src3);
|
996
|
+
|
997
|
+
/**
|
998
|
+
* Convenience routine that returns an initialized instr_t allocated on the
|
999
|
+
* thread-local heap with opcode \p opcode, one destination (\p dst),
|
1000
|
+
* and five sources (\p src1, \p src2, \p src3, \p src4, \p src5).
|
1001
|
+
*/
|
1002
|
+
instr_t *
|
1003
|
+
instr_create_1dst_5src(void *drcontext, int opcode,
|
1004
|
+
opnd_t dst, opnd_t src1, opnd_t src2, opnd_t src3,
|
1005
|
+
opnd_t src4, opnd_t src5);
|
1006
|
+
|
1007
|
+
/**
|
1008
|
+
* Convenience routine that returns an initialized instr_t allocated on the
|
1009
|
+
* thread-local heap with opcode \p opcode, two destinations (\p dst1, \p dst2)
|
1010
|
+
* and no sources.
|
1011
|
+
*/
|
1012
|
+
instr_t *
|
1013
|
+
instr_create_2dst_0src(void *drcontext, int opcode,
|
1014
|
+
opnd_t dst1, opnd_t dst2);
|
1015
|
+
|
1016
|
+
/**
|
1017
|
+
* Convenience routine that returns an initialized instr_t allocated on the
|
1018
|
+
* thread-local heap with opcode \p opcode, two destinations (\p dst1, \p dst2)
|
1019
|
+
* and one source (\p src).
|
1020
|
+
*/
|
1021
|
+
instr_t *
|
1022
|
+
instr_create_2dst_1src(void *drcontext, int opcode,
|
1023
|
+
opnd_t dst1, opnd_t dst2, opnd_t src);
|
1024
|
+
|
1025
|
+
/**
|
1026
|
+
* Convenience routine that returns an initialized instr_t allocated on the
|
1027
|
+
* thread-local heap with opcode \p opcode, two destinations (\p dst1, \p dst2)
|
1028
|
+
* and two sources (\p src1, \p src2).
|
1029
|
+
*/
|
1030
|
+
instr_t *
|
1031
|
+
instr_create_2dst_2src(void *drcontext, int opcode,
|
1032
|
+
opnd_t dst1, opnd_t dst2, opnd_t src1, opnd_t src2);
|
1033
|
+
|
1034
|
+
/**
|
1035
|
+
* Convenience routine that returns an initialized instr_t allocated on the
|
1036
|
+
* thread-local heap with opcode \p opcode, two destinations (\p dst1, \p dst2)
|
1037
|
+
* and three sources (\p src1, \p src2, \p src3).
|
1038
|
+
*/
|
1039
|
+
instr_t *
|
1040
|
+
instr_create_2dst_3src(void *drcontext, int opcode,
|
1041
|
+
opnd_t dst1, opnd_t dst2,
|
1042
|
+
opnd_t src1, opnd_t src2, opnd_t src3);
|
1043
|
+
|
1044
|
+
/**
|
1045
|
+
* Convenience routine that returns an initialized instr_t allocated on the
|
1046
|
+
* thread-local heap with opcode \p opcode, two destinations (\p dst1, \p dst2)
|
1047
|
+
* and four sources (\p src1, \p src2, \p src3, \p src4).
|
1048
|
+
*/
|
1049
|
+
instr_t *
|
1050
|
+
instr_create_2dst_4src(void *drcontext, int opcode,
|
1051
|
+
opnd_t dst1, opnd_t dst2,
|
1052
|
+
opnd_t src1, opnd_t src2, opnd_t src3, opnd_t src4);
|
1053
|
+
|
1054
|
+
/**
|
1055
|
+
* Convenience routine that returns an initialized instr_t allocated
|
1056
|
+
* on the thread-local heap with opcode \p opcode, three destinations
|
1057
|
+
* (\p dst1, \p dst2, \p dst3) and no sources.
|
1058
|
+
*/
|
1059
|
+
instr_t *
|
1060
|
+
instr_create_3dst_0src(void *drcontext, int opcode,
|
1061
|
+
opnd_t dst1, opnd_t dst2, opnd_t dst3);
|
1062
|
+
|
1063
|
+
/**
|
1064
|
+
* Convenience routine that returns an initialized instr_t allocated
|
1065
|
+
* on the thread-local heap with opcode \p opcode, three destinations
|
1066
|
+
* (\p dst1, \p dst2, \p dst3) and three sources
|
1067
|
+
* (\p src1, \p src2, \p src3).
|
1068
|
+
*/
|
1069
|
+
instr_t *
|
1070
|
+
instr_create_3dst_3src(void *drcontext, int opcode,
|
1071
|
+
opnd_t dst1, opnd_t dst2, opnd_t dst3,
|
1072
|
+
opnd_t src1, opnd_t src2, opnd_t src3);
|
1073
|
+
|
1074
|
+
/**
|
1075
|
+
* Convenience routine that returns an initialized instr_t allocated
|
1076
|
+
* on the thread-local heap with opcode \p opcode, three destinations
|
1077
|
+
* (\p dst1, \p dst2, \p dst3) and four sources
|
1078
|
+
* (\p src1, \p src2, \p src3, \p src4).
|
1079
|
+
*/
|
1080
|
+
instr_t *
|
1081
|
+
instr_create_3dst_4src(void *drcontext, int opcode,
|
1082
|
+
opnd_t dst1, opnd_t dst2, opnd_t dst3,
|
1083
|
+
opnd_t src1, opnd_t src2, opnd_t src3, opnd_t src4);
|
1084
|
+
|
1085
|
+
/**
|
1086
|
+
* Convenience routine that returns an initialized instr_t allocated
|
1087
|
+
* on the thread-local heap with opcode \p opcode, three destinations
|
1088
|
+
* (\p dst1, \p dst2, \p dst3) and five sources
|
1089
|
+
* (\p src1, \p src2, \p src3, \p src4, \p src5).
|
1090
|
+
*/
|
1091
|
+
instr_t *
|
1092
|
+
instr_create_3dst_5src(void *drcontext, int opcode,
|
1093
|
+
opnd_t dst1, opnd_t dst2, opnd_t dst3,
|
1094
|
+
opnd_t src1, opnd_t src2, opnd_t src3,
|
1095
|
+
opnd_t src4, opnd_t src5);
|
1096
|
+
|
1097
|
+
/**
|
1098
|
+
* Convenience routine that returns an initialized instr_t allocated
|
1099
|
+
* on the thread-local heap with opcode \p opcode, four destinations
|
1100
|
+
* (\p dst1, \p dst2, \p dst3, \p dst4) and 1 source (\p src).
|
1101
|
+
*/
|
1102
|
+
instr_t *
|
1103
|
+
instr_create_4dst_1src(void *drcontext, int opcode,
|
1104
|
+
opnd_t dst1, opnd_t dst2, opnd_t dst3, opnd_t dst4,
|
1105
|
+
opnd_t src);
|
1106
|
+
|
1107
|
+
/**
|
1108
|
+
* Convenience routine that returns an initialized instr_t allocated
|
1109
|
+
* on the thread-local heap with opcode \p opcode, four destinations
|
1110
|
+
* (\p dst1, \p dst2, \p dst3, \p dst4) and four sources
|
1111
|
+
* (\p src1, \p src2, \p src3, \p src4).
|
1112
|
+
*/
|
1113
|
+
instr_t *
|
1114
|
+
instr_create_4dst_4src(void *drcontext, int opcode,
|
1115
|
+
opnd_t dst1, opnd_t dst2, opnd_t dst3, opnd_t dst4,
|
1116
|
+
opnd_t src1, opnd_t src2, opnd_t src3, opnd_t src4);
|
1117
|
+
|
1118
|
+
/** Convenience routine that returns an initialized instr_t for OP_popa. */
|
1119
|
+
instr_t *
|
1120
|
+
instr_create_popa(void *drcontext);
|
1121
|
+
|
1122
|
+
/** Convenience routine that returns an initialized instr_t for OP_pusha. */
|
1123
|
+
instr_t *
|
1124
|
+
instr_create_pusha(void *drcontext);
|
1125
|
+
|
1126
|
+
|
1127
|
+
/****************************************************************************
|
1128
|
+
* EFLAGS
|
1129
|
+
*/
|
1130
|
+
/* we only care about these 11 flags, and mostly only about the first 6
|
1131
|
+
* we consider an undefined effect on a flag to be a write
|
1132
|
+
*/
|
1133
|
+
#define EFLAGS_READ_CF 0x00000001 /**< Reads CF (Carry Flag). */
|
1134
|
+
#define EFLAGS_READ_PF 0x00000002 /**< Reads PF (Parity Flag). */
|
1135
|
+
#define EFLAGS_READ_AF 0x00000004 /**< Reads AF (Auxiliary Carry Flag). */
|
1136
|
+
#define EFLAGS_READ_ZF 0x00000008 /**< Reads ZF (Zero Flag). */
|
1137
|
+
#define EFLAGS_READ_SF 0x00000010 /**< Reads SF (Sign Flag). */
|
1138
|
+
#define EFLAGS_READ_TF 0x00000020 /**< Reads TF (Trap Flag). */
|
1139
|
+
#define EFLAGS_READ_IF 0x00000040 /**< Reads IF (Interrupt Enable Flag). */
|
1140
|
+
#define EFLAGS_READ_DF 0x00000080 /**< Reads DF (Direction Flag). */
|
1141
|
+
#define EFLAGS_READ_OF 0x00000100 /**< Reads OF (Overflow Flag). */
|
1142
|
+
#define EFLAGS_READ_NT 0x00000200 /**< Reads NT (Nested Task). */
|
1143
|
+
#define EFLAGS_READ_RF 0x00000400 /**< Reads RF (Resume Flag). */
|
1144
|
+
#define EFLAGS_WRITE_CF 0x00000800 /**< Writes CF (Carry Flag). */
|
1145
|
+
#define EFLAGS_WRITE_PF 0x00001000 /**< Writes PF (Parity Flag). */
|
1146
|
+
#define EFLAGS_WRITE_AF 0x00002000 /**< Writes AF (Auxiliary Carry Flag). */
|
1147
|
+
#define EFLAGS_WRITE_ZF 0x00004000 /**< Writes ZF (Zero Flag). */
|
1148
|
+
#define EFLAGS_WRITE_SF 0x00008000 /**< Writes SF (Sign Flag). */
|
1149
|
+
#define EFLAGS_WRITE_TF 0x00010000 /**< Writes TF (Trap Flag). */
|
1150
|
+
#define EFLAGS_WRITE_IF 0x00020000 /**< Writes IF (Interrupt Enable Flag). */
|
1151
|
+
#define EFLAGS_WRITE_DF 0x00040000 /**< Writes DF (Direction Flag). */
|
1152
|
+
#define EFLAGS_WRITE_OF 0x00080000 /**< Writes OF (Overflow Flag). */
|
1153
|
+
#define EFLAGS_WRITE_NT 0x00100000 /**< Writes NT (Nested Task). */
|
1154
|
+
#define EFLAGS_WRITE_RF 0x00200000 /**< Writes RF (Resume Flag). */
|
1155
|
+
|
1156
|
+
#define EFLAGS_READ_ALL 0x000007ff /**< Reads all flags. */
|
1157
|
+
#define EFLAGS_WRITE_ALL 0x003ff800 /**< Writes all flags. */
|
1158
|
+
/* 6 most common flags ("arithmetic flags"): CF, PF, AF, ZF, SF, OF */
|
1159
|
+
/** Reads all 6 arithmetic flags (CF, PF, AF, ZF, SF, OF). */
|
1160
|
+
#define EFLAGS_READ_6 0x0000011f
|
1161
|
+
/** Writes all 6 arithmetic flags (CF, PF, AF, ZF, SF, OF). */
|
1162
|
+
#define EFLAGS_WRITE_6 0x0008f800
|
1163
|
+
|
1164
|
+
/** Converts an EFLAGS_WRITE_* value to the corresponding EFLAGS_READ_* value. */
|
1165
|
+
#define EFLAGS_WRITE_TO_READ(x) ((x) >> 11)
|
1166
|
+
/** Converts an EFLAGS_READ_* value to the corresponding EFLAGS_WRITE_* value. */
|
1167
|
+
#define EFLAGS_READ_TO_WRITE(x) ((x) << 11)
|
1168
|
+
|
1169
|
+
/**
|
1170
|
+
* The actual bits in the eflags register that we care about:\n<pre>
|
1171
|
+
* 11 10 9 8 7 6 5 4 3 2 1 0
|
1172
|
+
* OF DF SF ZF AF PF CF </pre>
|
1173
|
+
*/
|
1174
|
+
enum {
|
1175
|
+
EFLAGS_CF = 0x00000001, /**< The bit in the eflags register of CF (Carry Flag). */
|
1176
|
+
EFLAGS_PF = 0x00000004, /**< The bit in the eflags register of PF (Parity Flag). */
|
1177
|
+
EFLAGS_AF = 0x00000010, /**< The bit in the eflags register of AF (Aux Carry Flag). */
|
1178
|
+
EFLAGS_ZF = 0x00000040, /**< The bit in the eflags register of ZF (Zero Flag). */
|
1179
|
+
EFLAGS_SF = 0x00000080, /**< The bit in the eflags register of SF (Sign Flag). */
|
1180
|
+
EFLAGS_DF = 0x00000400, /**< The bit in the eflags register of DF (Direction Flag). */
|
1181
|
+
EFLAGS_OF = 0x00000800, /**< The bit in the eflags register of OF (Overflow Flag). */
|
1182
|
+
};
|
1183
|
+
|
1184
|
+
|
1185
|
+
|
1186
|
+
/****************************************************************************
|
1187
|
+
* instr_t prefixes
|
1188
|
+
*
|
1189
|
+
* Note that prefixes that change the data or address size, or that
|
1190
|
+
* specify a different base segment, are not specified on a
|
1191
|
+
* whole-instruction level, but rather on individual operands (of
|
1192
|
+
* course with multiple operands they must all match).
|
1193
|
+
* The rep and repne prefixes are encoded directly into the opcodes.
|
1194
|
+
*
|
1195
|
+
*/
|
1196
|
+
#define PREFIX_LOCK 0x1 /**< Makes the instruction's memory accesses atomic. */
|
1197
|
+
#define PREFIX_JCC_NOT_TAKEN 0x2 /**< Branch hint: conditional branch is taken. */
|
1198
|
+
#define PREFIX_JCC_TAKEN 0x4 /**< Branch hint: conditional branch is not taken. */
|
1199
|
+
|
1200
|
+
|
1201
|
+
|
1202
|
+
/**
|
1203
|
+
* Prints the instruction \p instr to file \p outfile.
|
1204
|
+
* Does not print address-size or data-size prefixes for other than
|
1205
|
+
* just-decoded instrs, and does not check that the instruction has a
|
1206
|
+
* valid encoding. Prints each operand with leading zeros indicating
|
1207
|
+
* the size.
|
1208
|
+
* The default is to use AT&T-style syntax, unless the \ref op_syntax_intel
|
1209
|
+
* "-syntax_intel" runtime option is specified.
|
1210
|
+
*/
|
1211
|
+
void
|
1212
|
+
instr_disassemble(void *drcontext, instr_t *instr, file_t outfile);
|
1213
|
+
|
1214
|
+
#endif /* _DR_IR_INSTR_H_ */
|