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