Path: blob/master/dep/zydis/include/Zydis/Formatter.h
4216 views
/***************************************************************************************************12Zyan Disassembler Library (Zydis)34Original Author : Florian Bernd56* Permission is hereby granted, free of charge, to any person obtaining a copy7* of this software and associated documentation files (the "Software"), to deal8* in the Software without restriction, including without limitation the rights9* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell10* copies of the Software, and to permit persons to whom the Software is11* furnished to do so, subject to the following conditions:12*13* The above copyright notice and this permission notice shall be included in all14* copies or substantial portions of the Software.15*16* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR17* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,18* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE19* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER20* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,21* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE22* SOFTWARE.2324***************************************************************************************************/2526/**27* @file28* Functions for formatting instructions to human-readable text.29*/3031#ifndef ZYDIS_FORMATTER_H32#define ZYDIS_FORMATTER_H3334#include <Zycore/Defines.h>35#include <Zycore/String.h>36#include <Zycore/Types.h>37#include <Zydis/DecoderTypes.h>38#include <Zydis/FormatterBuffer.h>3940#ifdef __cplusplus41extern "C" {42#endif4344/* ============================================================================================== */45/* Constants */46/* ============================================================================================== */4748/**49* Use this constant as value for `runtime_address` in `ZydisFormatterFormatInstruction(Ex)`50* or `ZydisFormatterFormatOperand(Ex)` to print relative values for all addresses.51*/52#define ZYDIS_RUNTIME_ADDRESS_NONE (ZyanU64)(-1)5354/* ============================================================================================== */55/* Enums and types */56/* ============================================================================================== */5758/* ---------------------------------------------------------------------------------------------- */59/* Formatter style */60/* ---------------------------------------------------------------------------------------------- */6162/**63* Enum selecting the syntax to format the disassembly in.64*/65typedef enum ZydisFormatterStyle_66{67/**68* Generates `AT&T`-style disassembly.69*/70ZYDIS_FORMATTER_STYLE_ATT,71/**72* Generates `Intel`-style disassembly.73*/74ZYDIS_FORMATTER_STYLE_INTEL,75/**76* Generates `MASM`-style disassembly that is directly accepted as input for77* the `MASM` assembler.78*79* The runtime-address is ignored in this mode.80*/81ZYDIS_FORMATTER_STYLE_INTEL_MASM,8283/**84* Maximum value of this enum.85*/86ZYDIS_FORMATTER_STYLE_MAX_VALUE = ZYDIS_FORMATTER_STYLE_INTEL_MASM,87/**88* The minimum number of bits required to represent all values of this enum.89*/90ZYDIS_FORMATTER_STYLE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_FORMATTER_STYLE_MAX_VALUE)91} ZydisFormatterStyle;9293/* ---------------------------------------------------------------------------------------------- */94/* Properties */95/* ---------------------------------------------------------------------------------------------- */9697/**98* Enum selecting a property of the formatter.99*/100typedef enum ZydisFormatterProperty_101{102/* ---------------------------------------------------------------------------------------- */103/* General */104/* ---------------------------------------------------------------------------------------- */105106/**107* Controls the printing of effective operand-size suffixes (`AT&T`) or operand-sizes108* of memory operands (`INTEL`).109*110* Pass `ZYAN_TRUE` as value to force the formatter to always print the size, or `ZYAN_FALSE`111* to only print it if needed.112*/113ZYDIS_FORMATTER_PROP_FORCE_SIZE,114/**115* Controls the printing of segment prefixes.116*117* Pass `ZYAN_TRUE` as value to force the formatter to always print the segment register of118* memory-operands or `ZYAN_FALSE` to omit implicit `DS`/`SS` segments.119*/120ZYDIS_FORMATTER_PROP_FORCE_SEGMENT,121/**122* Controls the printing of the scale-factor component for memory operands.123*124* Pass `ZYAN_TRUE` as value to force the formatter to always print the scale-factor component125* of memory operands or `ZYAN_FALSE` to omit the scale factor for values of `1`.126*/127ZYDIS_FORMATTER_PROP_FORCE_SCALE_ONE,128/**129* Controls the printing of branch addresses.130*131* Pass `ZYAN_TRUE` as value to force the formatter to always print relative branch addresses132* or `ZYAN_FALSE` to use absolute addresses, if a runtime-address different to133* `ZYDIS_RUNTIME_ADDRESS_NONE` was passed.134*/135ZYDIS_FORMATTER_PROP_FORCE_RELATIVE_BRANCHES,136/**137* Controls the printing of `EIP`/`RIP`-relative addresses.138*139* Pass `ZYAN_TRUE` as value to force the formatter to always print relative addresses for140* `EIP`/`RIP`-relative operands or `ZYAN_FALSE` to use absolute addresses, if a runtime-141* address different to `ZYDIS_RUNTIME_ADDRESS_NONE` was passed.142*/143ZYDIS_FORMATTER_PROP_FORCE_RELATIVE_RIPREL,144/**145* Controls the printing of branch-instructions sizes.146*147* Pass `ZYAN_TRUE` as value to print the size (`short`, `near`) of branch148* instructions or `ZYAN_FALSE` to hide it.149*150* Note that the `far`/`l` modifier is always printed.151*/152ZYDIS_FORMATTER_PROP_PRINT_BRANCH_SIZE,153154/**155* Controls the printing of instruction prefixes.156*157* Pass `ZYAN_TRUE` as value to print all instruction-prefixes (even ignored or duplicate158* ones) or `ZYAN_FALSE` to only print prefixes that are effectively used by the instruction.159*/160ZYDIS_FORMATTER_PROP_DETAILED_PREFIXES,161162/* ---------------------------------------------------------------------------------------- */163/* Numeric values */164/* ---------------------------------------------------------------------------------------- */165166/**167* Controls the base of address values.168*/169ZYDIS_FORMATTER_PROP_ADDR_BASE,170/**171* Controls the signedness of relative addresses. Absolute addresses are172* always unsigned.173*/174ZYDIS_FORMATTER_PROP_ADDR_SIGNEDNESS,175/**176* Controls the padding of absolute address values.177*178* Pass `ZYDIS_PADDING_DISABLED` to disable padding, `ZYDIS_PADDING_AUTO` to padd all179* addresses to the current stack width (hexadecimal only), or any other integer value for180* custom padding.181*/182ZYDIS_FORMATTER_PROP_ADDR_PADDING_ABSOLUTE,183/**184* Controls the padding of relative address values.185*186* Pass `ZYDIS_PADDING_DISABLED` to disable padding, `ZYDIS_PADDING_AUTO` to padd all187* addresses to the current stack width (hexadecimal only), or any other integer value for188* custom padding.189*/190ZYDIS_FORMATTER_PROP_ADDR_PADDING_RELATIVE,191192/* ---------------------------------------------------------------------------------------- */193194/**195* Controls the base of displacement values.196*/197ZYDIS_FORMATTER_PROP_DISP_BASE,198/**199* Controls the signedness of displacement values.200*/201ZYDIS_FORMATTER_PROP_DISP_SIGNEDNESS,202/**203* Controls the padding of displacement values.204*205* Pass `ZYDIS_PADDING_DISABLED` to disable padding, or any other integer value for custom206* padding.207*/208ZYDIS_FORMATTER_PROP_DISP_PADDING,209210/* ---------------------------------------------------------------------------------------- */211212/**213* Controls the base of immediate values.214*/215ZYDIS_FORMATTER_PROP_IMM_BASE,216/**217* Controls the signedness of immediate values.218*219* Pass `ZYDIS_SIGNEDNESS_AUTO` to automatically choose the most suitable mode based on the220* operands `ZydisDecodedOperand.imm.is_signed` attribute.221*/222ZYDIS_FORMATTER_PROP_IMM_SIGNEDNESS,223/**224* Controls the padding of immediate values.225*226* Pass `ZYDIS_PADDING_DISABLED` to disable padding, `ZYDIS_PADDING_AUTO` to padd all227* immediates to the operand-width (hexadecimal only), or any other integer value for custom228* padding.229*/230ZYDIS_FORMATTER_PROP_IMM_PADDING,231232/* ---------------------------------------------------------------------------------------- */233/* Text formatting */234/* ---------------------------------------------------------------------------------------- */235236/**237* Controls the letter-case for prefixes.238*239* Pass `ZYAN_TRUE` as value to format in uppercase or `ZYAN_FALSE` to format in lowercase.240*/241ZYDIS_FORMATTER_PROP_UPPERCASE_PREFIXES,242/**243* Controls the letter-case for the mnemonic.244*245* Pass `ZYAN_TRUE` as value to format in uppercase or `ZYAN_FALSE` to format in lowercase.246*/247ZYDIS_FORMATTER_PROP_UPPERCASE_MNEMONIC,248/**249* Controls the letter-case for registers.250*251* Pass `ZYAN_TRUE` as value to format in uppercase or `ZYAN_FALSE` to format in lowercase.252*/253ZYDIS_FORMATTER_PROP_UPPERCASE_REGISTERS,254/**255* Controls the letter-case for typecasts.256*257* Pass `ZYAN_TRUE` as value to format in uppercase or `ZYAN_FALSE` to format in lowercase.258*/259ZYDIS_FORMATTER_PROP_UPPERCASE_TYPECASTS,260/**261* Controls the letter-case for decorators.262*263* Pass `ZYAN_TRUE` as value to format in uppercase or `ZYAN_FALSE` to format in lowercase.264*/265ZYDIS_FORMATTER_PROP_UPPERCASE_DECORATORS,266267/* ---------------------------------------------------------------------------------------- */268/* Number formatting */269/* ---------------------------------------------------------------------------------------- */270271/**272* Controls the prefix for decimal values.273*274* Pass a pointer to a null-terminated C-style string with a maximum length of 10 characters275* to set a custom prefix, or `ZYAN_NULL` to disable it.276*277* The string is deep-copied into an internal buffer.278*/279ZYDIS_FORMATTER_PROP_DEC_PREFIX,280/**281* Controls the suffix for decimal values.282*283* Pass a pointer to a null-terminated C-style string with a maximum length of 10 characters284* to set a custom suffix, or `ZYAN_NULL` to disable it.285*286* The string is deep-copied into an internal buffer.287*/288ZYDIS_FORMATTER_PROP_DEC_SUFFIX,289290/* ---------------------------------------------------------------------------------------- */291292/**293* Controls the letter-case of hexadecimal values.294*295* Pass `ZYAN_TRUE` as value to format in uppercase and `ZYAN_FALSE` to format in lowercase.296*297* The default value is `ZYAN_TRUE`.298*/299ZYDIS_FORMATTER_PROP_HEX_UPPERCASE,300/**301* Controls whether to prepend hexadecimal values with a leading zero if the first character302* is non-numeric.303*304* Pass `ZYAN_TRUE` to prepend a leading zero if the first character is non-numeric or305* `ZYAN_FALSE` to disable this functionality.306*307* The default value is `ZYAN_FALSE`.308*/309ZYDIS_FORMATTER_PROP_HEX_FORCE_LEADING_NUMBER,310/**311* Controls the prefix for hexadecimal values.312*313* Pass a pointer to a null-terminated C-style string with a maximum length of 10 characters314* to set a custom prefix, or `ZYAN_NULL` to disable it.315*316* The string is deep-copied into an internal buffer.317*/318ZYDIS_FORMATTER_PROP_HEX_PREFIX,319/**320* Controls the suffix for hexadecimal values.321*322* Pass a pointer to a null-terminated C-style string with a maximum length of 10 characters323* to set a custom suffix, or `ZYAN_NULL` to disable it.324*325* The string is deep-copied into an internal buffer.326*/327ZYDIS_FORMATTER_PROP_HEX_SUFFIX,328329/* ---------------------------------------------------------------------------------------- */330331/**332* Maximum value of this enum.333*/334ZYDIS_FORMATTER_PROP_MAX_VALUE = ZYDIS_FORMATTER_PROP_HEX_SUFFIX,335/**336* The minimum number of bits required to represent all values of this enum.337*/338ZYDIS_FORMATTER_PROP_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_FORMATTER_PROP_MAX_VALUE)339} ZydisFormatterProperty;340341/* ---------------------------------------------------------------------------------------------- */342343/**344* Enum defining different mantissae to be used during formatting.345*/346typedef enum ZydisNumericBase_347{348/**349* Decimal system.350*/351ZYDIS_NUMERIC_BASE_DEC,352/**353* Hexadecimal system.354*/355ZYDIS_NUMERIC_BASE_HEX,356357/**358* Maximum value of this enum.359*/360ZYDIS_NUMERIC_BASE_MAX_VALUE = ZYDIS_NUMERIC_BASE_HEX,361/**362* The minimum number of bits required to represent all values of this enum.363*/364ZYDIS_NUMERIC_BASE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_NUMERIC_BASE_MAX_VALUE)365} ZydisNumericBase;366367/* ---------------------------------------------------------------------------------------------- */368369/**370* Enum defining the signeness of integers to be used during formatting.371*/372typedef enum ZydisSignedness_373{374/**375* Automatically choose the most suitable mode based on the operands376* ZydisDecodedOperand.imm.is_signed` attribute.377*/378ZYDIS_SIGNEDNESS_AUTO,379/**380* Force signed values.381*/382ZYDIS_SIGNEDNESS_SIGNED,383/**384* Force unsigned values.385*/386ZYDIS_SIGNEDNESS_UNSIGNED,387388/**389* Maximum value of this enum.390*/391ZYDIS_SIGNEDNESS_MAX_VALUE = ZYDIS_SIGNEDNESS_UNSIGNED,392/**393* The minimum number of bits required to represent all values of this enum.394*/395ZYDIS_SIGNEDNESS_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_SIGNEDNESS_MAX_VALUE)396} ZydisSignedness;397398/* ---------------------------------------------------------------------------------------------- */399400/**401* Enum definining magic values that receive special treatment when used as padding properties402* of the formatter.403*/404typedef enum ZydisPadding_405{406/**407* Disables padding.408*/409ZYDIS_PADDING_DISABLED = 0,410/**411* Padds the value to the current stack-width for addresses, or to the412* operand-width for immediate values (hexadecimal only).413*/414ZYDIS_PADDING_AUTO = (-1),415416/**417* Maximum value of this enum.418*/419ZYDIS_PADDING_MAX_VALUE = ZYDIS_PADDING_AUTO,420/**421* The minimum number of bits required to represent all values of this enum.422*/423ZYDIS_PADDING_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_PADDING_MAX_VALUE)424} ZydisPadding;425426/* ---------------------------------------------------------------------------------------------- */427/* Function types */428/* ---------------------------------------------------------------------------------------------- */429430/**431* Enum selecting a formatter function to be replaced with hooks.432*433* Do NOT change the order of the values this enum or the function fields inside the434* `ZydisFormatter` struct.435*/436typedef enum ZydisFormatterFunction_437{438/* ---------------------------------------------------------------------------------------- */439/* Instruction */440/* ---------------------------------------------------------------------------------------- */441442/**443* This function is invoked before the formatter formats an instruction.444*/445ZYDIS_FORMATTER_FUNC_PRE_INSTRUCTION,446/**447* This function is invoked after the formatter formatted an instruction.448*/449ZYDIS_FORMATTER_FUNC_POST_INSTRUCTION,450451/* ---------------------------------------------------------------------------------------- */452453/**454* This function refers to the main formatting function.455*456* Replacing this function allows for complete custom formatting, but indirectly disables all457* other hooks except for `ZYDIS_FORMATTER_FUNC_PRE_INSTRUCTION` and458* `ZYDIS_FORMATTER_FUNC_POST_INSTRUCTION`.459*/460ZYDIS_FORMATTER_FUNC_FORMAT_INSTRUCTION,461462/* ---------------------------------------------------------------------------------------- */463/* Operands */464/* ---------------------------------------------------------------------------------------- */465466/**467* This function is invoked before the formatter formats an operand.468*/469ZYDIS_FORMATTER_FUNC_PRE_OPERAND,470/**471* This function is invoked after the formatter formatted an operand.472*/473ZYDIS_FORMATTER_FUNC_POST_OPERAND,474475/* ---------------------------------------------------------------------------------------- */476477/**478* This function is invoked to format a register operand.479*/480ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_REG,481/**482* This function is invoked to format a memory operand.483*484* Replacing this function might indirectly disable some specific calls to the485* `ZYDIS_FORMATTER_FUNC_PRINT_TYPECAST`, `ZYDIS_FORMATTER_FUNC_PRINT_SEGMENT`,486* `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS` and `ZYDIS_FORMATTER_FUNC_PRINT_DISP` functions.487*/488ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_MEM,489/**490* This function is invoked to format a pointer operand.491*/492ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_PTR,493/**494* This function is invoked to format an immediate operand.495*496* Replacing this function might indirectly disable some specific calls to the497* `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS`, `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_REL` and498* `ZYDIS_FORMATTER_FUNC_PRINT_IMM` functions.499*/500ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_IMM,501502/* ---------------------------------------------------------------------------------------- */503/* Elemental tokens */504/* ---------------------------------------------------------------------------------------- */505506/**507* This function is invoked to print the instruction mnemonic.508*/509ZYDIS_FORMATTER_FUNC_PRINT_MNEMONIC,510511/* ---------------------------------------------------------------------------------------- */512513/**514* This function is invoked to print a register.515*/516ZYDIS_FORMATTER_FUNC_PRINT_REGISTER,517/**518* This function is invoked to print absolute addresses.519*520* Conditionally invoked, if a runtime-address different to `ZYDIS_RUNTIME_ADDRESS_NONE` was521* passed:522* - `IMM` operands with relative address (e.g. `JMP`, `CALL`, ...)523* - `MEM` operands with `EIP`/`RIP`-relative address (e.g. `MOV RAX, [RIP+0x12345678]`)524*525* Always invoked for:526* - `MEM` operands with absolute address (e.g. `MOV RAX, [0x12345678]`)527*/528ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS,529/**530* This function is invoked to print relative addresses.531*532* Conditionally invoked, if `ZYDIS_RUNTIME_ADDRESS_NONE` was passed as runtime-address:533* - `IMM` operands with relative address (e.g. `JMP`, `CALL`, ...)534*/535ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_REL,536/**537* This function is invoked to print a memory displacement value.538*539* If the memory displacement contains an address and a runtime-address different to540* `ZYDIS_RUNTIME_ADDRESS_NONE` was passed, `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS` is called541* instead.542*/543ZYDIS_FORMATTER_FUNC_PRINT_DISP,544/**545* This function is invoked to print an immediate value.546*547* If the immediate contains an address and a runtime-address different to548* `ZYDIS_RUNTIME_ADDRESS_NONE` was passed, `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS` is called549* instead.550*551* If the immediate contains an address and `ZYDIS_RUNTIME_ADDRESS_NONE` was passed as552* runtime-address, `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_REL` is called instead.553*/554ZYDIS_FORMATTER_FUNC_PRINT_IMM,555556/* ---------------------------------------------------------------------------------------- */557/* Optional tokens */558/* ---------------------------------------------------------------------------------------- */559560/**561* This function is invoked to print the size of a memory operand (`INTEL` only).562*/563ZYDIS_FORMATTER_FUNC_PRINT_TYPECAST,564/**565* This function is invoked to print the segment-register of a memory operand.566*/567ZYDIS_FORMATTER_FUNC_PRINT_SEGMENT,568/**569* This function is invoked to print the instruction prefixes.570*/571ZYDIS_FORMATTER_FUNC_PRINT_PREFIXES,572/**573* This function is invoked after formatting an operand to print a `EVEX`/`MVEX`574* decorator.575*/576ZYDIS_FORMATTER_FUNC_PRINT_DECORATOR,577578/* ---------------------------------------------------------------------------------------- */579580/**581* Maximum value of this enum.582*/583ZYDIS_FORMATTER_FUNC_MAX_VALUE = ZYDIS_FORMATTER_FUNC_PRINT_DECORATOR,584/**585* The minimum number of bits required to represent all values of this enum.586*/587ZYDIS_FORMATTER_FUNC_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_FORMATTER_FUNC_MAX_VALUE)588} ZydisFormatterFunction;589590/* ---------------------------------------------------------------------------------------------- */591/* Decorator types */592/* ---------------------------------------------------------------------------------------------- */593594/**595* Enum of all decorator types.596*/597typedef enum ZydisDecorator_598{599ZYDIS_DECORATOR_INVALID,600/**601* The embedded-mask decorator.602*/603ZYDIS_DECORATOR_MASK,604/**605* The broadcast decorator.606*/607ZYDIS_DECORATOR_BC,608/**609* The rounding-control decorator.610*/611ZYDIS_DECORATOR_RC,612/**613* The suppress-all-exceptions decorator.614*/615ZYDIS_DECORATOR_SAE,616/**617* The register-swizzle decorator.618*/619ZYDIS_DECORATOR_SWIZZLE,620/**621* The conversion decorator.622*/623ZYDIS_DECORATOR_CONVERSION,624/**625* The eviction-hint decorator.626*/627ZYDIS_DECORATOR_EH,628629/**630* Maximum value of this enum.631*/632ZYDIS_DECORATOR_MAX_VALUE = ZYDIS_DECORATOR_EH,633/**634* The minimum number of bits required to represent all values of this enum.635*/636ZYDIS_DECORATOR_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_DECORATOR_MAX_VALUE)637} ZydisDecorator;638639/* ---------------------------------------------------------------------------------------------- */640/* Formatter context */641/* ---------------------------------------------------------------------------------------------- */642643typedef struct ZydisFormatter_ ZydisFormatter;644645/**646* Context structure that that is passed to all formatter.647*/648typedef struct ZydisFormatterContext_649{650/**651* A pointer to the `ZydisDecodedInstruction` struct.652*/653const ZydisDecodedInstruction* instruction;654/**655* A pointer to the first `ZydisDecodedOperand` struct of the instruction.656*/657const ZydisDecodedOperand* operands;658/**659* A pointer to the `ZydisDecodedOperand` struct.660*/661const ZydisDecodedOperand* operand;662/**663* The runtime address of the instruction.664*/665ZyanU64 runtime_address;666/**667* A pointer to user-defined data.668*669* This is the value that was previously passed as the `user_data` argument to670* @ref ZydisFormatterFormatInstruction or @ref ZydisFormatterTokenizeOperand.671*/672void* user_data;673} ZydisFormatterContext;674675/* ---------------------------------------------------------------------------------------------- */676/* Function prototypes */677/* ---------------------------------------------------------------------------------------------- */678679/**680* Defines the `ZydisFormatterFunc` function prototype.681*682* @param formatter A pointer to the `ZydisFormatter` instance.683* @param buffer A pointer to the `ZydisFormatterBuffer` struct.684* @param context A pointer to the `ZydisFormatterContext` struct.685*686* @return A zyan status code.687*688* Returning a status code other than `ZYAN_STATUS_SUCCESS` will immediately cause the formatting689* process to fail (see exceptions below).690*691* Returning `ZYDIS_STATUS_SKIP_TOKEN` is valid for functions of the following types and will692* instruct the formatter to omit the whole operand:693* - `ZYDIS_FORMATTER_FUNC_PRE_OPERAND`694* - `ZYDIS_FORMATTER_FUNC_POST_OPERAND`695* - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_REG`696* - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_MEM`697* - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_PTR`698* - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_IMM`699*700* This function prototype is used by functions of the following types:701* - `ZYDIS_FORMATTER_FUNC_PRE_INSTRUCTION`702* - `ZYDIS_FORMATTER_FUNC_POST_INSTRUCTION`703* - `ZYDIS_FORMATTER_FUNC_PRE_OPERAND`704* - `ZYDIS_FORMATTER_FUNC_POST_OPERAND`705* - `ZYDIS_FORMATTER_FUNC_FORMAT_INSTRUCTION`706* - `ZYDIS_FORMATTER_FUNC_PRINT_MNEMONIC`707* - `ZYDIS_FORMATTER_FUNC_PRINT_PREFIXES`708* - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_REG`709* - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_MEM`710* - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_PTR`711* - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_IMM`712* - `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS`713* - `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_REL`714* - `ZYDIS_FORMATTER_FUNC_PRINT_DISP`715* - `ZYDIS_FORMATTER_FUNC_PRINT_IMM`716* - `ZYDIS_FORMATTER_FUNC_PRINT_TYPECAST`717* - `ZYDIS_FORMATTER_FUNC_PRINT_SEGMENT`718*/719typedef ZyanStatus (*ZydisFormatterFunc)(const ZydisFormatter* formatter,720ZydisFormatterBuffer* buffer, ZydisFormatterContext* context);721722/**723* Defines the `ZydisFormatterRegisterFunc` function prototype.724*725* @param formatter A pointer to the `ZydisFormatter` instance.726* @param buffer A pointer to the `ZydisFormatterBuffer` struct.727* @param context A pointer to the `ZydisFormatterContext` struct.728* @param reg The register.729*730* @return Returning a status code other than `ZYAN_STATUS_SUCCESS` will immediately cause the731* formatting process to fail.732*733* This function prototype is used by functions of the following types:734* - `ZYDIS_FORMATTER_FUNC_PRINT_REGISTER`.735*/736typedef ZyanStatus (*ZydisFormatterRegisterFunc)(const ZydisFormatter* formatter,737ZydisFormatterBuffer* buffer, ZydisFormatterContext* context, ZydisRegister reg);738739/**740* Defines the `ZydisFormatterDecoratorFunc` function prototype.741*742* @param formatter A pointer to the `ZydisFormatter` instance.743* @param buffer A pointer to the `ZydisFormatterBuffer` struct.744* @param context A pointer to the `ZydisFormatterContext` struct.745* @param decorator The decorator type.746*747* @return Returning a status code other than `ZYAN_STATUS_SUCCESS` will immediately cause the748* formatting process to fail.749*750* This function type is used for:751* - `ZYDIS_FORMATTER_FUNC_PRINT_DECORATOR`752*/753typedef ZyanStatus (*ZydisFormatterDecoratorFunc)(const ZydisFormatter* formatter,754ZydisFormatterBuffer* buffer, ZydisFormatterContext* context, ZydisDecorator decorator);755756/* ---------------------------------------------------------------------------------------------- */757/* Formatter struct */758/* ---------------------------------------------------------------------------------------------- */759760/**761* Context structure keeping track of internal state of the formatter.762*763* All fields in this struct should be considered as "private". Any changes may lead to unexpected764* behavior.765*766* Do NOT change the order of the function fields or the values of the `ZydisFormatterFunction`767* enum.768*/769struct ZydisFormatter_770{771/**772* The formatter style.773*/774ZydisFormatterStyle style;775/**776* The `ZYDIS_FORMATTER_PROP_FORCE_SIZE` property.777*/778ZyanBool force_memory_size;779/**780* The `ZYDIS_FORMATTER_PROP_FORCE_SEGMENT` property.781*/782ZyanBool force_memory_segment;783/**784* The `ZYDIS_FORMATTER_PROP_FORCE_SCALE_ONE` property.785*/786ZyanBool force_memory_scale;787/**788* The `ZYDIS_FORMATTER_PROP_FORCE_RELATIVE_BRANCHES` property.789*/790ZyanBool force_relative_branches;791/**792* The `ZYDIS_FORMATTER_PROP_FORCE_RELATIVE_RIPREL` property.793*/794ZyanBool force_relative_riprel;795/**796* The `ZYDIS_FORMATTER_PROP_PRINT_BRANCH_SIZE` property.797*/798ZyanBool print_branch_size;799/**800* The `ZYDIS_FORMATTER_DETAILED_PREFIXES` property.801*/802ZyanBool detailed_prefixes;803/**804* The `ZYDIS_FORMATTER_ADDR_BASE` property.805*/806ZydisNumericBase addr_base;807/**808* The `ZYDIS_FORMATTER_ADDR_SIGNEDNESS` property.809*/810ZydisSignedness addr_signedness;811/**812* The `ZYDIS_FORMATTER_ADDR_PADDING_ABSOLUTE` property.813*/814ZydisPadding addr_padding_absolute;815/**816* The `ZYDIS_FORMATTER_ADDR_PADDING_RELATIVE` property.817*/818ZydisPadding addr_padding_relative;819/**820* The `ZYDIS_FORMATTER_DISP_BASE` property.821*/822ZydisNumericBase disp_base;823/**824* The `ZYDIS_FORMATTER_DISP_SIGNEDNESS` property.825*/826ZydisSignedness disp_signedness;827/**828* The `ZYDIS_FORMATTER_DISP_PADDING` property.829*/830ZydisPadding disp_padding;831/**832* The `ZYDIS_FORMATTER_IMM_BASE` property.833*/834ZydisNumericBase imm_base;835/**836* The `ZYDIS_FORMATTER_IMM_SIGNEDNESS` property.837*/838ZydisSignedness imm_signedness;839/**840* The `ZYDIS_FORMATTER_IMM_PADDING` property.841*/842ZydisPadding imm_padding;843/**844* The `ZYDIS_FORMATTER_UPPERCASE_PREFIXES` property.845*/846ZyanI32 case_prefixes;847/**848* The `ZYDIS_FORMATTER_UPPERCASE_MNEMONIC` property.849*/850ZyanI32 case_mnemonic;851/**852* The `ZYDIS_FORMATTER_UPPERCASE_REGISTERS` property.853*/854ZyanI32 case_registers;855/**856* The `ZYDIS_FORMATTER_UPPERCASE_TYPECASTS` property.857*/858ZyanI32 case_typecasts;859/**860* The `ZYDIS_FORMATTER_UPPERCASE_DECORATORS` property.861*/862ZyanI32 case_decorators;863/**864* The `ZYDIS_FORMATTER_HEX_UPPERCASE` property.865*/866ZyanBool hex_uppercase;867/**868* The `ZYDIS_FORMATTER_HEX_FORCE_LEADING_NUMBER` property.869*/870ZyanBool hex_force_leading_number;871/**872* The number formats for all numeric bases.873*874* Index 0 = prefix875* Index 1 = suffix876*/877struct878{879/**880* A pointer to the `ZyanStringView` to use as prefix/suffix.881*/882const ZyanStringView* string;883/**884* The `ZyanStringView` to use as prefix/suffix885*/886ZyanStringView string_data;887/**888* The actual string data.889*/890char buffer[11];891} number_format[ZYDIS_NUMERIC_BASE_MAX_VALUE + 1][2];892/**893* The `ZYDIS_FORMATTER_FUNC_PRE_INSTRUCTION` function.894*/895ZydisFormatterFunc func_pre_instruction;896/**897* The `ZYDIS_FORMATTER_FUNC_POST_INSTRUCTION` function.898*/899ZydisFormatterFunc func_post_instruction;900/**901* The `ZYDIS_FORMATTER_FUNC_FORMAT_INSTRUCTION` function.902*/903ZydisFormatterFunc func_format_instruction;904/**905* The `ZYDIS_FORMATTER_FUNC_PRE_OPERAND` function.906*/907ZydisFormatterFunc func_pre_operand;908/**909* The `ZYDIS_FORMATTER_FUNC_POST_OPERAND` function.910*/911ZydisFormatterFunc func_post_operand;912/**913* The `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_REG` function.914*/915ZydisFormatterFunc func_format_operand_reg;916/**917* The `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_MEM` function.918*/919ZydisFormatterFunc func_format_operand_mem;920/**921* The `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_PTR` function.922*/923ZydisFormatterFunc func_format_operand_ptr;924/**925* The `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_IMM` function.926*/927ZydisFormatterFunc func_format_operand_imm;928/**929* The `ZYDIS_FORMATTER_FUNC_PRINT_MNEMONIC function.930*/931ZydisFormatterFunc func_print_mnemonic;932/**933* The `ZYDIS_FORMATTER_FUNC_PRINT_REGISTER` function.934*/935ZydisFormatterRegisterFunc func_print_register;936/**937* The `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS` function.938*/939ZydisFormatterFunc func_print_address_abs;940/**941* The `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_REL` function.942*/943ZydisFormatterFunc func_print_address_rel;944/**945* The `ZYDIS_FORMATTER_FUNC_PRINT_DISP` function.946*/947ZydisFormatterFunc func_print_disp;948/**949* The `ZYDIS_FORMATTER_FUNC_PRINT_IMM` function.950*/951ZydisFormatterFunc func_print_imm;952/**953* The `ZYDIS_FORMATTER_FUNC_PRINT_TYPECAST` function.954*/955ZydisFormatterFunc func_print_typecast;956/**957* The `ZYDIS_FORMATTER_FUNC_PRINT_SEGMENT` function.958*/959ZydisFormatterFunc func_print_segment;960/**961* The `ZYDIS_FORMATTER_FUNC_PRINT_PREFIXES` function.962*/963ZydisFormatterFunc func_print_prefixes;964/**965* The `ZYDIS_FORMATTER_FUNC_PRINT_DECORATOR` function.966*/967ZydisFormatterDecoratorFunc func_print_decorator;968};969970/* ---------------------------------------------------------------------------------------------- */971972/* ============================================================================================== */973/* Exported functions */974/* ============================================================================================== */975976/**977* @addtogroup formatter Formatter978* Functions allowing formatting of previously decoded instructions to human readable text.979* @{980*/981982/* ---------------------------------------------------------------------------------------------- */983/* Initialization */984/* ---------------------------------------------------------------------------------------------- */985986/**987* Initializes the given `ZydisFormatter` instance.988*989* @param formatter A pointer to the `ZydisFormatter` instance.990* @param style The base formatter style (either `AT&T` or `Intel` style).991*992* @return A zyan status code.993*/994ZYDIS_EXPORT ZyanStatus ZydisFormatterInit(ZydisFormatter* formatter, ZydisFormatterStyle style);995996/* ---------------------------------------------------------------------------------------------- */997/* Setter */998/* ---------------------------------------------------------------------------------------------- */9991000/**1001* Changes the value of the specified formatter `property`.1002*1003* @param formatter A pointer to the `ZydisFormatter` instance.1004* @param property The id of the formatter-property.1005* @param value The new value.1006*1007* @return A zyan status code.1008*1009* This function returns `ZYAN_STATUS_INVALID_OPERATION` if a property can't be changed for the1010* current formatter-style.1011*/1012ZYDIS_EXPORT ZyanStatus ZydisFormatterSetProperty(ZydisFormatter* formatter,1013ZydisFormatterProperty property, ZyanUPointer value);10141015/**1016* Replaces a formatter function with a custom callback and/or retrieves the currently1017* used function.1018*1019* @param formatter A pointer to the `ZydisFormatter` instance.1020* @param type The formatter function-type.1021* @param callback A pointer to a variable that contains the pointer of the callback function1022* and receives the pointer of the currently used function.1023*1024* @return A zyan status code.1025*1026* Call this function with `callback` pointing to a `ZYAN_NULL` value to retrieve the currently1027* used function without replacing it.1028*1029* This function returns `ZYAN_STATUS_INVALID_OPERATION` if a function can't be replaced for the1030* current formatter-style.1031*/1032ZYDIS_EXPORT ZyanStatus ZydisFormatterSetHook(ZydisFormatter* formatter,1033ZydisFormatterFunction type, const void** callback);10341035/* ---------------------------------------------------------------------------------------------- */1036/* Formatting */1037/* ---------------------------------------------------------------------------------------------- */10381039/**1040* Formats the given instruction and writes it into the output buffer.1041*1042* @param formatter A pointer to the `ZydisFormatter` instance.1043* @param instruction A pointer to the `ZydisDecodedInstruction` struct.1044* @param operands A pointer to the decoded operands array.1045* @param operand_count The length of the `operands` array. Must be equal to or greater than1046* the value of `instruction->operand_count_visible`.1047* @param buffer A pointer to the output buffer.1048* @param length The length of the output buffer (in characters).1049* @param runtime_address The runtime address of the instruction or `ZYDIS_RUNTIME_ADDRESS_NONE`1050* to print relative addresses.1051* @param user_data A pointer to user-defined data which can be used in custom formatter1052* callbacks. Can be `ZYAN_NULL`.1053*1054* @return A zyan status code.1055*/1056ZYDIS_EXPORT ZyanStatus ZydisFormatterFormatInstruction(const ZydisFormatter* formatter,1057const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operands,1058ZyanU8 operand_count, char* buffer, ZyanUSize length, ZyanU64 runtime_address,1059void* user_data);10601061/**1062* Formats the given operand and writes it into the output buffer.1063*1064* @param formatter A pointer to the `ZydisFormatter` instance.1065* @param instruction A pointer to the `ZydisDecodedInstruction` struct.1066* @param operand A pointer to the `ZydisDecodedOperand` struct of the operand to format.1067* @param buffer A pointer to the output buffer.1068* @param length The length of the output buffer (in characters).1069* @param runtime_address The runtime address of the instruction or `ZYDIS_RUNTIME_ADDRESS_NONE`1070* to print relative addresses.1071* @param user_data A pointer to user-defined data which can be used in custom formatter1072* callbacks. Can be `ZYAN_NULL`.1073*1074* @return A zyan status code.1075*1076* Use `ZydisFormatterFormatInstruction` or `ZydisFormatterFormatInstructionEx` to format a1077* complete instruction.1078*/1079ZYDIS_EXPORT ZyanStatus ZydisFormatterFormatOperand(const ZydisFormatter* formatter,1080const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand,1081char* buffer, ZyanUSize length, ZyanU64 runtime_address, void* user_data);10821083/* ---------------------------------------------------------------------------------------------- */1084/* Tokenizing */1085/* ---------------------------------------------------------------------------------------------- */10861087/**1088* Tokenizes the given instruction and writes it into the output buffer.1089*1090* @param formatter A pointer to the `ZydisFormatter` instance.1091* @param instruction A pointer to the `ZydisDecodedInstruction` struct.1092* @param operands A pointer to the decoded operands array.1093* @param operand_count The length of the `operands` array. Must be equal to or greater than1094* the value of `instruction->operand_count_visible`.1095* @param buffer A pointer to the output buffer.1096* @param length The length of the output buffer (in bytes).1097* @param runtime_address The runtime address of the instruction or `ZYDIS_RUNTIME_ADDRESS_NONE`1098* to print relative addresses.1099* @param token Receives a pointer to the first token in the output buffer.1100* @param user_data A pointer to user-defined data which can be used in custom formatter1101* callbacks. Can be `ZYAN_NULL`.1102*1103* @return A zyan status code.1104*/1105ZYDIS_EXPORT ZyanStatus ZydisFormatterTokenizeInstruction(const ZydisFormatter* formatter,1106const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operands,1107ZyanU8 operand_count, void* buffer, ZyanUSize length, ZyanU64 runtime_address,1108ZydisFormatterTokenConst** token, void* user_data);11091110/**1111* Tokenizes the given operand and writes it into the output buffer.1112*1113* @param formatter A pointer to the `ZydisFormatter` instance.1114* @param instruction A pointer to the `ZydisDecodedInstruction` struct.1115* @param operand A pointer to the `ZydisDecodedOperand` struct of the operand to format.1116* @param buffer A pointer to the output buffer.1117* @param length The length of the output buffer (in bytes).1118* @param runtime_address The runtime address of the instruction or `ZYDIS_RUNTIME_ADDRESS_NONE`1119* to print relative addresses.1120* @param token Receives a pointer to the first token in the output buffer.1121* @param user_data A pointer to user-defined data which can be used in custom formatter1122* callbacks. Can be `ZYAN_NULL`.1123*1124* @return A zyan status code.1125*1126* Use `ZydisFormatterTokenizeInstruction` to tokenize a complete instruction.1127*/1128ZYDIS_EXPORT ZyanStatus ZydisFormatterTokenizeOperand(const ZydisFormatter* formatter,1129const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand,1130void* buffer, ZyanUSize length, ZyanU64 runtime_address, ZydisFormatterTokenConst** token,1131void* user_data);11321133/* ---------------------------------------------------------------------------------------------- */11341135/**1136* @}1137*/11381139/* ============================================================================================== */11401141#ifdef __cplusplus1142}1143#endif11441145#endif /* ZYDIS_FORMATTER_H */114611471148