FormatterBuffer.h (10860B)
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 #pragma pack(push, 1) 131 132 /** 133 * Defines the `ZydisFormatterToken` struct. 134 * 135 * All fields in this struct should be considered as "private". Any changes may lead to unexpected 136 * behavior. 137 */ 138 typedef struct ZydisFormatterToken_ 139 { 140 /** 141 * The token type. 142 */ 143 ZydisTokenType type; 144 /** 145 * An offset to the next token, or `0`. 146 */ 147 ZyanU8 next; 148 } ZydisFormatterToken; 149 150 #pragma pack(pop) 151 152 /** 153 * Defines the `ZydisFormatterTokenConst` data-type. 154 */ 155 typedef const ZydisFormatterToken ZydisFormatterTokenConst; 156 157 /* ---------------------------------------------------------------------------------------------- */ 158 /* Buffer */ 159 /* ---------------------------------------------------------------------------------------------- */ 160 161 /** 162 * Defines the `ZydisFormatterBuffer` struct. 163 * 164 * All fields in this struct should be considered as "private". Any changes may 165 * lead to unexpected behavior. 166 */ 167 typedef struct ZydisFormatterBuffer_ 168 { 169 /** 170 * `ZYAN_TRUE`, if the buffer contains a token stream or `ZYAN_FALSE, if it 171 * contains a simple string. 172 */ 173 ZyanBool is_token_list; 174 /** 175 * The remaining capacity of the buffer. 176 */ 177 ZyanUSize capacity; 178 /** 179 * The `ZyanString` instance that refers to the literal value of the most 180 * recently added token. 181 */ 182 ZyanString string; 183 } ZydisFormatterBuffer; 184 185 /* ---------------------------------------------------------------------------------------------- */ 186 187 /* ============================================================================================== */ 188 /* Exported functions */ 189 /* ============================================================================================== */ 190 191 /* ---------------------------------------------------------------------------------------------- */ 192 /* Token */ 193 /* ---------------------------------------------------------------------------------------------- */ 194 195 /** 196 * Returns the `type` and the string `value` of the given `token`. 197 * 198 * @param token A pointer to the `ZydisFormatterToken` struct. 199 * @param type Receives the token type. 200 * @param value Receives a pointer to the string value of the token. 201 * 202 * @return A zyan status code. 203 */ 204 ZYDIS_EXPORT ZyanStatus ZydisFormatterTokenGetValue(const ZydisFormatterToken* token, 205 ZydisTokenType* type, ZyanConstCharPointer* value); 206 207 /** 208 * Obtains the next `token` linked to the passed one. 209 * 210 * @param token Receives a pointer to the next `ZydisFormatterToken` struct 211 * linked to the passed one. 212 * 213 * @return A zyan status code. 214 */ 215 ZYDIS_EXPORT ZyanStatus ZydisFormatterTokenNext(ZydisFormatterTokenConst** token); 216 217 /* ---------------------------------------------------------------------------------------------- */ 218 /* Buffer */ 219 /* ---------------------------------------------------------------------------------------------- */ 220 221 /** 222 * Returns the current (most recently added) token. 223 * 224 * @param buffer A pointer to the `ZydisFormatterBuffer` struct. 225 * @param token Receives a pointer to the current token. 226 * 227 * @return A zyan status code. 228 * 229 * This function returns `ZYAN_STATUS_INVALID_OPERATION`, if the buffer does not contain at least 230 * one token. 231 */ 232 ZYDIS_EXPORT ZyanStatus ZydisFormatterBufferGetToken(const ZydisFormatterBuffer* buffer, 233 ZydisFormatterTokenConst** token); 234 235 /** 236 * Returns the `ZyanString` instance associated with the given buffer. 237 * 238 * @param buffer A pointer to the `ZydisFormatterBuffer` struct. 239 * @param string Receives a pointer to the `ZyanString` instance associated with the given 240 * buffer. 241 * 242 * @return A zyan status code. 243 * 244 * This function returns `ZYAN_STATUS_INVALID_OPERATION`, if the buffer does not contain at least 245 * one token. 246 * 247 * The returned string always refers to the literal value of the current (most recently added) 248 * token and will remain valid until the buffer is destroyed. 249 */ 250 ZYDIS_EXPORT ZyanStatus ZydisFormatterBufferGetString(ZydisFormatterBuffer* buffer, 251 ZyanString** string); 252 253 /** 254 * Appends a new token to the `buffer`. 255 * 256 * @param buffer A pointer to the `ZydisFormatterBuffer` struct. 257 * @param type The type of the new token. 258 * 259 * @return A zyan status code. 260 * 261 * Note that the `ZyanString` instance returned by `ZydisFormatterBufferGetString` will 262 * automatically be updated by calling this function. 263 */ 264 ZYDIS_EXPORT ZyanStatus ZydisFormatterBufferAppend(ZydisFormatterBuffer* buffer, 265 ZydisTokenType type); 266 267 /** 268 * Returns a snapshot of the buffer-state. 269 * 270 * @param buffer A pointer to the `ZydisFormatterBuffer` struct. 271 * @param state Receives a snapshot of the buffer-state. 272 * 273 * @return A zyan status code. 274 * 275 * Note that the buffer-state is saved inside the buffer itself and thus becomes invalid as soon 276 * as the buffer gets overwritten or destroyed. 277 */ 278 ZYDIS_EXPORT ZyanStatus ZydisFormatterBufferRemember(const ZydisFormatterBuffer* buffer, 279 ZyanUPointer* state); 280 281 /** 282 * Restores a previously saved buffer-state. 283 * 284 * @param buffer A pointer to the `ZydisFormatterBuffer` struct. 285 * @param state The buffer-state to restore. 286 * 287 * @return A zyan status code. 288 * 289 * All tokens added after obtaining the given `state` snapshot will be removed. This function 290 * does NOT restore any string content. 291 * 292 * Note that the `ZyanString` instance returned by `ZydisFormatterBufferGetString` will 293 * automatically be updated by calling this function. 294 */ 295 ZYDIS_EXPORT ZyanStatus ZydisFormatterBufferRestore(ZydisFormatterBuffer* buffer, 296 ZyanUPointer state); 297 298 /* ---------------------------------------------------------------------------------------------- */ 299 300 /* ============================================================================================== */ 301 302 #ifdef __cplusplus 303 } 304 #endif 305 306 #endif /* ZYDIS_FORMATTER_TOKEN_H */