Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/dep/zydis/include/Zydis/Formatter.h
4216 views
1
/***************************************************************************************************
2
3
Zyan Disassembler Library (Zydis)
4
5
Original Author : Florian Bernd
6
7
* Permission is hereby granted, free of charge, to any person obtaining a copy
8
* of this software and associated documentation files (the "Software"), to deal
9
* in the Software without restriction, including without limitation the rights
10
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
* copies of the Software, and to permit persons to whom the Software is
12
* furnished to do so, subject to the following conditions:
13
*
14
* The above copyright notice and this permission notice shall be included in all
15
* copies or substantial portions of the Software.
16
*
17
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
* SOFTWARE.
24
25
***************************************************************************************************/
26
27
/**
28
* @file
29
* Functions for formatting instructions to human-readable text.
30
*/
31
32
#ifndef ZYDIS_FORMATTER_H
33
#define ZYDIS_FORMATTER_H
34
35
#include <Zycore/Defines.h>
36
#include <Zycore/String.h>
37
#include <Zycore/Types.h>
38
#include <Zydis/DecoderTypes.h>
39
#include <Zydis/FormatterBuffer.h>
40
41
#ifdef __cplusplus
42
extern "C" {
43
#endif
44
45
/* ============================================================================================== */
46
/* Constants */
47
/* ============================================================================================== */
48
49
/**
50
* Use this constant as value for `runtime_address` in `ZydisFormatterFormatInstruction(Ex)`
51
* or `ZydisFormatterFormatOperand(Ex)` to print relative values for all addresses.
52
*/
53
#define ZYDIS_RUNTIME_ADDRESS_NONE (ZyanU64)(-1)
54
55
/* ============================================================================================== */
56
/* Enums and types */
57
/* ============================================================================================== */
58
59
/* ---------------------------------------------------------------------------------------------- */
60
/* Formatter style */
61
/* ---------------------------------------------------------------------------------------------- */
62
63
/**
64
* Enum selecting the syntax to format the disassembly in.
65
*/
66
typedef enum ZydisFormatterStyle_
67
{
68
/**
69
* Generates `AT&T`-style disassembly.
70
*/
71
ZYDIS_FORMATTER_STYLE_ATT,
72
/**
73
* Generates `Intel`-style disassembly.
74
*/
75
ZYDIS_FORMATTER_STYLE_INTEL,
76
/**
77
* Generates `MASM`-style disassembly that is directly accepted as input for
78
* the `MASM` assembler.
79
*
80
* The runtime-address is ignored in this mode.
81
*/
82
ZYDIS_FORMATTER_STYLE_INTEL_MASM,
83
84
/**
85
* Maximum value of this enum.
86
*/
87
ZYDIS_FORMATTER_STYLE_MAX_VALUE = ZYDIS_FORMATTER_STYLE_INTEL_MASM,
88
/**
89
* The minimum number of bits required to represent all values of this enum.
90
*/
91
ZYDIS_FORMATTER_STYLE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_FORMATTER_STYLE_MAX_VALUE)
92
} ZydisFormatterStyle;
93
94
/* ---------------------------------------------------------------------------------------------- */
95
/* Properties */
96
/* ---------------------------------------------------------------------------------------------- */
97
98
/**
99
* Enum selecting a property of the formatter.
100
*/
101
typedef enum ZydisFormatterProperty_
102
{
103
/* ---------------------------------------------------------------------------------------- */
104
/* General */
105
/* ---------------------------------------------------------------------------------------- */
106
107
/**
108
* Controls the printing of effective operand-size suffixes (`AT&T`) or operand-sizes
109
* of memory operands (`INTEL`).
110
*
111
* Pass `ZYAN_TRUE` as value to force the formatter to always print the size, or `ZYAN_FALSE`
112
* to only print it if needed.
113
*/
114
ZYDIS_FORMATTER_PROP_FORCE_SIZE,
115
/**
116
* Controls the printing of segment prefixes.
117
*
118
* Pass `ZYAN_TRUE` as value to force the formatter to always print the segment register of
119
* memory-operands or `ZYAN_FALSE` to omit implicit `DS`/`SS` segments.
120
*/
121
ZYDIS_FORMATTER_PROP_FORCE_SEGMENT,
122
/**
123
* Controls the printing of the scale-factor component for memory operands.
124
*
125
* Pass `ZYAN_TRUE` as value to force the formatter to always print the scale-factor component
126
* of memory operands or `ZYAN_FALSE` to omit the scale factor for values of `1`.
127
*/
128
ZYDIS_FORMATTER_PROP_FORCE_SCALE_ONE,
129
/**
130
* Controls the printing of branch addresses.
131
*
132
* Pass `ZYAN_TRUE` as value to force the formatter to always print relative branch addresses
133
* or `ZYAN_FALSE` to use absolute addresses, if a runtime-address different to
134
* `ZYDIS_RUNTIME_ADDRESS_NONE` was passed.
135
*/
136
ZYDIS_FORMATTER_PROP_FORCE_RELATIVE_BRANCHES,
137
/**
138
* Controls the printing of `EIP`/`RIP`-relative addresses.
139
*
140
* Pass `ZYAN_TRUE` as value to force the formatter to always print relative addresses for
141
* `EIP`/`RIP`-relative operands or `ZYAN_FALSE` to use absolute addresses, if a runtime-
142
* address different to `ZYDIS_RUNTIME_ADDRESS_NONE` was passed.
143
*/
144
ZYDIS_FORMATTER_PROP_FORCE_RELATIVE_RIPREL,
145
/**
146
* Controls the printing of branch-instructions sizes.
147
*
148
* Pass `ZYAN_TRUE` as value to print the size (`short`, `near`) of branch
149
* instructions or `ZYAN_FALSE` to hide it.
150
*
151
* Note that the `far`/`l` modifier is always printed.
152
*/
153
ZYDIS_FORMATTER_PROP_PRINT_BRANCH_SIZE,
154
155
/**
156
* Controls the printing of instruction prefixes.
157
*
158
* Pass `ZYAN_TRUE` as value to print all instruction-prefixes (even ignored or duplicate
159
* ones) or `ZYAN_FALSE` to only print prefixes that are effectively used by the instruction.
160
*/
161
ZYDIS_FORMATTER_PROP_DETAILED_PREFIXES,
162
163
/* ---------------------------------------------------------------------------------------- */
164
/* Numeric values */
165
/* ---------------------------------------------------------------------------------------- */
166
167
/**
168
* Controls the base of address values.
169
*/
170
ZYDIS_FORMATTER_PROP_ADDR_BASE,
171
/**
172
* Controls the signedness of relative addresses. Absolute addresses are
173
* always unsigned.
174
*/
175
ZYDIS_FORMATTER_PROP_ADDR_SIGNEDNESS,
176
/**
177
* Controls the padding of absolute address values.
178
*
179
* Pass `ZYDIS_PADDING_DISABLED` to disable padding, `ZYDIS_PADDING_AUTO` to padd all
180
* addresses to the current stack width (hexadecimal only), or any other integer value for
181
* custom padding.
182
*/
183
ZYDIS_FORMATTER_PROP_ADDR_PADDING_ABSOLUTE,
184
/**
185
* Controls the padding of relative address values.
186
*
187
* Pass `ZYDIS_PADDING_DISABLED` to disable padding, `ZYDIS_PADDING_AUTO` to padd all
188
* addresses to the current stack width (hexadecimal only), or any other integer value for
189
* custom padding.
190
*/
191
ZYDIS_FORMATTER_PROP_ADDR_PADDING_RELATIVE,
192
193
/* ---------------------------------------------------------------------------------------- */
194
195
/**
196
* Controls the base of displacement values.
197
*/
198
ZYDIS_FORMATTER_PROP_DISP_BASE,
199
/**
200
* Controls the signedness of displacement values.
201
*/
202
ZYDIS_FORMATTER_PROP_DISP_SIGNEDNESS,
203
/**
204
* Controls the padding of displacement values.
205
*
206
* Pass `ZYDIS_PADDING_DISABLED` to disable padding, or any other integer value for custom
207
* padding.
208
*/
209
ZYDIS_FORMATTER_PROP_DISP_PADDING,
210
211
/* ---------------------------------------------------------------------------------------- */
212
213
/**
214
* Controls the base of immediate values.
215
*/
216
ZYDIS_FORMATTER_PROP_IMM_BASE,
217
/**
218
* Controls the signedness of immediate values.
219
*
220
* Pass `ZYDIS_SIGNEDNESS_AUTO` to automatically choose the most suitable mode based on the
221
* operands `ZydisDecodedOperand.imm.is_signed` attribute.
222
*/
223
ZYDIS_FORMATTER_PROP_IMM_SIGNEDNESS,
224
/**
225
* Controls the padding of immediate values.
226
*
227
* Pass `ZYDIS_PADDING_DISABLED` to disable padding, `ZYDIS_PADDING_AUTO` to padd all
228
* immediates to the operand-width (hexadecimal only), or any other integer value for custom
229
* padding.
230
*/
231
ZYDIS_FORMATTER_PROP_IMM_PADDING,
232
233
/* ---------------------------------------------------------------------------------------- */
234
/* Text formatting */
235
/* ---------------------------------------------------------------------------------------- */
236
237
/**
238
* Controls the letter-case for prefixes.
239
*
240
* Pass `ZYAN_TRUE` as value to format in uppercase or `ZYAN_FALSE` to format in lowercase.
241
*/
242
ZYDIS_FORMATTER_PROP_UPPERCASE_PREFIXES,
243
/**
244
* Controls the letter-case for the mnemonic.
245
*
246
* Pass `ZYAN_TRUE` as value to format in uppercase or `ZYAN_FALSE` to format in lowercase.
247
*/
248
ZYDIS_FORMATTER_PROP_UPPERCASE_MNEMONIC,
249
/**
250
* Controls the letter-case for registers.
251
*
252
* Pass `ZYAN_TRUE` as value to format in uppercase or `ZYAN_FALSE` to format in lowercase.
253
*/
254
ZYDIS_FORMATTER_PROP_UPPERCASE_REGISTERS,
255
/**
256
* Controls the letter-case for typecasts.
257
*
258
* Pass `ZYAN_TRUE` as value to format in uppercase or `ZYAN_FALSE` to format in lowercase.
259
*/
260
ZYDIS_FORMATTER_PROP_UPPERCASE_TYPECASTS,
261
/**
262
* Controls the letter-case for decorators.
263
*
264
* Pass `ZYAN_TRUE` as value to format in uppercase or `ZYAN_FALSE` to format in lowercase.
265
*/
266
ZYDIS_FORMATTER_PROP_UPPERCASE_DECORATORS,
267
268
/* ---------------------------------------------------------------------------------------- */
269
/* Number formatting */
270
/* ---------------------------------------------------------------------------------------- */
271
272
/**
273
* Controls the prefix for decimal values.
274
*
275
* Pass a pointer to a null-terminated C-style string with a maximum length of 10 characters
276
* to set a custom prefix, or `ZYAN_NULL` to disable it.
277
*
278
* The string is deep-copied into an internal buffer.
279
*/
280
ZYDIS_FORMATTER_PROP_DEC_PREFIX,
281
/**
282
* Controls the suffix for decimal values.
283
*
284
* Pass a pointer to a null-terminated C-style string with a maximum length of 10 characters
285
* to set a custom suffix, or `ZYAN_NULL` to disable it.
286
*
287
* The string is deep-copied into an internal buffer.
288
*/
289
ZYDIS_FORMATTER_PROP_DEC_SUFFIX,
290
291
/* ---------------------------------------------------------------------------------------- */
292
293
/**
294
* Controls the letter-case of hexadecimal values.
295
*
296
* Pass `ZYAN_TRUE` as value to format in uppercase and `ZYAN_FALSE` to format in lowercase.
297
*
298
* The default value is `ZYAN_TRUE`.
299
*/
300
ZYDIS_FORMATTER_PROP_HEX_UPPERCASE,
301
/**
302
* Controls whether to prepend hexadecimal values with a leading zero if the first character
303
* is non-numeric.
304
*
305
* Pass `ZYAN_TRUE` to prepend a leading zero if the first character is non-numeric or
306
* `ZYAN_FALSE` to disable this functionality.
307
*
308
* The default value is `ZYAN_FALSE`.
309
*/
310
ZYDIS_FORMATTER_PROP_HEX_FORCE_LEADING_NUMBER,
311
/**
312
* Controls the prefix for hexadecimal values.
313
*
314
* Pass a pointer to a null-terminated C-style string with a maximum length of 10 characters
315
* to set a custom prefix, or `ZYAN_NULL` to disable it.
316
*
317
* The string is deep-copied into an internal buffer.
318
*/
319
ZYDIS_FORMATTER_PROP_HEX_PREFIX,
320
/**
321
* Controls the suffix for hexadecimal values.
322
*
323
* Pass a pointer to a null-terminated C-style string with a maximum length of 10 characters
324
* to set a custom suffix, or `ZYAN_NULL` to disable it.
325
*
326
* The string is deep-copied into an internal buffer.
327
*/
328
ZYDIS_FORMATTER_PROP_HEX_SUFFIX,
329
330
/* ---------------------------------------------------------------------------------------- */
331
332
/**
333
* Maximum value of this enum.
334
*/
335
ZYDIS_FORMATTER_PROP_MAX_VALUE = ZYDIS_FORMATTER_PROP_HEX_SUFFIX,
336
/**
337
* The minimum number of bits required to represent all values of this enum.
338
*/
339
ZYDIS_FORMATTER_PROP_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_FORMATTER_PROP_MAX_VALUE)
340
} ZydisFormatterProperty;
341
342
/* ---------------------------------------------------------------------------------------------- */
343
344
/**
345
* Enum defining different mantissae to be used during formatting.
346
*/
347
typedef enum ZydisNumericBase_
348
{
349
/**
350
* Decimal system.
351
*/
352
ZYDIS_NUMERIC_BASE_DEC,
353
/**
354
* Hexadecimal system.
355
*/
356
ZYDIS_NUMERIC_BASE_HEX,
357
358
/**
359
* Maximum value of this enum.
360
*/
361
ZYDIS_NUMERIC_BASE_MAX_VALUE = ZYDIS_NUMERIC_BASE_HEX,
362
/**
363
* The minimum number of bits required to represent all values of this enum.
364
*/
365
ZYDIS_NUMERIC_BASE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_NUMERIC_BASE_MAX_VALUE)
366
} ZydisNumericBase;
367
368
/* ---------------------------------------------------------------------------------------------- */
369
370
/**
371
* Enum defining the signeness of integers to be used during formatting.
372
*/
373
typedef enum ZydisSignedness_
374
{
375
/**
376
* Automatically choose the most suitable mode based on the operands
377
* ZydisDecodedOperand.imm.is_signed` attribute.
378
*/
379
ZYDIS_SIGNEDNESS_AUTO,
380
/**
381
* Force signed values.
382
*/
383
ZYDIS_SIGNEDNESS_SIGNED,
384
/**
385
* Force unsigned values.
386
*/
387
ZYDIS_SIGNEDNESS_UNSIGNED,
388
389
/**
390
* Maximum value of this enum.
391
*/
392
ZYDIS_SIGNEDNESS_MAX_VALUE = ZYDIS_SIGNEDNESS_UNSIGNED,
393
/**
394
* The minimum number of bits required to represent all values of this enum.
395
*/
396
ZYDIS_SIGNEDNESS_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_SIGNEDNESS_MAX_VALUE)
397
} ZydisSignedness;
398
399
/* ---------------------------------------------------------------------------------------------- */
400
401
/**
402
* Enum definining magic values that receive special treatment when used as padding properties
403
* of the formatter.
404
*/
405
typedef enum ZydisPadding_
406
{
407
/**
408
* Disables padding.
409
*/
410
ZYDIS_PADDING_DISABLED = 0,
411
/**
412
* Padds the value to the current stack-width for addresses, or to the
413
* operand-width for immediate values (hexadecimal only).
414
*/
415
ZYDIS_PADDING_AUTO = (-1),
416
417
/**
418
* Maximum value of this enum.
419
*/
420
ZYDIS_PADDING_MAX_VALUE = ZYDIS_PADDING_AUTO,
421
/**
422
* The minimum number of bits required to represent all values of this enum.
423
*/
424
ZYDIS_PADDING_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_PADDING_MAX_VALUE)
425
} ZydisPadding;
426
427
/* ---------------------------------------------------------------------------------------------- */
428
/* Function types */
429
/* ---------------------------------------------------------------------------------------------- */
430
431
/**
432
* Enum selecting a formatter function to be replaced with hooks.
433
*
434
* Do NOT change the order of the values this enum or the function fields inside the
435
* `ZydisFormatter` struct.
436
*/
437
typedef enum ZydisFormatterFunction_
438
{
439
/* ---------------------------------------------------------------------------------------- */
440
/* Instruction */
441
/* ---------------------------------------------------------------------------------------- */
442
443
/**
444
* This function is invoked before the formatter formats an instruction.
445
*/
446
ZYDIS_FORMATTER_FUNC_PRE_INSTRUCTION,
447
/**
448
* This function is invoked after the formatter formatted an instruction.
449
*/
450
ZYDIS_FORMATTER_FUNC_POST_INSTRUCTION,
451
452
/* ---------------------------------------------------------------------------------------- */
453
454
/**
455
* This function refers to the main formatting function.
456
*
457
* Replacing this function allows for complete custom formatting, but indirectly disables all
458
* other hooks except for `ZYDIS_FORMATTER_FUNC_PRE_INSTRUCTION` and
459
* `ZYDIS_FORMATTER_FUNC_POST_INSTRUCTION`.
460
*/
461
ZYDIS_FORMATTER_FUNC_FORMAT_INSTRUCTION,
462
463
/* ---------------------------------------------------------------------------------------- */
464
/* Operands */
465
/* ---------------------------------------------------------------------------------------- */
466
467
/**
468
* This function is invoked before the formatter formats an operand.
469
*/
470
ZYDIS_FORMATTER_FUNC_PRE_OPERAND,
471
/**
472
* This function is invoked after the formatter formatted an operand.
473
*/
474
ZYDIS_FORMATTER_FUNC_POST_OPERAND,
475
476
/* ---------------------------------------------------------------------------------------- */
477
478
/**
479
* This function is invoked to format a register operand.
480
*/
481
ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_REG,
482
/**
483
* This function is invoked to format a memory operand.
484
*
485
* Replacing this function might indirectly disable some specific calls to the
486
* `ZYDIS_FORMATTER_FUNC_PRINT_TYPECAST`, `ZYDIS_FORMATTER_FUNC_PRINT_SEGMENT`,
487
* `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS` and `ZYDIS_FORMATTER_FUNC_PRINT_DISP` functions.
488
*/
489
ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_MEM,
490
/**
491
* This function is invoked to format a pointer operand.
492
*/
493
ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_PTR,
494
/**
495
* This function is invoked to format an immediate operand.
496
*
497
* Replacing this function might indirectly disable some specific calls to the
498
* `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS`, `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_REL` and
499
* `ZYDIS_FORMATTER_FUNC_PRINT_IMM` functions.
500
*/
501
ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_IMM,
502
503
/* ---------------------------------------------------------------------------------------- */
504
/* Elemental tokens */
505
/* ---------------------------------------------------------------------------------------- */
506
507
/**
508
* This function is invoked to print the instruction mnemonic.
509
*/
510
ZYDIS_FORMATTER_FUNC_PRINT_MNEMONIC,
511
512
/* ---------------------------------------------------------------------------------------- */
513
514
/**
515
* This function is invoked to print a register.
516
*/
517
ZYDIS_FORMATTER_FUNC_PRINT_REGISTER,
518
/**
519
* This function is invoked to print absolute addresses.
520
*
521
* Conditionally invoked, if a runtime-address different to `ZYDIS_RUNTIME_ADDRESS_NONE` was
522
* passed:
523
* - `IMM` operands with relative address (e.g. `JMP`, `CALL`, ...)
524
* - `MEM` operands with `EIP`/`RIP`-relative address (e.g. `MOV RAX, [RIP+0x12345678]`)
525
*
526
* Always invoked for:
527
* - `MEM` operands with absolute address (e.g. `MOV RAX, [0x12345678]`)
528
*/
529
ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS,
530
/**
531
* This function is invoked to print relative addresses.
532
*
533
* Conditionally invoked, if `ZYDIS_RUNTIME_ADDRESS_NONE` was passed as runtime-address:
534
* - `IMM` operands with relative address (e.g. `JMP`, `CALL`, ...)
535
*/
536
ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_REL,
537
/**
538
* This function is invoked to print a memory displacement value.
539
*
540
* If the memory displacement contains an address and a runtime-address different to
541
* `ZYDIS_RUNTIME_ADDRESS_NONE` was passed, `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS` is called
542
* instead.
543
*/
544
ZYDIS_FORMATTER_FUNC_PRINT_DISP,
545
/**
546
* This function is invoked to print an immediate value.
547
*
548
* If the immediate contains an address and a runtime-address different to
549
* `ZYDIS_RUNTIME_ADDRESS_NONE` was passed, `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS` is called
550
* instead.
551
*
552
* If the immediate contains an address and `ZYDIS_RUNTIME_ADDRESS_NONE` was passed as
553
* runtime-address, `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_REL` is called instead.
554
*/
555
ZYDIS_FORMATTER_FUNC_PRINT_IMM,
556
557
/* ---------------------------------------------------------------------------------------- */
558
/* Optional tokens */
559
/* ---------------------------------------------------------------------------------------- */
560
561
/**
562
* This function is invoked to print the size of a memory operand (`INTEL` only).
563
*/
564
ZYDIS_FORMATTER_FUNC_PRINT_TYPECAST,
565
/**
566
* This function is invoked to print the segment-register of a memory operand.
567
*/
568
ZYDIS_FORMATTER_FUNC_PRINT_SEGMENT,
569
/**
570
* This function is invoked to print the instruction prefixes.
571
*/
572
ZYDIS_FORMATTER_FUNC_PRINT_PREFIXES,
573
/**
574
* This function is invoked after formatting an operand to print a `EVEX`/`MVEX`
575
* decorator.
576
*/
577
ZYDIS_FORMATTER_FUNC_PRINT_DECORATOR,
578
579
/* ---------------------------------------------------------------------------------------- */
580
581
/**
582
* Maximum value of this enum.
583
*/
584
ZYDIS_FORMATTER_FUNC_MAX_VALUE = ZYDIS_FORMATTER_FUNC_PRINT_DECORATOR,
585
/**
586
* The minimum number of bits required to represent all values of this enum.
587
*/
588
ZYDIS_FORMATTER_FUNC_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_FORMATTER_FUNC_MAX_VALUE)
589
} ZydisFormatterFunction;
590
591
/* ---------------------------------------------------------------------------------------------- */
592
/* Decorator types */
593
/* ---------------------------------------------------------------------------------------------- */
594
595
/**
596
* Enum of all decorator types.
597
*/
598
typedef enum ZydisDecorator_
599
{
600
ZYDIS_DECORATOR_INVALID,
601
/**
602
* The embedded-mask decorator.
603
*/
604
ZYDIS_DECORATOR_MASK,
605
/**
606
* The broadcast decorator.
607
*/
608
ZYDIS_DECORATOR_BC,
609
/**
610
* The rounding-control decorator.
611
*/
612
ZYDIS_DECORATOR_RC,
613
/**
614
* The suppress-all-exceptions decorator.
615
*/
616
ZYDIS_DECORATOR_SAE,
617
/**
618
* The register-swizzle decorator.
619
*/
620
ZYDIS_DECORATOR_SWIZZLE,
621
/**
622
* The conversion decorator.
623
*/
624
ZYDIS_DECORATOR_CONVERSION,
625
/**
626
* The eviction-hint decorator.
627
*/
628
ZYDIS_DECORATOR_EH,
629
630
/**
631
* Maximum value of this enum.
632
*/
633
ZYDIS_DECORATOR_MAX_VALUE = ZYDIS_DECORATOR_EH,
634
/**
635
* The minimum number of bits required to represent all values of this enum.
636
*/
637
ZYDIS_DECORATOR_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_DECORATOR_MAX_VALUE)
638
} ZydisDecorator;
639
640
/* ---------------------------------------------------------------------------------------------- */
641
/* Formatter context */
642
/* ---------------------------------------------------------------------------------------------- */
643
644
typedef struct ZydisFormatter_ ZydisFormatter;
645
646
/**
647
* Context structure that that is passed to all formatter.
648
*/
649
typedef struct ZydisFormatterContext_
650
{
651
/**
652
* A pointer to the `ZydisDecodedInstruction` struct.
653
*/
654
const ZydisDecodedInstruction* instruction;
655
/**
656
* A pointer to the first `ZydisDecodedOperand` struct of the instruction.
657
*/
658
const ZydisDecodedOperand* operands;
659
/**
660
* A pointer to the `ZydisDecodedOperand` struct.
661
*/
662
const ZydisDecodedOperand* operand;
663
/**
664
* The runtime address of the instruction.
665
*/
666
ZyanU64 runtime_address;
667
/**
668
* A pointer to user-defined data.
669
*
670
* This is the value that was previously passed as the `user_data` argument to
671
* @ref ZydisFormatterFormatInstruction or @ref ZydisFormatterTokenizeOperand.
672
*/
673
void* user_data;
674
} ZydisFormatterContext;
675
676
/* ---------------------------------------------------------------------------------------------- */
677
/* Function prototypes */
678
/* ---------------------------------------------------------------------------------------------- */
679
680
/**
681
* Defines the `ZydisFormatterFunc` function prototype.
682
*
683
* @param formatter A pointer to the `ZydisFormatter` instance.
684
* @param buffer A pointer to the `ZydisFormatterBuffer` struct.
685
* @param context A pointer to the `ZydisFormatterContext` struct.
686
*
687
* @return A zyan status code.
688
*
689
* Returning a status code other than `ZYAN_STATUS_SUCCESS` will immediately cause the formatting
690
* process to fail (see exceptions below).
691
*
692
* Returning `ZYDIS_STATUS_SKIP_TOKEN` is valid for functions of the following types and will
693
* instruct the formatter to omit the whole operand:
694
* - `ZYDIS_FORMATTER_FUNC_PRE_OPERAND`
695
* - `ZYDIS_FORMATTER_FUNC_POST_OPERAND`
696
* - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_REG`
697
* - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_MEM`
698
* - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_PTR`
699
* - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_IMM`
700
*
701
* This function prototype is used by functions of the following types:
702
* - `ZYDIS_FORMATTER_FUNC_PRE_INSTRUCTION`
703
* - `ZYDIS_FORMATTER_FUNC_POST_INSTRUCTION`
704
* - `ZYDIS_FORMATTER_FUNC_PRE_OPERAND`
705
* - `ZYDIS_FORMATTER_FUNC_POST_OPERAND`
706
* - `ZYDIS_FORMATTER_FUNC_FORMAT_INSTRUCTION`
707
* - `ZYDIS_FORMATTER_FUNC_PRINT_MNEMONIC`
708
* - `ZYDIS_FORMATTER_FUNC_PRINT_PREFIXES`
709
* - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_REG`
710
* - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_MEM`
711
* - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_PTR`
712
* - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_IMM`
713
* - `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS`
714
* - `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_REL`
715
* - `ZYDIS_FORMATTER_FUNC_PRINT_DISP`
716
* - `ZYDIS_FORMATTER_FUNC_PRINT_IMM`
717
* - `ZYDIS_FORMATTER_FUNC_PRINT_TYPECAST`
718
* - `ZYDIS_FORMATTER_FUNC_PRINT_SEGMENT`
719
*/
720
typedef ZyanStatus (*ZydisFormatterFunc)(const ZydisFormatter* formatter,
721
ZydisFormatterBuffer* buffer, ZydisFormatterContext* context);
722
723
/**
724
* Defines the `ZydisFormatterRegisterFunc` function prototype.
725
*
726
* @param formatter A pointer to the `ZydisFormatter` instance.
727
* @param buffer A pointer to the `ZydisFormatterBuffer` struct.
728
* @param context A pointer to the `ZydisFormatterContext` struct.
729
* @param reg The register.
730
*
731
* @return Returning a status code other than `ZYAN_STATUS_SUCCESS` will immediately cause the
732
* formatting process to fail.
733
*
734
* This function prototype is used by functions of the following types:
735
* - `ZYDIS_FORMATTER_FUNC_PRINT_REGISTER`.
736
*/
737
typedef ZyanStatus (*ZydisFormatterRegisterFunc)(const ZydisFormatter* formatter,
738
ZydisFormatterBuffer* buffer, ZydisFormatterContext* context, ZydisRegister reg);
739
740
/**
741
* Defines the `ZydisFormatterDecoratorFunc` function prototype.
742
*
743
* @param formatter A pointer to the `ZydisFormatter` instance.
744
* @param buffer A pointer to the `ZydisFormatterBuffer` struct.
745
* @param context A pointer to the `ZydisFormatterContext` struct.
746
* @param decorator The decorator type.
747
*
748
* @return Returning a status code other than `ZYAN_STATUS_SUCCESS` will immediately cause the
749
* formatting process to fail.
750
*
751
* This function type is used for:
752
* - `ZYDIS_FORMATTER_FUNC_PRINT_DECORATOR`
753
*/
754
typedef ZyanStatus (*ZydisFormatterDecoratorFunc)(const ZydisFormatter* formatter,
755
ZydisFormatterBuffer* buffer, ZydisFormatterContext* context, ZydisDecorator decorator);
756
757
/* ---------------------------------------------------------------------------------------------- */
758
/* Formatter struct */
759
/* ---------------------------------------------------------------------------------------------- */
760
761
/**
762
* Context structure keeping track of internal state of the formatter.
763
*
764
* All fields in this struct should be considered as "private". Any changes may lead to unexpected
765
* behavior.
766
*
767
* Do NOT change the order of the function fields or the values of the `ZydisFormatterFunction`
768
* enum.
769
*/
770
struct ZydisFormatter_
771
{
772
/**
773
* The formatter style.
774
*/
775
ZydisFormatterStyle style;
776
/**
777
* The `ZYDIS_FORMATTER_PROP_FORCE_SIZE` property.
778
*/
779
ZyanBool force_memory_size;
780
/**
781
* The `ZYDIS_FORMATTER_PROP_FORCE_SEGMENT` property.
782
*/
783
ZyanBool force_memory_segment;
784
/**
785
* The `ZYDIS_FORMATTER_PROP_FORCE_SCALE_ONE` property.
786
*/
787
ZyanBool force_memory_scale;
788
/**
789
* The `ZYDIS_FORMATTER_PROP_FORCE_RELATIVE_BRANCHES` property.
790
*/
791
ZyanBool force_relative_branches;
792
/**
793
* The `ZYDIS_FORMATTER_PROP_FORCE_RELATIVE_RIPREL` property.
794
*/
795
ZyanBool force_relative_riprel;
796
/**
797
* The `ZYDIS_FORMATTER_PROP_PRINT_BRANCH_SIZE` property.
798
*/
799
ZyanBool print_branch_size;
800
/**
801
* The `ZYDIS_FORMATTER_DETAILED_PREFIXES` property.
802
*/
803
ZyanBool detailed_prefixes;
804
/**
805
* The `ZYDIS_FORMATTER_ADDR_BASE` property.
806
*/
807
ZydisNumericBase addr_base;
808
/**
809
* The `ZYDIS_FORMATTER_ADDR_SIGNEDNESS` property.
810
*/
811
ZydisSignedness addr_signedness;
812
/**
813
* The `ZYDIS_FORMATTER_ADDR_PADDING_ABSOLUTE` property.
814
*/
815
ZydisPadding addr_padding_absolute;
816
/**
817
* The `ZYDIS_FORMATTER_ADDR_PADDING_RELATIVE` property.
818
*/
819
ZydisPadding addr_padding_relative;
820
/**
821
* The `ZYDIS_FORMATTER_DISP_BASE` property.
822
*/
823
ZydisNumericBase disp_base;
824
/**
825
* The `ZYDIS_FORMATTER_DISP_SIGNEDNESS` property.
826
*/
827
ZydisSignedness disp_signedness;
828
/**
829
* The `ZYDIS_FORMATTER_DISP_PADDING` property.
830
*/
831
ZydisPadding disp_padding;
832
/**
833
* The `ZYDIS_FORMATTER_IMM_BASE` property.
834
*/
835
ZydisNumericBase imm_base;
836
/**
837
* The `ZYDIS_FORMATTER_IMM_SIGNEDNESS` property.
838
*/
839
ZydisSignedness imm_signedness;
840
/**
841
* The `ZYDIS_FORMATTER_IMM_PADDING` property.
842
*/
843
ZydisPadding imm_padding;
844
/**
845
* The `ZYDIS_FORMATTER_UPPERCASE_PREFIXES` property.
846
*/
847
ZyanI32 case_prefixes;
848
/**
849
* The `ZYDIS_FORMATTER_UPPERCASE_MNEMONIC` property.
850
*/
851
ZyanI32 case_mnemonic;
852
/**
853
* The `ZYDIS_FORMATTER_UPPERCASE_REGISTERS` property.
854
*/
855
ZyanI32 case_registers;
856
/**
857
* The `ZYDIS_FORMATTER_UPPERCASE_TYPECASTS` property.
858
*/
859
ZyanI32 case_typecasts;
860
/**
861
* The `ZYDIS_FORMATTER_UPPERCASE_DECORATORS` property.
862
*/
863
ZyanI32 case_decorators;
864
/**
865
* The `ZYDIS_FORMATTER_HEX_UPPERCASE` property.
866
*/
867
ZyanBool hex_uppercase;
868
/**
869
* The `ZYDIS_FORMATTER_HEX_FORCE_LEADING_NUMBER` property.
870
*/
871
ZyanBool hex_force_leading_number;
872
/**
873
* The number formats for all numeric bases.
874
*
875
* Index 0 = prefix
876
* Index 1 = suffix
877
*/
878
struct
879
{
880
/**
881
* A pointer to the `ZyanStringView` to use as prefix/suffix.
882
*/
883
const ZyanStringView* string;
884
/**
885
* The `ZyanStringView` to use as prefix/suffix
886
*/
887
ZyanStringView string_data;
888
/**
889
* The actual string data.
890
*/
891
char buffer[11];
892
} number_format[ZYDIS_NUMERIC_BASE_MAX_VALUE + 1][2];
893
/**
894
* The `ZYDIS_FORMATTER_FUNC_PRE_INSTRUCTION` function.
895
*/
896
ZydisFormatterFunc func_pre_instruction;
897
/**
898
* The `ZYDIS_FORMATTER_FUNC_POST_INSTRUCTION` function.
899
*/
900
ZydisFormatterFunc func_post_instruction;
901
/**
902
* The `ZYDIS_FORMATTER_FUNC_FORMAT_INSTRUCTION` function.
903
*/
904
ZydisFormatterFunc func_format_instruction;
905
/**
906
* The `ZYDIS_FORMATTER_FUNC_PRE_OPERAND` function.
907
*/
908
ZydisFormatterFunc func_pre_operand;
909
/**
910
* The `ZYDIS_FORMATTER_FUNC_POST_OPERAND` function.
911
*/
912
ZydisFormatterFunc func_post_operand;
913
/**
914
* The `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_REG` function.
915
*/
916
ZydisFormatterFunc func_format_operand_reg;
917
/**
918
* The `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_MEM` function.
919
*/
920
ZydisFormatterFunc func_format_operand_mem;
921
/**
922
* The `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_PTR` function.
923
*/
924
ZydisFormatterFunc func_format_operand_ptr;
925
/**
926
* The `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_IMM` function.
927
*/
928
ZydisFormatterFunc func_format_operand_imm;
929
/**
930
* The `ZYDIS_FORMATTER_FUNC_PRINT_MNEMONIC function.
931
*/
932
ZydisFormatterFunc func_print_mnemonic;
933
/**
934
* The `ZYDIS_FORMATTER_FUNC_PRINT_REGISTER` function.
935
*/
936
ZydisFormatterRegisterFunc func_print_register;
937
/**
938
* The `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS` function.
939
*/
940
ZydisFormatterFunc func_print_address_abs;
941
/**
942
* The `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_REL` function.
943
*/
944
ZydisFormatterFunc func_print_address_rel;
945
/**
946
* The `ZYDIS_FORMATTER_FUNC_PRINT_DISP` function.
947
*/
948
ZydisFormatterFunc func_print_disp;
949
/**
950
* The `ZYDIS_FORMATTER_FUNC_PRINT_IMM` function.
951
*/
952
ZydisFormatterFunc func_print_imm;
953
/**
954
* The `ZYDIS_FORMATTER_FUNC_PRINT_TYPECAST` function.
955
*/
956
ZydisFormatterFunc func_print_typecast;
957
/**
958
* The `ZYDIS_FORMATTER_FUNC_PRINT_SEGMENT` function.
959
*/
960
ZydisFormatterFunc func_print_segment;
961
/**
962
* The `ZYDIS_FORMATTER_FUNC_PRINT_PREFIXES` function.
963
*/
964
ZydisFormatterFunc func_print_prefixes;
965
/**
966
* The `ZYDIS_FORMATTER_FUNC_PRINT_DECORATOR` function.
967
*/
968
ZydisFormatterDecoratorFunc func_print_decorator;
969
};
970
971
/* ---------------------------------------------------------------------------------------------- */
972
973
/* ============================================================================================== */
974
/* Exported functions */
975
/* ============================================================================================== */
976
977
/**
978
* @addtogroup formatter Formatter
979
* Functions allowing formatting of previously decoded instructions to human readable text.
980
* @{
981
*/
982
983
/* ---------------------------------------------------------------------------------------------- */
984
/* Initialization */
985
/* ---------------------------------------------------------------------------------------------- */
986
987
/**
988
* Initializes the given `ZydisFormatter` instance.
989
*
990
* @param formatter A pointer to the `ZydisFormatter` instance.
991
* @param style The base formatter style (either `AT&T` or `Intel` style).
992
*
993
* @return A zyan status code.
994
*/
995
ZYDIS_EXPORT ZyanStatus ZydisFormatterInit(ZydisFormatter* formatter, ZydisFormatterStyle style);
996
997
/* ---------------------------------------------------------------------------------------------- */
998
/* Setter */
999
/* ---------------------------------------------------------------------------------------------- */
1000
1001
/**
1002
* Changes the value of the specified formatter `property`.
1003
*
1004
* @param formatter A pointer to the `ZydisFormatter` instance.
1005
* @param property The id of the formatter-property.
1006
* @param value The new value.
1007
*
1008
* @return A zyan status code.
1009
*
1010
* This function returns `ZYAN_STATUS_INVALID_OPERATION` if a property can't be changed for the
1011
* current formatter-style.
1012
*/
1013
ZYDIS_EXPORT ZyanStatus ZydisFormatterSetProperty(ZydisFormatter* formatter,
1014
ZydisFormatterProperty property, ZyanUPointer value);
1015
1016
/**
1017
* Replaces a formatter function with a custom callback and/or retrieves the currently
1018
* used function.
1019
*
1020
* @param formatter A pointer to the `ZydisFormatter` instance.
1021
* @param type The formatter function-type.
1022
* @param callback A pointer to a variable that contains the pointer of the callback function
1023
* and receives the pointer of the currently used function.
1024
*
1025
* @return A zyan status code.
1026
*
1027
* Call this function with `callback` pointing to a `ZYAN_NULL` value to retrieve the currently
1028
* used function without replacing it.
1029
*
1030
* This function returns `ZYAN_STATUS_INVALID_OPERATION` if a function can't be replaced for the
1031
* current formatter-style.
1032
*/
1033
ZYDIS_EXPORT ZyanStatus ZydisFormatterSetHook(ZydisFormatter* formatter,
1034
ZydisFormatterFunction type, const void** callback);
1035
1036
/* ---------------------------------------------------------------------------------------------- */
1037
/* Formatting */
1038
/* ---------------------------------------------------------------------------------------------- */
1039
1040
/**
1041
* Formats the given instruction and writes it into the output buffer.
1042
*
1043
* @param formatter A pointer to the `ZydisFormatter` instance.
1044
* @param instruction A pointer to the `ZydisDecodedInstruction` struct.
1045
* @param operands A pointer to the decoded operands array.
1046
* @param operand_count The length of the `operands` array. Must be equal to or greater than
1047
* the value of `instruction->operand_count_visible`.
1048
* @param buffer A pointer to the output buffer.
1049
* @param length The length of the output buffer (in characters).
1050
* @param runtime_address The runtime address of the instruction or `ZYDIS_RUNTIME_ADDRESS_NONE`
1051
* to print relative addresses.
1052
* @param user_data A pointer to user-defined data which can be used in custom formatter
1053
* callbacks. Can be `ZYAN_NULL`.
1054
*
1055
* @return A zyan status code.
1056
*/
1057
ZYDIS_EXPORT ZyanStatus ZydisFormatterFormatInstruction(const ZydisFormatter* formatter,
1058
const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operands,
1059
ZyanU8 operand_count, char* buffer, ZyanUSize length, ZyanU64 runtime_address,
1060
void* user_data);
1061
1062
/**
1063
* Formats the given operand and writes it into the output buffer.
1064
*
1065
* @param formatter A pointer to the `ZydisFormatter` instance.
1066
* @param instruction A pointer to the `ZydisDecodedInstruction` struct.
1067
* @param operand A pointer to the `ZydisDecodedOperand` struct of the operand to format.
1068
* @param buffer A pointer to the output buffer.
1069
* @param length The length of the output buffer (in characters).
1070
* @param runtime_address The runtime address of the instruction or `ZYDIS_RUNTIME_ADDRESS_NONE`
1071
* to print relative addresses.
1072
* @param user_data A pointer to user-defined data which can be used in custom formatter
1073
* callbacks. Can be `ZYAN_NULL`.
1074
*
1075
* @return A zyan status code.
1076
*
1077
* Use `ZydisFormatterFormatInstruction` or `ZydisFormatterFormatInstructionEx` to format a
1078
* complete instruction.
1079
*/
1080
ZYDIS_EXPORT ZyanStatus ZydisFormatterFormatOperand(const ZydisFormatter* formatter,
1081
const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand,
1082
char* buffer, ZyanUSize length, ZyanU64 runtime_address, void* user_data);
1083
1084
/* ---------------------------------------------------------------------------------------------- */
1085
/* Tokenizing */
1086
/* ---------------------------------------------------------------------------------------------- */
1087
1088
/**
1089
* Tokenizes the given instruction and writes it into the output buffer.
1090
*
1091
* @param formatter A pointer to the `ZydisFormatter` instance.
1092
* @param instruction A pointer to the `ZydisDecodedInstruction` struct.
1093
* @param operands A pointer to the decoded operands array.
1094
* @param operand_count The length of the `operands` array. Must be equal to or greater than
1095
* the value of `instruction->operand_count_visible`.
1096
* @param buffer A pointer to the output buffer.
1097
* @param length The length of the output buffer (in bytes).
1098
* @param runtime_address The runtime address of the instruction or `ZYDIS_RUNTIME_ADDRESS_NONE`
1099
* to print relative addresses.
1100
* @param token Receives a pointer to the first token in the output buffer.
1101
* @param user_data A pointer to user-defined data which can be used in custom formatter
1102
* callbacks. Can be `ZYAN_NULL`.
1103
*
1104
* @return A zyan status code.
1105
*/
1106
ZYDIS_EXPORT ZyanStatus ZydisFormatterTokenizeInstruction(const ZydisFormatter* formatter,
1107
const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operands,
1108
ZyanU8 operand_count, void* buffer, ZyanUSize length, ZyanU64 runtime_address,
1109
ZydisFormatterTokenConst** token, void* user_data);
1110
1111
/**
1112
* Tokenizes the given operand and writes it into the output buffer.
1113
*
1114
* @param formatter A pointer to the `ZydisFormatter` instance.
1115
* @param instruction A pointer to the `ZydisDecodedInstruction` struct.
1116
* @param operand A pointer to the `ZydisDecodedOperand` struct of the operand to format.
1117
* @param buffer A pointer to the output buffer.
1118
* @param length The length of the output buffer (in bytes).
1119
* @param runtime_address The runtime address of the instruction or `ZYDIS_RUNTIME_ADDRESS_NONE`
1120
* to print relative addresses.
1121
* @param token Receives a pointer to the first token in the output buffer.
1122
* @param user_data A pointer to user-defined data which can be used in custom formatter
1123
* callbacks. Can be `ZYAN_NULL`.
1124
*
1125
* @return A zyan status code.
1126
*
1127
* Use `ZydisFormatterTokenizeInstruction` to tokenize a complete instruction.
1128
*/
1129
ZYDIS_EXPORT ZyanStatus ZydisFormatterTokenizeOperand(const ZydisFormatter* formatter,
1130
const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand,
1131
void* buffer, ZyanUSize length, ZyanU64 runtime_address, ZydisFormatterTokenConst** token,
1132
void* user_data);
1133
1134
/* ---------------------------------------------------------------------------------------------- */
1135
1136
/**
1137
* @}
1138
*/
1139
1140
/* ============================================================================================== */
1141
1142
#ifdef __cplusplus
1143
}
1144
#endif
1145
1146
#endif /* ZYDIS_FORMATTER_H */
1147
1148