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 */