tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Encoder.h (17781B)


      1 /***************************************************************************************************
      2 
      3  Zyan Disassembler Library (Zydis)
      4 
      5  Original Author : Mappa
      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 encoding instructions.
     30 */
     31 
     32 #ifndef ZYDIS_ENCODER_H
     33 #define ZYDIS_ENCODER_H
     34 
     35 #include "zydis/Zycore/Types.h"
     36 #include "zydis/Zydis/MetaInfo.h"
     37 #include "zydis/Zydis/Register.h"
     38 #include "zydis/Zydis/DecoderTypes.h"
     39 #include "zydis/Zydis/Mnemonic.h"
     40 #include "zydis/Zydis/Status.h"
     41 
     42 #ifdef __cplusplus
     43 extern "C" {
     44 #endif
     45 
     46 /* ============================================================================================== */
     47 /* Macros                                                                                         */
     48 /* ============================================================================================== */
     49 
     50 /* ---------------------------------------------------------------------------------------------- */
     51 /* Constants                                                                                      */
     52 /* ---------------------------------------------------------------------------------------------- */
     53 
     54 /**
     55 * Maximum number of encodable (explicit and implicit) operands
     56 */
     57 #define ZYDIS_ENCODER_MAX_OPERANDS 5
     58 
     59 // If asserts are failing here remember to update encoder table generator before fixing asserts
     60 ZYAN_STATIC_ASSERT(ZYAN_BITS_TO_REPRESENT(ZYDIS_ENCODER_MAX_OPERANDS) == 3);
     61 
     62 /**
     63 * Combination of all user-encodable prefixes
     64 */
     65 #define ZYDIS_ENCODABLE_PREFIXES   (ZYDIS_ATTRIB_HAS_LOCK | \
     66                                    ZYDIS_ATTRIB_HAS_REP | \
     67                                    ZYDIS_ATTRIB_HAS_REPE | \
     68                                    ZYDIS_ATTRIB_HAS_REPNE | \
     69                                    ZYDIS_ATTRIB_HAS_BND | \
     70                                    ZYDIS_ATTRIB_HAS_XACQUIRE | \
     71                                    ZYDIS_ATTRIB_HAS_XRELEASE | \
     72                                    ZYDIS_ATTRIB_HAS_BRANCH_NOT_TAKEN | \
     73                                    ZYDIS_ATTRIB_HAS_BRANCH_TAKEN | \
     74                                    ZYDIS_ATTRIB_HAS_NOTRACK | \
     75                                    ZYDIS_ATTRIB_HAS_SEGMENT_CS | \
     76                                    ZYDIS_ATTRIB_HAS_SEGMENT_SS | \
     77                                    ZYDIS_ATTRIB_HAS_SEGMENT_DS | \
     78                                    ZYDIS_ATTRIB_HAS_SEGMENT_ES | \
     79                                    ZYDIS_ATTRIB_HAS_SEGMENT_FS | \
     80                                    ZYDIS_ATTRIB_HAS_SEGMENT_GS)
     81 
     82 /* ---------------------------------------------------------------------------------------------- */
     83 
     84 /* ============================================================================================== */
     85 /* Enums and types                                                                                */
     86 /* ============================================================================================== */
     87 
     88 /**
     89 * Defines possible physical instruction encodings as bit flags, so multiple acceptable encodings
     90 * can be specified simultaneously.
     91 */
     92 typedef enum ZydisEncodableEncoding_
     93 {
     94    ZYDIS_ENCODABLE_ENCODING_DEFAULT                = 0x00000000,
     95    ZYDIS_ENCODABLE_ENCODING_LEGACY                 = 0x00000001,
     96    ZYDIS_ENCODABLE_ENCODING_3DNOW                  = 0x00000002,
     97    ZYDIS_ENCODABLE_ENCODING_XOP                    = 0x00000004,
     98    ZYDIS_ENCODABLE_ENCODING_VEX                    = 0x00000008,
     99    ZYDIS_ENCODABLE_ENCODING_EVEX                   = 0x00000010,
    100    ZYDIS_ENCODABLE_ENCODING_MVEX                   = 0x00000020,
    101 
    102    /**
    103     * Maximum value of this enum.
    104     */
    105    ZYDIS_ENCODABLE_ENCODING_MAX_VALUE              = (ZYDIS_ENCODABLE_ENCODING_MVEX | 
    106                                                       (ZYDIS_ENCODABLE_ENCODING_MVEX - 1)),
    107    /**
    108     * The minimum number of bits required to represent all values of this enum.
    109     */
    110    ZYDIS_ENCODABLE_ENCODING_REQUIRED_BITS          = 
    111        ZYAN_BITS_TO_REPRESENT(ZYDIS_ENCODABLE_ENCODING_MAX_VALUE)
    112 } ZydisEncodableEncoding;
    113 
    114 /**
    115 * Defines encodable physical/effective sizes of relative immediate operands. See
    116 * `ZydisEncoderRequest.branch_width` for more details.
    117 */
    118 typedef enum ZydisBranchWidth_
    119 {
    120    ZYDIS_BRANCH_WIDTH_NONE,
    121    ZYDIS_BRANCH_WIDTH_8,
    122    ZYDIS_BRANCH_WIDTH_16,
    123    ZYDIS_BRANCH_WIDTH_32,
    124    ZYDIS_BRANCH_WIDTH_64,
    125 
    126    /**
    127     * Maximum value of this enum.
    128     */
    129    ZYDIS_BRANCH_WIDTH_MAX_VALUE = ZYDIS_BRANCH_WIDTH_64,
    130    /**
    131     * The minimum number of bits required to represent all values of this enum.
    132     */
    133    ZYDIS_BRANCH_WIDTH_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_BRANCH_WIDTH_MAX_VALUE)
    134 } ZydisBranchWidth;
    135 
    136 /**
    137 * Defines possible values for address size hints. See `ZydisEncoderRequest` for more information
    138 * about address size hints.
    139 */
    140 typedef enum ZydisAddressSizeHint_
    141 {
    142    ZYDIS_ADDRESS_SIZE_HINT_NONE,
    143    ZYDIS_ADDRESS_SIZE_HINT_16,
    144    ZYDIS_ADDRESS_SIZE_HINT_32,
    145    ZYDIS_ADDRESS_SIZE_HINT_64,
    146 
    147    /**
    148     * Maximum value of this enum.
    149     */
    150    ZYDIS_ADDRESS_SIZE_HINT_MAX_VALUE = ZYDIS_ADDRESS_SIZE_HINT_64,
    151    /**
    152     * The minimum number of bits required to represent all values of this enum.
    153     */
    154    ZYDIS_ADDRESS_SIZE_HINT_REQUIRED_BITS =
    155        ZYAN_BITS_TO_REPRESENT(ZYDIS_ADDRESS_SIZE_HINT_MAX_VALUE)
    156 } ZydisAddressSizeHint;
    157 
    158 /**
    159 * Defines possible values for operand size hints. See `ZydisEncoderRequest` for more information
    160 * about operand size hints.
    161 */
    162 typedef enum ZydisOperandSizeHint_
    163 {
    164    ZYDIS_OPERAND_SIZE_HINT_NONE,
    165    ZYDIS_OPERAND_SIZE_HINT_8,
    166    ZYDIS_OPERAND_SIZE_HINT_16,
    167    ZYDIS_OPERAND_SIZE_HINT_32,
    168    ZYDIS_OPERAND_SIZE_HINT_64,
    169 
    170    /**
    171     * Maximum value of this enum.
    172     */
    173    ZYDIS_OPERAND_SIZE_HINT_MAX_VALUE = ZYDIS_OPERAND_SIZE_HINT_64,
    174    /**
    175     * The minimum number of bits required to represent all values of this enum.
    176     */
    177    ZYDIS_OPERAND_SIZE_HINT_REQUIRED_BITS =
    178        ZYAN_BITS_TO_REPRESENT(ZYDIS_OPERAND_SIZE_HINT_MAX_VALUE)
    179 } ZydisOperandSizeHint;
    180 
    181 /**
    182 * Describes explicit or implicit instruction operand.
    183 */
    184 typedef struct ZydisEncoderOperand_
    185 {
    186    /**
    187     * The type of the operand.
    188     */
    189    ZydisOperandType type;
    190    /**
    191     * Extended info for register-operands.
    192     */
    193    struct ZydisEncoderOperandReg_
    194    {
    195        /**
    196         * The register value.
    197         */
    198        ZydisRegister value;
    199        /**
    200         * Is this 4th operand (`VEX`/`XOP`). Despite its name, `is4` encoding can sometimes be
    201         * applied to 3rd operand instead of 4th. This field is used to resolve such ambiguities.
    202         * For all other operands it should be set to `ZYAN_FALSE`.
    203         */
    204        ZyanBool is4;
    205    } reg;
    206    /**
    207     * Extended info for memory-operands.
    208     */
    209    struct ZydisEncoderOperandMem_
    210    {
    211        /**
    212         * The base register.
    213         */
    214        ZydisRegister base;
    215        /**
    216         * The index register.
    217         */
    218        ZydisRegister index;
    219        /**
    220         * The scale factor.
    221         */
    222        ZyanU8 scale;
    223        /**
    224         * The displacement value. This value is always treated as 64-bit signed integer, so it's
    225         * important to take this into account when specifying absolute addresses. For example
    226         * to specify a 16-bit address 0x8000 in 16-bit mode it should be sign extended to
    227         * `0xFFFFFFFFFFFF8000`. See `address_size_hint` for more information about absolute
    228         * addresses.
    229         */
    230        ZyanI64 displacement;
    231        /**
    232         * Size of this operand in bytes.
    233         */
    234        ZyanU16 size;
    235    } mem;
    236    /**
    237     * Extended info for pointer-operands.
    238     */
    239    struct ZydisEncoderOperandPtr_
    240    {
    241        /**
    242         * The segment value.
    243         */
    244        ZyanU16 segment;
    245        /**
    246         * The offset value.
    247         */
    248        ZyanU32 offset;
    249    } ptr;
    250    /**
    251     * Extended info for immediate-operands.
    252     */
    253    union ZydisEncoderOperandImm_
    254    {
    255        /**
    256         * The unsigned immediate value.
    257         */
    258        ZyanU64 u;
    259        /**
    260         * The signed immediate value.
    261         */
    262        ZyanI64 s;
    263    } imm;
    264 } ZydisEncoderOperand;
    265 
    266 /**
    267 * Main structure consumed by the encoder. It represents full semantics of an instruction.
    268 */
    269 typedef struct ZydisEncoderRequest_
    270 {
    271    /**
    272     * The machine mode used to encode this instruction.
    273     */
    274    ZydisMachineMode machine_mode;
    275    /**
    276     * This optional field can be used to restrict allowed physical encodings for desired
    277     * instruction. Some mnemonics can be supported by more than one encoding, so this field can
    278     * resolve ambiguities e.g. you can disable `AVX-512` extensions by prohibiting usage of `EVEX`
    279     * prefix and allow only `VEX` variants.
    280     */
    281    ZydisEncodableEncoding allowed_encodings;
    282    /**
    283     * The instruction-mnemonic.
    284     */
    285    ZydisMnemonic mnemonic;
    286    /**
    287     * A combination of requested encodable prefixes (`ZYDIS_ATTRIB_HAS_*` flags) for desired
    288     * instruction. See `ZYDIS_ENCODABLE_PREFIXES` for list of available prefixes.
    289     */
    290    ZydisInstructionAttributes prefixes;
    291    /**
    292     * Branch type (required for branching instructions only). Use `ZYDIS_BRANCH_TYPE_NONE` to let
    293     * encoder pick size-optimal branch type automatically (`short` and `near` are prioritized over
    294     * `far`).
    295     */
    296    ZydisBranchType branch_type;
    297    /**
    298     * Specifies physical size for relative immediate operands. Use `ZYDIS_BRANCH_WIDTH_NONE` to
    299     * let encoder pick size-optimal branch width automatically. For segment:offset `far` branches
    300     * this field applies to physical size of the offset part. For branching instructions without
    301     * relative operands this field affects effective operand size attribute.
    302     */
    303    ZydisBranchWidth branch_width;
    304    /**
    305     * Optional address size hint used to resolve ambiguities for some instructions. Generally
    306     * encoder deduces address size from `ZydisEncoderOperand` structures that represent
    307     * explicit and implicit operands. This hint resolves conflicts when instruction's hidden
    308     * operands scale with address size attribute.
    309     *
    310     * This hint is also used for instructions with absolute memory addresses (memory operands with
    311     * displacement and no registers). Since displacement field is a 64-bit signed integer it's not
    312     * possible to determine actual size of the address value in all situations. This hint
    313     * specifies size of the address value provided inside encoder request rather than desired
    314     * address size attribute of encoded instruction. Use `ZYDIS_ADDRESS_SIZE_HINT_NONE` to assume
    315     * address size default for specified machine mode.
    316     */
    317    ZydisAddressSizeHint address_size_hint;
    318    /**
    319     * Optional operand size hint used to resolve ambiguities for some instructions. Generally
    320     * encoder deduces operand size from `ZydisEncoderOperand` structures that represent
    321     * explicit and implicit operands. This hint resolves conflicts when instruction's hidden
    322     * operands scale with operand size attribute.
    323     */
    324    ZydisOperandSizeHint operand_size_hint;
    325    /**
    326     * The number of instruction-operands.
    327     */
    328    ZyanU8 operand_count;
    329    /**
    330     * Detailed info for all explicit and implicit instruction operands.
    331     */
    332    ZydisEncoderOperand operands[ZYDIS_ENCODER_MAX_OPERANDS];
    333    /**
    334     * Extended info for `EVEX` instructions.
    335     */
    336    struct ZydisEncoderRequestEvexFeatures_
    337    {
    338        /**
    339         * The broadcast-mode. Specify `ZYDIS_BROADCAST_MODE_INVALID` for instructions with
    340         * static broadcast functionality.
    341         */
    342        ZydisBroadcastMode broadcast;
    343        /**
    344         * The rounding-mode.
    345         */
    346        ZydisRoundingMode rounding;
    347        /**
    348         * Signals, if the `SAE` (suppress-all-exceptions) functionality should be enabled for 
    349         * the instruction.
    350         */
    351        ZyanBool sae;
    352        /**
    353         * Signals, if the zeroing-mask functionality should be enabled for the instruction.
    354         * Specify `ZYAN_TRUE` for instructions with forced zeroing mask.
    355         */
    356        ZyanBool zeroing_mask;
    357    } evex;
    358    /**
    359     * Extended info for `MVEX` instructions.
    360     */
    361    struct ZydisEncoderRequestMvexFeatures_
    362    {
    363        /**
    364         * The broadcast-mode.
    365         */
    366        ZydisBroadcastMode broadcast;
    367        /**
    368         * The data-conversion mode.
    369         */
    370        ZydisConversionMode conversion;
    371        /**
    372         * The rounding-mode.
    373         */
    374        ZydisRoundingMode rounding;
    375        /**
    376         * The `AVX` register-swizzle mode.
    377         */
    378        ZydisSwizzleMode swizzle;
    379        /**
    380         * Signals, if the `SAE` (suppress-all-exceptions) functionality is enabled for
    381         * the instruction.
    382         */
    383        ZyanBool sae;
    384        /**
    385         * Signals, if the instruction has a memory-eviction-hint (`KNC` only).
    386         */
    387        ZyanBool eviction_hint;
    388    } mvex;
    389 } ZydisEncoderRequest;
    390 
    391 /* ============================================================================================== */
    392 /* Exported functions                                                                             */
    393 /* ============================================================================================== */
    394 
    395 /**
    396 * @addtogroup encoder Encoder
    397 * Functions allowing encoding of instruction bytes from a machine interpretable struct.
    398 * @{
    399 */
    400 
    401 /**
    402 * Encodes instruction with semantics specified in encoder request structure.
    403 *
    404 * @param   request     A pointer to the `ZydisEncoderRequest` struct.
    405 * @param   buffer      A pointer to the output buffer receiving encoded instruction.
    406 * @param   length      A pointer to the variable containing length of the output buffer. Upon 
    407 *                      successful return this variable receives length of the encoded instruction.
    408 *
    409 * @return  A zyan status code.
    410 */
    411 ZYDIS_EXPORT ZyanStatus ZydisEncoderEncodeInstruction(const ZydisEncoderRequest *request, 
    412    void *buffer, ZyanUSize *length);
    413 
    414 /**
    415 * Encodes instruction with semantics specified in encoder request structure. This function expects
    416 * absolute addresses inside encoder request instead of `EIP`/`RIP`-relative values. Function
    417 * predicts final instruction length prior to encoding and writes back calculated relative operands
    418 * to provided encoder request.
    419 *
    420 * @param   request         A pointer to the `ZydisEncoderRequest` struct.
    421 * @param   buffer          A pointer to the output buffer receiving encoded instruction.
    422 * @param   length          A pointer to the variable containing length of the output buffer. Upon
    423 *                          successful return this variable receives length of the encoded
    424 *                          instruction.
    425 * @param   runtime_address The runtime address of the instruction.
    426 *
    427 * @return  A zyan status code.
    428 */
    429 ZYDIS_EXPORT ZyanStatus ZydisEncoderEncodeInstructionAbsolute(ZydisEncoderRequest *request,
    430    void *buffer, ZyanUSize *length, ZyanU64 runtime_address);
    431 
    432 /**
    433 * Converts decoded instruction to encoder request that can be passed to
    434 * `ZydisEncoderEncodeInstruction`.
    435 *
    436 * @param   instruction     A pointer to the `ZydisDecodedInstruction` struct.
    437 * @param   operands        A pointer to the decoded operands.
    438 * @param   operand_count   The operand count.
    439 * @param   request         A pointer to the `ZydisEncoderRequest` struct, that receives
    440 *                          information necessary for encoder to re-encode the instruction.
    441 *
    442 * This function performs simple structure conversion and does minimal sanity checks on the 
    443 * input. There's no guarantee that produced request will be accepted by
    444 * `ZydisEncoderEncodeInstruction` if malformed `ZydisDecodedInstruction` or malformed
    445 * `ZydisDecodedOperands` is passed to this function.
    446 *
    447 * @return  A zyan status code.
    448 */
    449 ZYDIS_EXPORT ZyanStatus ZydisEncoderDecodedInstructionToEncoderRequest(
    450    const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operands,
    451    ZyanU8 operand_count, ZydisEncoderRequest* request);
    452 
    453 /**
    454 * Fills provided buffer with `NOP` instructions using longest possible multi-byte instructions.
    455 *
    456 * @param   buffer  A pointer to the output buffer receiving encoded instructions.
    457 * @param   length  Size of the output buffer.
    458 *
    459 * @return  A zyan status code.
    460 */
    461 ZYDIS_EXPORT ZyanStatus ZydisEncoderNopFill(void *buffer, ZyanUSize length);
    462 
    463 /** @} */
    464 
    465 /* ============================================================================================== */
    466 
    467 #ifdef __cplusplus
    468 }
    469 #endif
    470 
    471 #endif /* ZYDIS_ENCODER_H */