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 * Implements the `ZydisFormatterToken` type and provides functions to use it. 30 */ 31 32 #ifndef ZYDIS_FORMATTER_TOKEN_H 33 #define ZYDIS_FORMATTER_TOKEN_H 34 35 #include <Zycore/String.h> 36 #include <Zycore/Types.h> 37 #include <Zydis/Defines.h> 38 #include <Zydis/Status.h> 39 40 #ifdef __cplusplus 41 extern "C" { 42 #endif 43 44 /* ============================================================================================== */ 45 /* Constants */ 46 /* ============================================================================================== */ 47 48 /* ---------------------------------------------------------------------------------------------- */ 49 /* Token types */ 50 /* ---------------------------------------------------------------------------------------------- */ 51 52 /** 53 * Defines the `ZydisTokenType` data-type. 54 */ 55 typedef ZyanU8 ZydisTokenType; 56 57 #define ZYDIS_TOKEN_INVALID 0x00 58 /** 59 * A whitespace character. 60 */ 61 #define ZYDIS_TOKEN_WHITESPACE 0x01 62 /** 63 * A delimiter character (like `','`, `':'`, `'+'`, `'-'`, `'*'`). 64 */ 65 #define ZYDIS_TOKEN_DELIMITER 0x02 66 /** 67 * An opening parenthesis character (like `'('`, `'['`, `'{'`). 68 */ 69 #define ZYDIS_TOKEN_PARENTHESIS_OPEN 0x03 70 /** 71 * A closing parenthesis character (like `')'`, `']'`, `'}'`). 72 */ 73 #define ZYDIS_TOKEN_PARENTHESIS_CLOSE 0x04 74 /** 75 * A prefix literal (like `"LOCK"`, `"REP"`). 76 */ 77 #define ZYDIS_TOKEN_PREFIX 0x05 78 /** 79 * A mnemonic literal (like `"MOV"`, `"VCMPPSD"`, `"LCALL"`). 80 */ 81 #define ZYDIS_TOKEN_MNEMONIC 0x06 82 /** 83 * A register literal (like `"RAX"`, `"DS"`, `"%ECX"`). 84 */ 85 #define ZYDIS_TOKEN_REGISTER 0x07 86 /** 87 * An absolute address literal (like `0x00400000`). 88 */ 89 #define ZYDIS_TOKEN_ADDRESS_ABS 0x08 90 /** 91 * A relative address literal (like `-0x100`). 92 */ 93 #define ZYDIS_TOKEN_ADDRESS_REL 0x09 94 /** 95 * A displacement literal (like `0xFFFFFFFF`, `-0x100`, `+0x1234`). 96 */ 97 #define ZYDIS_TOKEN_DISPLACEMENT 0x0A 98 /** 99 * An immediate literal (like `0xC0`, `-0x1234`, `$0x0000`). 100 */ 101 #define ZYDIS_TOKEN_IMMEDIATE 0x0B 102 /** 103 * A typecast literal (like `DWORD PTR`). 104 */ 105 #define ZYDIS_TOKEN_TYPECAST 0x0C 106 /** 107 * A decorator literal (like `"Z"`, `"1TO4"`). 108 */ 109 #define ZYDIS_TOKEN_DECORATOR 0x0D 110 /** 111 * A symbol literal. 112 */ 113 #define ZYDIS_TOKEN_SYMBOL 0x0E 114 115 /** 116 * The base for user-defined token types. 117 */ 118 #define ZYDIS_TOKEN_USER 0x80 119 120 /* ---------------------------------------------------------------------------------------------- */ 121 122 /* ============================================================================================== */ 123 /* Enums and types */ 124 /* ============================================================================================== */ 125 126 /* ---------------------------------------------------------------------------------------------- */ 127 /* Token */ 128 /* ---------------------------------------------------------------------------------------------- */ 129 130 #if !defined(__HAIKU__) || (defined(__GNUC__) && (__GNUC__ >= 4)) 131 #pragma pack(push, 1) 132 #endif 133 134 /** 135 * Defines the `ZydisFormatterToken` struct. 136 * 137 * All fields in this struct should be considered as "private". Any changes may lead to unexpected 138 * behavior. 139 */ 140 typedef struct ZydisFormatterToken_ 141 { 142 /** 143 * The token type. 144 */ 145 ZydisTokenType type; 146 /** 147 * An offset to the next token, or `0`. 148 */ 149 ZyanU8 next; 150 } ZydisFormatterToken; 151 152 #if !defined(__HAIKU__) || (defined(__GNUC__) && (__GNUC__ >= 4)) 153 #pragma pack(pop) 154 #endif 155 156 /** 157 * Defines the `ZydisFormatterTokenConst` data-type. 158 */ 159 typedef const ZydisFormatterToken ZydisFormatterTokenConst; 160 161 /* ---------------------------------------------------------------------------------------------- */ 162 /* Buffer */ 163 /* ---------------------------------------------------------------------------------------------- */ 164 165 /** 166 * Defines the `ZydisFormatterBuffer` struct. 167 * 168 * All fields in this struct should be considered as "private". Any changes may 169 * lead to unexpected behavior. 170 */ 171 typedef struct ZydisFormatterBuffer_ 172 { 173 /** 174 * `ZYAN_TRUE`, if the buffer contains a token stream or `ZYAN_FALSE, if it 175 * contains a simple string. 176 */ 177 ZyanBool is_token_list; 178 /** 179 * The remaining capacity of the buffer. 180 */ 181 ZyanUSize capacity; 182 /** 183 * The `ZyanString` instance that refers to the literal value of the most 184 * recently added token. 185 */ 186 ZyanString string; 187 } ZydisFormatterBuffer; 188 189 /* ---------------------------------------------------------------------------------------------- */ 190 191 /* ============================================================================================== */ 192 /* Exported functions */ 193 /* ============================================================================================== */ 194 195 /* ---------------------------------------------------------------------------------------------- */ 196 /* Token */ 197 /* ---------------------------------------------------------------------------------------------- */ 198 199 /** 200 * Returns the `type` and the string `value` of the given `token`. 201 * 202 * @param token A pointer to the `ZydisFormatterToken` struct. 203 * @param type Receives the token type. 204 * @param value Receives a pointer to the string value of the token. 205 * 206 * @return A zyan status code. 207 */ 208 ZYDIS_EXPORT ZyanStatus ZydisFormatterTokenGetValue(const ZydisFormatterToken* token, 209 ZydisTokenType* type, ZyanConstCharPointer* value); 210 211 /** 212 * Obtains the next `token` linked to the passed one. 213 * 214 * @param token Receives a pointer to the next `ZydisFormatterToken` struct 215 * linked to the passed one. 216 * 217 * @return A zyan status code. 218 */ 219 ZYDIS_EXPORT ZyanStatus ZydisFormatterTokenNext(ZydisFormatterTokenConst** token); 220 221 /* ---------------------------------------------------------------------------------------------- */ 222 /* Buffer */ 223 /* ---------------------------------------------------------------------------------------------- */ 224 225 /** 226 * Returns the current (most recently added) token. 227 * 228 * @param buffer A pointer to the `ZydisFormatterBuffer` struct. 229 * @param token Receives a pointer to the current token. 230 * 231 * @return A zyan status code. 232 * 233 * This function returns `ZYAN_STATUS_INVALID_OPERATION`, if the buffer does not contain at least 234 * one token. 235 */ 236 ZYDIS_EXPORT ZyanStatus ZydisFormatterBufferGetToken(const ZydisFormatterBuffer* buffer, 237 ZydisFormatterTokenConst** token); 238 239 /** 240 * Returns the `ZyanString` instance associated with the given buffer. 241 * 242 * @param buffer A pointer to the `ZydisFormatterBuffer` struct. 243 * @param string Receives a pointer to the `ZyanString` instance associated with the given 244 * buffer. 245 * 246 * @return A zyan status code. 247 * 248 * This function returns `ZYAN_STATUS_INVALID_OPERATION`, if the buffer does not contain at least 249 * one token. 250 * 251 * The returned string always refers to the literal value of the current (most recently added) 252 * token and will remain valid until the buffer is destroyed. 253 */ 254 ZYDIS_EXPORT ZyanStatus ZydisFormatterBufferGetString(ZydisFormatterBuffer* buffer, 255 ZyanString** string); 256 257 /** 258 * Appends a new token to the `buffer`. 259 * 260 * @param buffer A pointer to the `ZydisFormatterBuffer` struct. 261 * @param type The type of the new token. 262 * 263 * @return A zyan status code. 264 * 265 * Note that the `ZyanString` instance returned by `ZydisFormatterBufferGetString` will 266 * automatically be updated by calling this function. 267 */ 268 ZYDIS_EXPORT ZyanStatus ZydisFormatterBufferAppend(ZydisFormatterBuffer* buffer, 269 ZydisTokenType type); 270 271 /** 272 * Returns a snapshot of the buffer-state. 273 * 274 * @param buffer A pointer to the `ZydisFormatterBuffer` struct. 275 * @param state Receives a snapshot of the buffer-state. 276 * 277 * @return A zyan status code. 278 * 279 * Note that the buffer-state is saved inside the buffer itself and thus becomes invalid as soon 280 * as the buffer gets overwritten or destroyed. 281 */ 282 ZYDIS_EXPORT ZyanStatus ZydisFormatterBufferRemember(const ZydisFormatterBuffer* buffer, 283 ZyanUPointer* state); 284 285 /** 286 * Restores a previously saved buffer-state. 287 * 288 * @param buffer A pointer to the `ZydisFormatterBuffer` struct. 289 * @param state The buffer-state to restore. 290 * 291 * @return A zyan status code. 292 * 293 * All tokens added after obtaining the given `state` snapshot will be removed. This function 294 * does NOT restore any string content. 295 * 296 * Note that the `ZyanString` instance returned by `ZydisFormatterBufferGetString` will 297 * automatically be updated by calling this function. 298 */ 299 ZYDIS_EXPORT ZyanStatus ZydisFormatterBufferRestore(ZydisFormatterBuffer* buffer, 300 ZyanUPointer state); 301 302 /* ---------------------------------------------------------------------------------------------- */ 303 304 /* ============================================================================================== */ 305 306 #ifdef __cplusplus 307 } 308 #endif 309 310 #endif /* ZYDIS_FORMATTER_TOKEN_H */ 311