1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
|
/***************************************************************************************************
Zyan Disassembler Library (Zydis)
Original Author : Florian Bernd
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
***************************************************************************************************/
/**
* @file
* Other utility functions.
*/
#ifndef ZYDIS_UTILS_H
#define ZYDIS_UTILS_H
#include "ZycoreDefines.h"
#include "ZydisDecoderTypes.h"
#include "ZydisStatus.h"
#include <wtf/Compiler.h>
WTF_ALLOW_UNSAFE_BUFFER_USAGE_BEGIN
#ifdef __cplusplus
extern "C" {
#endif
/* ============================================================================================== */
/* Macros */
/* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* Constants */
/* ---------------------------------------------------------------------------------------------- */
#define ZYDIS_MAX_INSTRUCTION_SEGMENT_COUNT 9
/* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */
/* Enums and types */
/* ============================================================================================== */
/**
* Defines the `ZydisInstructionSegment` struct.
*/
typedef enum ZydisInstructionSegment_
{
ZYDIS_INSTR_SEGMENT_NONE,
/**
* The legacy prefixes (including ignored `REX` prefixes).
*/
ZYDIS_INSTR_SEGMENT_PREFIXES,
/**
* The effective `REX` prefix byte.
*/
ZYDIS_INSTR_SEGMENT_REX,
/**
* The `XOP` prefix bytes.
*/
ZYDIS_INSTR_SEGMENT_XOP,
/**
* The `VEX` prefix bytes.
*/
ZYDIS_INSTR_SEGMENT_VEX,
/**
* The `EVEX` prefix bytes.
*/
ZYDIS_INSTR_SEGMENT_EVEX,
/**
* The `MVEX` prefix bytes.
*/
ZYDIS_INSTR_SEGMENT_MVEX,
/**
* The opcode bytes.
*/
ZYDIS_INSTR_SEGMENT_OPCODE,
/**
* The `ModRM` byte.
*/
ZYDIS_INSTR_SEGMENT_MODRM,
/**
* The `SIB` byte.
*/
ZYDIS_INSTR_SEGMENT_SIB,
/**
* The displacement bytes.
*/
ZYDIS_INSTR_SEGMENT_DISPLACEMENT,
/**
* The immediate bytes.
*/
ZYDIS_INSTR_SEGMENT_IMMEDIATE,
/**
* Maximum value of this enum.
*/
ZYDIS_INSTR_SEGMENT_MAX_VALUE = ZYDIS_INSTR_SEGMENT_IMMEDIATE,
/**
* The minimum number of bits required to represent all values of this enum.
*/
ZYDIS_INSTR_SEGMENT_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_INSTR_SEGMENT_MAX_VALUE)
} ZydisInstructionSegment;
/**
* Defines the `ZydisInstructionSegments` struct.
*/
typedef struct ZydisInstructionSegments_
{
/**
* The number of logical instruction segments.
*/
ZyanU8 count;
struct
{
/**
* The type of the segment.
*/
ZydisInstructionSegment type;
/**
* The offset of the segment relative to the start of the instruction (in bytes).
*/
ZyanU8 offset;
/**
* The size of the segment, in bytes.
*/
ZyanU8 size;
} segments[ZYDIS_MAX_INSTRUCTION_SEGMENT_COUNT];
} ZydisInstructionSegments;
/* ============================================================================================== */
/* Exported functions */
/* ============================================================================================== */
/**
* @addtogroup utils Utils
* Miscellaneous utility functions. Address translation and other helpers.
* @{
*/
/* ---------------------------------------------------------------------------------------------- */
/* Address calculation */
/* ---------------------------------------------------------------------------------------------- */
// TODO: Provide a function that works in minimal-mode and does not require a operand parameter
/**
* Calculates the absolute address value for the given instruction operand.
*
* @param instruction A pointer to the `ZydisDecodedInstruction` struct.
* @param operand A pointer to the `ZydisDecodedOperand` struct.
* @param runtime_address The runtime address of the instruction.
* @param result_address A pointer to the memory that receives the absolute address.
*
* @return A zyan status code.
*
* You should use this function in the following cases:
* - `IMM` operands with relative address (e.g. `JMP`, `CALL`, ...)
* - `MEM` operands with `RIP`/`EIP`-relative address (e.g. `MOV RAX, [RIP+0x12345678]`)
* - `MEM` operands with absolute address (e.g. `MOV RAX, [0x12345678]`)
* - The displacement needs to get truncated and zero extended
*/
ZYDIS_EXPORT ZyanStatus ZydisCalcAbsoluteAddress(const ZydisDecodedInstruction* instruction,
const ZydisDecodedOperand* operand, ZyanU64 runtime_address, ZyanU64* result_address);
/**
* Calculates the absolute address value for the given instruction operand.
*
* @param instruction A pointer to the `ZydisDecodedInstruction` struct.
* @param operand A pointer to the `ZydisDecodedOperand` struct.
* @param runtime_address The runtime address of the instruction.
* @param register_context A pointer to the `ZydisRegisterContext` struct.
* @param result_address A pointer to the memory that receives the absolute target-address.
*
* @return A zyan status code.
*
* This function behaves like `ZydisCalcAbsoluteAddress` but takes an additional register-context
* argument to allow calculation of addresses depending on runtime register values.
*
* Note that `IP/EIP/RIP` from the register-context will be ignored in favor of the passed
* runtime-address.
*/
ZYDIS_EXPORT ZyanStatus ZydisCalcAbsoluteAddressEx(const ZydisDecodedInstruction* instruction,
const ZydisDecodedOperand* operand, ZyanU64 runtime_address,
const ZydisRegisterContext* register_context, ZyanU64* result_address);
/* ---------------------------------------------------------------------------------------------- */
/* Accessed CPU flags */
/* ---------------------------------------------------------------------------------------------- */
/**
* Returns a mask of accessed CPU-flags matching the given `action`.
*
* @param instruction A pointer to the `ZydisDecodedInstruction` struct.
* @param action The CPU-flag action.
* @param flags Receives the flag mask.
*
* @return A zyan status code.
*/
ZYDIS_EXPORT ZyanStatus ZydisGetAccessedFlagsByAction(const ZydisDecodedInstruction* instruction,
ZydisCPUFlagAction action, ZydisCPUFlags* flags);
/**
* Returns a mask of accessed CPU-flags that are read (tested) by the current instruction.
*
* DEPRECATED. This function will be removed in the next major release. Please refer to the
* `cpu_flags_read` or `fpu_flags_read` fields of the `ZydisDecodedInstruction` instead.
*
* @param instruction A pointer to the `ZydisDecodedInstruction` struct.
* @param flags Receives the flag mask.
*
* @return A zyan status code.
*/
ZYDIS_DEPRECATED_EXPORT ZyanStatus ZydisGetAccessedFlagsRead(
const ZydisDecodedInstruction* instruction, ZydisCPUFlags* flags);
/**
* Returns a mask of accessed CPU-flags that are written (modified, undefined) by the current
* instruction.
*
* DEPRECATED. This function will be removed in the next major release. Please refer to the
* `cpu_flags_written` or `fpu_flags_written` fields of the `ZydisDecodedInstruction` instead.
*
* @param instruction A pointer to the `ZydisDecodedInstruction` struct.
* @param flags Receives the flag mask.
*
* @return A zyan status code.
*/
ZYDIS_DEPRECATED_EXPORT ZyanStatus ZydisGetAccessedFlagsWritten(
const ZydisDecodedInstruction* instruction, ZydisCPUFlags* flags);
/* ---------------------------------------------------------------------------------------------- */
/* Instruction segments */
/* ---------------------------------------------------------------------------------------------- */
/**
* Returns offsets and sizes of all logical instruction segments (e.g. `OPCODE`,
* `MODRM`, ...).
*
* @param instruction A pointer to the `ZydisDecodedInstruction` struct.
* @param segments Receives the instruction segments information.
*
* @return A zyan status code.
*/
ZYDIS_EXPORT ZyanStatus ZydisGetInstructionSegments(const ZydisDecodedInstruction* instruction,
ZydisInstructionSegments* segments);
/* ---------------------------------------------------------------------------------------------- */
/**
* @}
*/
/* ============================================================================================== */
#ifdef __cplusplus
}
#endif
WTF_ALLOW_UNSAFE_BUFFER_USAGE_END
#endif /* ZYDIS_UTILS_H */
|