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