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