xref: /haiku/headers/libs/zydis/Zydis/Formatter.h (revision caed67a8cba83913b9c21ac2b06ebc6bd1cb3111)
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 pad all
180      * addresses to the current address 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 pad all
188      * addresses to the current address 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      * WARNING: this is currently not implemented (ignored).
267      */
268     ZYDIS_FORMATTER_PROP_UPPERCASE_DECORATORS,
269 
270     /* ---------------------------------------------------------------------------------------- */
271     /* Number formatting                                                                        */
272     /* ---------------------------------------------------------------------------------------- */
273 
274     /**
275      * Controls the prefix for decimal values.
276      *
277      * Pass a pointer to a null-terminated C-style string with a maximum length of 10 characters
278      * to set a custom prefix, or `ZYAN_NULL` to disable it.
279      *
280      * The string is deep-copied into an internal buffer.
281      */
282     ZYDIS_FORMATTER_PROP_DEC_PREFIX,
283     /**
284      * Controls the suffix for decimal values.
285      *
286      * Pass a pointer to a null-terminated C-style string with a maximum length of 10 characters
287      * to set a custom suffix, or `ZYAN_NULL` to disable it.
288      *
289      * The string is deep-copied into an internal buffer.
290      */
291     ZYDIS_FORMATTER_PROP_DEC_SUFFIX,
292 
293     /* ---------------------------------------------------------------------------------------- */
294 
295     /**
296      * Controls the letter-case of hexadecimal values.
297      *
298      * Pass `ZYAN_TRUE` as value to format in uppercase and `ZYAN_FALSE` to format in lowercase.
299      *
300      * The default value is `ZYAN_TRUE`.
301      */
302     ZYDIS_FORMATTER_PROP_HEX_UPPERCASE,
303     /**
304      * Controls whether to prepend hexadecimal values with a leading zero if the first character
305      * is non-numeric.
306      *
307      * Pass `ZYAN_TRUE` to prepend a leading zero if the first character is non-numeric or
308      * `ZYAN_FALSE` to disable this functionality.
309      *
310      * The default value is `ZYAN_FALSE`.
311      */
312     ZYDIS_FORMATTER_PROP_HEX_FORCE_LEADING_NUMBER,
313     /**
314      * Controls the prefix for hexadecimal values.
315      *
316      * Pass a pointer to a null-terminated C-style string with a maximum length of 10 characters
317      * to set a custom prefix, or `ZYAN_NULL` to disable it.
318      *
319      * The string is deep-copied into an internal buffer.
320      */
321     ZYDIS_FORMATTER_PROP_HEX_PREFIX,
322     /**
323      * Controls the suffix for hexadecimal values.
324      *
325      * Pass a pointer to a null-terminated C-style string with a maximum length of 10 characters
326      * to set a custom suffix, or `ZYAN_NULL` to disable it.
327      *
328      * The string is deep-copied into an internal buffer.
329      */
330     ZYDIS_FORMATTER_PROP_HEX_SUFFIX,
331 
332     /* ---------------------------------------------------------------------------------------- */
333 
334     /**
335      * Maximum value of this enum.
336      */
337     ZYDIS_FORMATTER_PROP_MAX_VALUE = ZYDIS_FORMATTER_PROP_HEX_SUFFIX,
338     /**
339      * The minimum number of bits required to represent all values of this enum.
340      */
341     ZYDIS_FORMATTER_PROP_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_FORMATTER_PROP_MAX_VALUE)
342 } ZydisFormatterProperty;
343 
344 /* ---------------------------------------------------------------------------------------------- */
345 
346 /**
347  * Enum defining different mantissae to be used during formatting.
348  */
349 typedef enum ZydisNumericBase_
350 {
351     /**
352      * Decimal system.
353      */
354     ZYDIS_NUMERIC_BASE_DEC,
355     /**
356      * Hexadecimal system.
357      */
358     ZYDIS_NUMERIC_BASE_HEX,
359 
360     /**
361      * Maximum value of this enum.
362      */
363     ZYDIS_NUMERIC_BASE_MAX_VALUE = ZYDIS_NUMERIC_BASE_HEX,
364     /**
365      * The minimum number of bits required to represent all values of this enum.
366      */
367     ZYDIS_NUMERIC_BASE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_NUMERIC_BASE_MAX_VALUE)
368 } ZydisNumericBase;
369 
370 /* ---------------------------------------------------------------------------------------------- */
371 
372 /**
373  * Enum defining the signeness of integers to be used during formatting.
374  */
375 typedef enum ZydisSignedness_
376 {
377     /**
378      * Automatically choose the most suitable mode based on the operands
379      * ZydisDecodedOperand.imm.is_signed` attribute.
380      */
381     ZYDIS_SIGNEDNESS_AUTO,
382     /**
383      * Force signed values.
384      */
385     ZYDIS_SIGNEDNESS_SIGNED,
386     /**
387      * Force unsigned values.
388      */
389     ZYDIS_SIGNEDNESS_UNSIGNED,
390 
391     /**
392      * Maximum value of this enum.
393      */
394     ZYDIS_SIGNEDNESS_MAX_VALUE = ZYDIS_SIGNEDNESS_UNSIGNED,
395     /**
396      * The minimum number of bits required to represent all values of this enum.
397      */
398     ZYDIS_SIGNEDNESS_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_SIGNEDNESS_MAX_VALUE)
399 } ZydisSignedness;
400 
401 /* ---------------------------------------------------------------------------------------------- */
402 
403 /**
404  * Enum definining magic values that receive special treatment when used as padding properties
405  * of the formatter.
406  */
407 typedef enum ZydisPadding_
408 {
409     /**
410      * Disables padding.
411      */
412     ZYDIS_PADDING_DISABLED = 0,
413     /**
414      * Padds the value to the current stack-width for addresses, or to the
415      * operand-width for immediate values (hexadecimal only).
416      */
417     ZYDIS_PADDING_AUTO     = (-1),
418 
419     /**
420      * Maximum value of this enum.
421      */
422     ZYDIS_PADDING_MAX_VALUE = ZYDIS_PADDING_AUTO,
423     /**
424      * The minimum number of bits required to represent all values of this enum.
425      */
426     ZYDIS_PADDING_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_PADDING_MAX_VALUE)
427 } ZydisPadding;
428 
429 /* ---------------------------------------------------------------------------------------------- */
430 /* Function types                                                                                 */
431 /* ---------------------------------------------------------------------------------------------- */
432 
433 /**
434  * Enum selecting a formatter function to be replaced with hooks.
435  *
436  * Do NOT change the order of the values this enum or the function fields inside the
437  * `ZydisFormatter` struct.
438  */
439 typedef enum ZydisFormatterFunction_
440 {
441     /* ---------------------------------------------------------------------------------------- */
442     /* Instruction                                                                              */
443     /* ---------------------------------------------------------------------------------------- */
444 
445     /**
446      * This function is invoked before the formatter formats an instruction.
447      */
448     ZYDIS_FORMATTER_FUNC_PRE_INSTRUCTION,
449     /**
450      * This function is invoked after the formatter formatted an instruction.
451      */
452     ZYDIS_FORMATTER_FUNC_POST_INSTRUCTION,
453 
454     /* ---------------------------------------------------------------------------------------- */
455 
456     /**
457      * This function refers to the main formatting function.
458      *
459      * Replacing this function allows for complete custom formatting, but indirectly disables all
460      * other hooks except for `ZYDIS_FORMATTER_FUNC_PRE_INSTRUCTION` and
461      * `ZYDIS_FORMATTER_FUNC_POST_INSTRUCTION`.
462      */
463     ZYDIS_FORMATTER_FUNC_FORMAT_INSTRUCTION,
464 
465     /* ---------------------------------------------------------------------------------------- */
466     /* Operands                                                                                 */
467     /* ---------------------------------------------------------------------------------------- */
468 
469     /**
470      * This function is invoked before the formatter formats an operand.
471      */
472     ZYDIS_FORMATTER_FUNC_PRE_OPERAND,
473     /**
474      * This function is invoked after the formatter formatted an operand.
475      */
476     ZYDIS_FORMATTER_FUNC_POST_OPERAND,
477 
478     /* ---------------------------------------------------------------------------------------- */
479 
480     /**
481      * This function is invoked to format a register operand.
482      */
483     ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_REG,
484     /**
485      * This function is invoked to format a memory operand.
486      *
487      * Replacing this function might indirectly disable some specific calls to the
488      * `ZYDIS_FORMATTER_FUNC_PRINT_TYPECAST`, `ZYDIS_FORMATTER_FUNC_PRINT_SEGMENT`,
489      * `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS` and `ZYDIS_FORMATTER_FUNC_PRINT_DISP` functions.
490      */
491     ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_MEM,
492     /**
493      * This function is invoked to format a pointer operand.
494      */
495     ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_PTR,
496     /**
497      * This function is invoked to format an immediate operand.
498      *
499      * Replacing this function might indirectly disable some specific calls to the
500      * `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS`, `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_REL` and
501      * `ZYDIS_FORMATTER_FUNC_PRINT_IMM` functions.
502      */
503     ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_IMM,
504 
505     /* ---------------------------------------------------------------------------------------- */
506     /* Elemental tokens                                                                         */
507     /* ---------------------------------------------------------------------------------------- */
508 
509     /**
510      * This function is invoked to print the instruction mnemonic.
511      */
512     ZYDIS_FORMATTER_FUNC_PRINT_MNEMONIC,
513 
514     /* ---------------------------------------------------------------------------------------- */
515 
516     /**
517      * This function is invoked to print a register.
518      */
519     ZYDIS_FORMATTER_FUNC_PRINT_REGISTER,
520     /**
521      * This function is invoked to print absolute addresses.
522      *
523      * Conditionally invoked, if a runtime-address different to `ZYDIS_RUNTIME_ADDRESS_NONE` was
524      * passed:
525      * - `IMM` operands with relative address (e.g. `JMP`, `CALL`, ...)
526      * - `MEM` operands with `EIP`/`RIP`-relative address (e.g. `MOV RAX, [RIP+0x12345678]`)
527      *
528      * Always invoked for:
529      * - `MEM` operands with absolute address (e.g. `MOV RAX, [0x12345678]`)
530      */
531     ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS,
532     /**
533      * This function is invoked to print relative addresses.
534      *
535      * Conditionally invoked, if `ZYDIS_RUNTIME_ADDRESS_NONE` was passed as runtime-address:
536      * - `IMM` operands with relative address (e.g. `JMP`, `CALL`, ...)
537      */
538     ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_REL,
539     /**
540      * This function is invoked to print a memory displacement value.
541      *
542      * If the memory displacement contains an address and a runtime-address different to
543      * `ZYDIS_RUNTIME_ADDRESS_NONE` was passed, `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS` is called
544      * instead.
545      */
546     ZYDIS_FORMATTER_FUNC_PRINT_DISP,
547     /**
548      * This function is invoked to print an immediate value.
549      *
550      * If the immediate contains an address and a runtime-address different to
551      * `ZYDIS_RUNTIME_ADDRESS_NONE` was passed, `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS` is called
552      * instead.
553      *
554      * If the immediate contains an address and `ZYDIS_RUNTIME_ADDRESS_NONE` was passed as
555      * runtime-address, `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_REL` is called instead.
556      */
557     ZYDIS_FORMATTER_FUNC_PRINT_IMM,
558 
559     /* ---------------------------------------------------------------------------------------- */
560     /* Optional tokens                                                                          */
561     /* ---------------------------------------------------------------------------------------- */
562 
563     /**
564      * This function is invoked to print the size of a memory operand (`INTEL` only).
565      */
566     ZYDIS_FORMATTER_FUNC_PRINT_TYPECAST,
567     /**
568      * This function is invoked to print the segment-register of a memory operand.
569      */
570     ZYDIS_FORMATTER_FUNC_PRINT_SEGMENT,
571     /**
572      * This function is invoked to print the instruction prefixes.
573      */
574     ZYDIS_FORMATTER_FUNC_PRINT_PREFIXES,
575     /**
576      * This function is invoked after formatting an operand to print a `EVEX`/`MVEX`
577      * decorator.
578      */
579     ZYDIS_FORMATTER_FUNC_PRINT_DECORATOR,
580 
581     /* ---------------------------------------------------------------------------------------- */
582 
583     /**
584      * Maximum value of this enum.
585      */
586     ZYDIS_FORMATTER_FUNC_MAX_VALUE = ZYDIS_FORMATTER_FUNC_PRINT_DECORATOR,
587     /**
588      * The minimum number of bits required to represent all values of this enum.
589      */
590     ZYDIS_FORMATTER_FUNC_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_FORMATTER_FUNC_MAX_VALUE)
591 } ZydisFormatterFunction;
592 
593 /* ---------------------------------------------------------------------------------------------- */
594 /* Decorator types                                                                                */
595 /* ---------------------------------------------------------------------------------------------- */
596 
597 /**
598  * Enum of all decorator types.
599  */
600 typedef enum ZydisDecorator_
601 {
602     ZYDIS_DECORATOR_INVALID,
603     /**
604      * The embedded-mask decorator.
605      */
606     ZYDIS_DECORATOR_MASK,
607     /**
608      * The broadcast decorator.
609      */
610     ZYDIS_DECORATOR_BC,
611     /**
612      * The rounding-control decorator.
613      */
614     ZYDIS_DECORATOR_RC,
615     /**
616      * The suppress-all-exceptions decorator.
617      */
618     ZYDIS_DECORATOR_SAE,
619     /**
620      * The register-swizzle decorator.
621      */
622     ZYDIS_DECORATOR_SWIZZLE,
623     /**
624      * The conversion decorator.
625      */
626     ZYDIS_DECORATOR_CONVERSION,
627     /**
628      * The eviction-hint decorator.
629      */
630     ZYDIS_DECORATOR_EH,
631 
632     /**
633      * Maximum value of this enum.
634      */
635     ZYDIS_DECORATOR_MAX_VALUE = ZYDIS_DECORATOR_EH,
636     /**
637      * The minimum number of bits required to represent all values of this enum.
638      */
639     ZYDIS_DECORATOR_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_DECORATOR_MAX_VALUE)
640 } ZydisDecorator;
641 
642 /* ---------------------------------------------------------------------------------------------- */
643 /* Formatter context                                                                              */
644 /* ---------------------------------------------------------------------------------------------- */
645 
646 typedef struct ZydisFormatter_ ZydisFormatter;
647 
648 /**
649  * Context structure that that is passed to all formatter.
650  */
651 typedef struct ZydisFormatterContext_
652 {
653     /**
654      * A pointer to the `ZydisDecodedInstruction` struct.
655      */
656     const ZydisDecodedInstruction* instruction;
657     /**
658      * A pointer to the first `ZydisDecodedOperand` struct of the instruction.
659      */
660     const ZydisDecodedOperand* operands;
661     /**
662      * A pointer to the `ZydisDecodedOperand` struct.
663      */
664     const ZydisDecodedOperand* operand;
665     /**
666      * The runtime address of the instruction.
667      */
668     ZyanU64 runtime_address;
669     /**
670      * A pointer to user-defined data.
671      *
672      * This is the value that was previously passed as the `user_data` argument to
673      * @ref ZydisFormatterFormatInstruction or @ref ZydisFormatterTokenizeOperand.
674      */
675     void* user_data;
676 } ZydisFormatterContext;
677 
678 /* ---------------------------------------------------------------------------------------------- */
679 /* Function prototypes                                                                            */
680 /* ---------------------------------------------------------------------------------------------- */
681 
682 /**
683  * Defines the `ZydisFormatterFunc` function prototype.
684  *
685  * @param   formatter   A pointer to the `ZydisFormatter` instance.
686  * @param   buffer      A pointer to the `ZydisFormatterBuffer` struct.
687  * @param   context     A pointer to the `ZydisFormatterContext` struct.
688  *
689  * @return  A zyan status code.
690  *
691  * Returning a status code other than `ZYAN_STATUS_SUCCESS` will immediately cause the formatting
692  * process to fail (see exceptions below).
693  *
694  * Returning `ZYDIS_STATUS_SKIP_TOKEN` is valid for functions of the following types and will
695  * instruct the formatter to omit the whole operand:
696  * - `ZYDIS_FORMATTER_FUNC_PRE_OPERAND`
697  * - `ZYDIS_FORMATTER_FUNC_POST_OPERAND`
698  * - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_REG`
699  * - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_MEM`
700  * - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_PTR`
701  * - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_IMM`
702  *
703  * This function prototype is used by functions of the following types:
704  * - `ZYDIS_FORMATTER_FUNC_PRE_INSTRUCTION`
705  * - `ZYDIS_FORMATTER_FUNC_POST_INSTRUCTION`
706  * - `ZYDIS_FORMATTER_FUNC_PRE_OPERAND`
707  * - `ZYDIS_FORMATTER_FUNC_POST_OPERAND`
708  * - `ZYDIS_FORMATTER_FUNC_FORMAT_INSTRUCTION`
709  * - `ZYDIS_FORMATTER_FUNC_PRINT_MNEMONIC`
710  * - `ZYDIS_FORMATTER_FUNC_PRINT_PREFIXES`
711  * - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_REG`
712  * - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_MEM`
713  * - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_PTR`
714  * - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_IMM`
715  * - `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS`
716  * - `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_REL`
717  * - `ZYDIS_FORMATTER_FUNC_PRINT_DISP`
718  * - `ZYDIS_FORMATTER_FUNC_PRINT_IMM`
719  * - `ZYDIS_FORMATTER_FUNC_PRINT_TYPECAST`
720  * - `ZYDIS_FORMATTER_FUNC_PRINT_SEGMENT`
721  */
722 typedef ZyanStatus (*ZydisFormatterFunc)(const ZydisFormatter* formatter,
723     ZydisFormatterBuffer* buffer, ZydisFormatterContext* context);
724 
725  /**
726  * Defines the `ZydisFormatterRegisterFunc` function prototype.
727  *
728  * @param   formatter   A pointer to the `ZydisFormatter` instance.
729  * @param   buffer      A pointer to the `ZydisFormatterBuffer` struct.
730  * @param   context     A pointer to the `ZydisFormatterContext` struct.
731  * @param   reg         The register.
732  *
733  * @return  Returning a status code other than `ZYAN_STATUS_SUCCESS` will immediately cause the
734  *          formatting process to fail.
735  *
736  * This function prototype is used by functions of the following types:
737  * - `ZYDIS_FORMATTER_FUNC_PRINT_REGISTER`.
738  */
739 typedef ZyanStatus (*ZydisFormatterRegisterFunc)(const ZydisFormatter* formatter,
740     ZydisFormatterBuffer* buffer, ZydisFormatterContext* context, ZydisRegister reg);
741 
742 /**
743  * Defines the `ZydisFormatterDecoratorFunc` function prototype.
744  *
745  * @param   formatter   A pointer to the `ZydisFormatter` instance.
746  * @param   buffer      A pointer to the `ZydisFormatterBuffer` struct.
747  * @param   context     A pointer to the `ZydisFormatterContext` struct.
748  * @param   decorator   The decorator type.
749  *
750  * @return  Returning a status code other than `ZYAN_STATUS_SUCCESS` will immediately cause the
751  *          formatting process to fail.
752  *
753  * This function type is used for:
754  * - `ZYDIS_FORMATTER_FUNC_PRINT_DECORATOR`
755  */
756 typedef ZyanStatus (*ZydisFormatterDecoratorFunc)(const ZydisFormatter* formatter,
757     ZydisFormatterBuffer* buffer, ZydisFormatterContext* context, ZydisDecorator decorator);
758 
759 /* ---------------------------------------------------------------------------------------------- */
760 /* Formatter struct                                                                               */
761 /* ---------------------------------------------------------------------------------------------- */
762 
763 /**
764  * Context structure keeping track of internal state of the formatter.
765  *
766  * All fields in this struct should be considered as "private". Any changes may lead to unexpected
767  * behavior.
768  *
769  * Do NOT change the order of the function fields or the values of the `ZydisFormatterFunction`
770  * enum.
771  */
772 struct ZydisFormatter_
773 {
774     /**
775      * The formatter style.
776      */
777     ZydisFormatterStyle style;
778     /**
779      * The `ZYDIS_FORMATTER_PROP_FORCE_SIZE` property.
780      */
781     ZyanBool force_memory_size;
782     /**
783      * The `ZYDIS_FORMATTER_PROP_FORCE_SEGMENT` property.
784      */
785     ZyanBool force_memory_segment;
786     /**
787      * The `ZYDIS_FORMATTER_PROP_FORCE_SCALE_ONE` property.
788      */
789     ZyanBool force_memory_scale;
790     /**
791      * The `ZYDIS_FORMATTER_PROP_FORCE_RELATIVE_BRANCHES` property.
792      */
793     ZyanBool force_relative_branches;
794     /**
795      * The `ZYDIS_FORMATTER_PROP_FORCE_RELATIVE_RIPREL` property.
796      */
797     ZyanBool force_relative_riprel;
798     /**
799      * The `ZYDIS_FORMATTER_PROP_PRINT_BRANCH_SIZE` property.
800      */
801     ZyanBool print_branch_size;
802     /**
803      * The `ZYDIS_FORMATTER_PROP_DETAILED_PREFIXES` property.
804      */
805     ZyanBool detailed_prefixes;
806     /**
807      * The `ZYDIS_FORMATTER_PROP_ADDR_BASE` property.
808      */
809     ZydisNumericBase addr_base;
810     /**
811      * The `ZYDIS_FORMATTER_PROP_ADDR_SIGNEDNESS` property.
812      */
813     ZydisSignedness addr_signedness;
814     /**
815      * The `ZYDIS_FORMATTER_PROP_ADDR_PADDING_ABSOLUTE` property.
816      */
817     ZydisPadding addr_padding_absolute;
818     /**
819      * The `ZYDIS_FORMATTER_PROP_ADDR_PADDING_RELATIVE` property.
820      */
821     ZydisPadding addr_padding_relative;
822     /**
823      * The `ZYDIS_FORMATTER_PROP_DISP_BASE` property.
824      */
825     ZydisNumericBase disp_base;
826     /**
827      * The `ZYDIS_FORMATTER_PROP_DISP_SIGNEDNESS` property.
828      */
829     ZydisSignedness disp_signedness;
830     /**
831      * The `ZYDIS_FORMATTER_PROP_DISP_PADDING` property.
832      */
833     ZydisPadding disp_padding;
834     /**
835      * The `ZYDIS_FORMATTER_PROP_IMM_BASE` property.
836      */
837     ZydisNumericBase imm_base;
838     /**
839      * The `ZYDIS_FORMATTER_PROP_IMM_SIGNEDNESS` property.
840      */
841     ZydisSignedness imm_signedness;
842     /**
843      * The `ZYDIS_FORMATTER_PROP_IMM_PADDING` property.
844      */
845     ZydisPadding imm_padding;
846     /**
847      * The `ZYDIS_FORMATTER_PROP_UPPERCASE_PREFIXES` property.
848      */
849     ZyanI32 case_prefixes;
850     /**
851      * The `ZYDIS_FORMATTER_PROP_UPPERCASE_MNEMONIC` property.
852      */
853     ZyanI32 case_mnemonic;
854     /**
855      * The `ZYDIS_FORMATTER_PROP_UPPERCASE_REGISTERS` property.
856      */
857     ZyanI32 case_registers;
858     /**
859      * The `ZYDIS_FORMATTER_PROP_UPPERCASE_TYPECASTS` property.
860      */
861     ZyanI32 case_typecasts;
862     /**
863      * The `ZYDIS_FORMATTER_PROP_UPPERCASE_DECORATORS` property.
864      */
865     ZyanI32 case_decorators;
866     /**
867      * The `ZYDIS_FORMATTER_PROP_HEX_UPPERCASE` property.
868      */
869     ZyanBool hex_uppercase;
870     /**
871      * The `ZYDIS_FORMATTER_PROP_HEX_FORCE_LEADING_NUMBER` property.
872      */
873     ZyanBool hex_force_leading_number;
874     /**
875      * The number formats for all numeric bases.
876      *
877      * Index 0 = prefix
878      * Index 1 = suffix
879      */
880     struct
881     {
882         /**
883          * A pointer to the `ZyanStringView` to use as prefix/suffix.
884          */
885         const ZyanStringView* string;
886         /**
887          * The `ZyanStringView` to use as prefix/suffix
888          */
889         ZyanStringView string_data;
890         /**
891          * The actual string data.
892          */
893         char buffer[11];
894     } number_format[ZYDIS_NUMERIC_BASE_MAX_VALUE + 1][2];
895     /**
896      * The `ZYDIS_FORMATTER_FUNC_PRE_INSTRUCTION` function.
897      */
898     ZydisFormatterFunc func_pre_instruction;
899     /**
900      * The `ZYDIS_FORMATTER_FUNC_POST_INSTRUCTION` function.
901      */
902     ZydisFormatterFunc func_post_instruction;
903     /**
904      * The `ZYDIS_FORMATTER_FUNC_FORMAT_INSTRUCTION` function.
905      */
906     ZydisFormatterFunc func_format_instruction;
907     /**
908      * The `ZYDIS_FORMATTER_FUNC_PRE_OPERAND` function.
909      */
910     ZydisFormatterFunc func_pre_operand;
911     /**
912      * The `ZYDIS_FORMATTER_FUNC_POST_OPERAND` function.
913      */
914     ZydisFormatterFunc func_post_operand;
915     /**
916      * The `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_REG` function.
917      */
918     ZydisFormatterFunc func_format_operand_reg;
919     /**
920      * The `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_MEM` function.
921      */
922     ZydisFormatterFunc func_format_operand_mem;
923     /**
924      * The `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_PTR` function.
925      */
926     ZydisFormatterFunc func_format_operand_ptr;
927     /**
928      * The `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_IMM` function.
929      */
930     ZydisFormatterFunc func_format_operand_imm;
931     /**
932      * The `ZYDIS_FORMATTER_FUNC_PRINT_MNEMONIC function.
933      */
934     ZydisFormatterFunc func_print_mnemonic;
935     /**
936      * The `ZYDIS_FORMATTER_FUNC_PRINT_REGISTER` function.
937      */
938     ZydisFormatterRegisterFunc func_print_register;
939     /**
940      * The `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS` function.
941      */
942     ZydisFormatterFunc func_print_address_abs;
943     /**
944      * The `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_REL` function.
945      */
946     ZydisFormatterFunc func_print_address_rel;
947     /**
948      * The `ZYDIS_FORMATTER_FUNC_PRINT_DISP` function.
949      */
950     ZydisFormatterFunc func_print_disp;
951     /**
952      * The `ZYDIS_FORMATTER_FUNC_PRINT_IMM` function.
953      */
954     ZydisFormatterFunc func_print_imm;
955     /**
956      * The `ZYDIS_FORMATTER_FUNC_PRINT_TYPECAST` function.
957      */
958     ZydisFormatterFunc func_print_typecast;
959     /**
960      * The `ZYDIS_FORMATTER_FUNC_PRINT_SEGMENT` function.
961      */
962     ZydisFormatterFunc func_print_segment;
963     /**
964      * The `ZYDIS_FORMATTER_FUNC_PRINT_PREFIXES` function.
965      */
966     ZydisFormatterFunc func_print_prefixes;
967     /**
968      * The `ZYDIS_FORMATTER_FUNC_PRINT_DECORATOR` function.
969      */
970     ZydisFormatterDecoratorFunc func_print_decorator;
971 };
972 
973 /* ---------------------------------------------------------------------------------------------- */
974 
975 /* ============================================================================================== */
976 /* Exported functions                                                                             */
977 /* ============================================================================================== */
978 
979 /**
980  * @addtogroup formatter Formatter
981  * Functions allowing formatting of previously decoded instructions to human readable text.
982  * @{
983  */
984 
985 /* ---------------------------------------------------------------------------------------------- */
986 /* Initialization                                                                                 */
987 /* ---------------------------------------------------------------------------------------------- */
988 
989 /**
990  * Initializes the given `ZydisFormatter` instance.
991  *
992  * @param   formatter   A pointer to the `ZydisFormatter` instance.
993  * @param   style       The base formatter style (either `AT&T` or `Intel` style).
994  *
995  * @return  A zyan status code.
996  */
997 ZYDIS_EXPORT ZyanStatus ZydisFormatterInit(ZydisFormatter* formatter, ZydisFormatterStyle style);
998 
999 /* ---------------------------------------------------------------------------------------------- */
1000 /* Setter                                                                                         */
1001 /* ---------------------------------------------------------------------------------------------- */
1002 
1003 /**
1004  * Changes the value of the specified formatter `property`.
1005  *
1006  * @param   formatter   A pointer to the `ZydisFormatter` instance.
1007  * @param   property    The id of the formatter-property.
1008  * @param   value       The new value.
1009  *
1010  * @return  A zyan status code.
1011  *
1012  * This function returns `ZYAN_STATUS_INVALID_OPERATION` if a property can't be changed for the
1013  * current formatter-style.
1014  */
1015 ZYDIS_EXPORT ZyanStatus ZydisFormatterSetProperty(ZydisFormatter* formatter,
1016     ZydisFormatterProperty property, ZyanUPointer value);
1017 
1018 /**
1019  * Replaces a formatter function with a custom callback and/or retrieves the currently
1020  * used function.
1021  *
1022  * @param   formatter   A pointer to the `ZydisFormatter` instance.
1023  * @param   type        The formatter function-type.
1024  * @param   callback    A pointer to a variable that contains the pointer of the callback function
1025  *                      and receives the pointer of the currently used function.
1026  *
1027  * @return  A zyan status code.
1028  *
1029  * Call this function with `callback` pointing to a `ZYAN_NULL` value to retrieve the currently
1030  * used function without replacing it.
1031  *
1032  * This function returns `ZYAN_STATUS_INVALID_OPERATION` if a function can't be replaced for the
1033  * current formatter-style.
1034  */
1035 ZYDIS_EXPORT ZyanStatus ZydisFormatterSetHook(ZydisFormatter* formatter,
1036     ZydisFormatterFunction type, const void** callback);
1037 
1038 /* ---------------------------------------------------------------------------------------------- */
1039 /* Formatting                                                                                     */
1040 /* ---------------------------------------------------------------------------------------------- */
1041 
1042 /**
1043  * Formats the given instruction and writes it into the output buffer.
1044  *
1045  * @param   formatter       A pointer to the `ZydisFormatter` instance.
1046  * @param   instruction     A pointer to the `ZydisDecodedInstruction` struct.
1047  * @param   operands        A pointer to the decoded operands array.
1048  * @param   operand_count   The length of the `operands` array. Must be equal to or greater than
1049  *                          the value of `instruction->operand_count_visible`.
1050  * @param   buffer          A pointer to the output buffer.
1051  * @param   length          The length of the output buffer (in characters).
1052  * @param   runtime_address The runtime address of the instruction or `ZYDIS_RUNTIME_ADDRESS_NONE`
1053  *                          to print relative addresses.
1054  * @param   user_data       A pointer to user-defined data which can be used in custom formatter
1055  *                          callbacks. Can be `ZYAN_NULL`.
1056  *
1057  * @return  A zyan status code.
1058  */
1059 ZYDIS_EXPORT ZyanStatus ZydisFormatterFormatInstruction(const ZydisFormatter* formatter,
1060     const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operands,
1061     ZyanU8 operand_count, char* buffer, ZyanUSize length, ZyanU64 runtime_address,
1062     void* user_data);
1063 
1064 /**
1065  * Formats the given operand and writes it into the output buffer.
1066  *
1067  * @param   formatter       A pointer to the `ZydisFormatter` instance.
1068  * @param   instruction     A pointer to the `ZydisDecodedInstruction` struct.
1069  * @param   operand         A pointer to the `ZydisDecodedOperand` struct of the operand to format.
1070  * @param   buffer          A pointer to the output buffer.
1071  * @param   length          The length of the output buffer (in characters).
1072  * @param   runtime_address The runtime address of the instruction or `ZYDIS_RUNTIME_ADDRESS_NONE`
1073  *                          to print relative addresses.
1074  * @param   user_data       A pointer to user-defined data which can be used in custom formatter
1075  *                          callbacks. Can be `ZYAN_NULL`.
1076  *
1077  * @return  A zyan status code.
1078  *
1079  * Use `ZydisFormatterFormatInstruction` or `ZydisFormatterFormatInstructionEx` to format a
1080  * complete instruction.
1081  */
1082 ZYDIS_EXPORT ZyanStatus ZydisFormatterFormatOperand(const ZydisFormatter* formatter,
1083     const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand,
1084     char* buffer, ZyanUSize length, ZyanU64 runtime_address, void* user_data);
1085 
1086 /* ---------------------------------------------------------------------------------------------- */
1087 /* Tokenizing                                                                                     */
1088 /* ---------------------------------------------------------------------------------------------- */
1089 
1090 /**
1091  * Tokenizes the given instruction and writes it into the output buffer.
1092  *
1093  * @param   formatter       A pointer to the `ZydisFormatter` instance.
1094  * @param   instruction     A pointer to the `ZydisDecodedInstruction` struct.
1095  * @param   operands        A pointer to the decoded operands array.
1096  * @param   operand_count   The length of the `operands` array. Must be equal to or greater than
1097  *                          the value of `instruction->operand_count_visible`.
1098  * @param   buffer          A pointer to the output buffer.
1099  * @param   length          The length of the output buffer (in bytes).
1100  * @param   runtime_address The runtime address of the instruction or `ZYDIS_RUNTIME_ADDRESS_NONE`
1101  *                          to print relative addresses.
1102  * @param   token           Receives a pointer to the first token in the output buffer.
1103  * @param   user_data       A pointer to user-defined data which can be used in custom formatter
1104  *                          callbacks. Can be `ZYAN_NULL`.
1105  *
1106  * @return  A zyan status code.
1107  */
1108 ZYDIS_EXPORT ZyanStatus ZydisFormatterTokenizeInstruction(const ZydisFormatter* formatter,
1109     const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operands,
1110     ZyanU8 operand_count, void* buffer, ZyanUSize length, ZyanU64 runtime_address,
1111     ZydisFormatterTokenConst** token, void* user_data);
1112 
1113 /**
1114  * Tokenizes the given operand and writes it into the output buffer.
1115  *
1116  * @param   formatter       A pointer to the `ZydisFormatter` instance.
1117  * @param   instruction     A pointer to the `ZydisDecodedInstruction` struct.
1118  * @param   operand         A pointer to the `ZydisDecodedOperand` struct of the operand to format.
1119  * @param   buffer          A pointer to the output buffer.
1120  * @param   length          The length of the output buffer (in bytes).
1121  * @param   runtime_address The runtime address of the instruction or `ZYDIS_RUNTIME_ADDRESS_NONE`
1122  *                          to print relative addresses.
1123  * @param   token           Receives a pointer to the first token in the output buffer.
1124  * @param   user_data       A pointer to user-defined data which can be used in custom formatter
1125  *                          callbacks. Can be `ZYAN_NULL`.
1126  *
1127  * @return  A zyan status code.
1128  *
1129  * Use `ZydisFormatterTokenizeInstruction` to tokenize a complete instruction.
1130  */
1131 ZYDIS_EXPORT ZyanStatus ZydisFormatterTokenizeOperand(const ZydisFormatter* formatter,
1132     const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand,
1133     void* buffer, ZyanUSize length, ZyanU64 runtime_address, ZydisFormatterTokenConst** token,
1134     void* user_data);
1135 
1136 /* ---------------------------------------------------------------------------------------------- */
1137 
1138 /**
1139  * @}
1140  */
1141 
1142 /* ============================================================================================== */
1143 
1144 #ifdef __cplusplus
1145 }
1146 #endif
1147 
1148 #endif /* ZYDIS_FORMATTER_H */
1149