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 #include <Zydis/Internal/String.h> 28 #include <Zydis/FormatterBuffer.h> 29 30 /* ============================================================================================== */ 31 /* Exported functions */ 32 /* ============================================================================================== */ 33 34 /* ---------------------------------------------------------------------------------------------- */ 35 /* Token */ 36 /* ---------------------------------------------------------------------------------------------- */ 37 38 ZyanStatus ZydisFormatterTokenGetValue(const ZydisFormatterToken* token, 39 ZydisTokenType* type, ZyanConstCharPointer* value) 40 { 41 if (!token || !type || !value) 42 { 43 return ZYAN_STATUS_INVALID_ARGUMENT; 44 } 45 46 *type = token->type; 47 *value = (ZyanConstCharPointer)((ZyanU8*)token + sizeof(ZydisFormatterToken)); 48 49 return ZYAN_STATUS_SUCCESS; 50 } 51 52 ZyanStatus ZydisFormatterTokenNext(ZydisFormatterTokenConst** token) 53 { 54 if (!token || !*token) 55 { 56 return ZYAN_STATUS_INVALID_ARGUMENT; 57 } 58 59 const ZyanU8 next = (*token)->next; 60 if (!next) 61 { 62 return ZYAN_STATUS_OUT_OF_RANGE; 63 } 64 *token = (ZydisFormatterTokenConst*)((ZyanU8*)*token + sizeof(ZydisFormatterToken) + next); 65 66 return ZYAN_STATUS_SUCCESS; 67 } 68 69 /* ---------------------------------------------------------------------------------------------- */ 70 /* Buffer */ 71 /* ---------------------------------------------------------------------------------------------- */ 72 73 ZyanStatus ZydisFormatterBufferGetToken(const ZydisFormatterBuffer* buffer, 74 ZydisFormatterTokenConst** token) 75 { 76 if (!buffer || !token) 77 { 78 return ZYAN_STATUS_INVALID_ARGUMENT; 79 } 80 81 *token = ((ZydisFormatterTokenConst*)buffer->string.vector.data - 1); 82 if ((*token)->type == ZYDIS_TOKEN_INVALID) 83 { 84 return ZYAN_STATUS_INVALID_OPERATION; 85 } 86 87 return ZYAN_STATUS_SUCCESS; 88 } 89 90 ZyanStatus ZydisFormatterBufferGetString(ZydisFormatterBuffer* buffer, ZyanString** string) 91 { 92 if (!buffer || !string) 93 { 94 return ZYAN_STATUS_INVALID_ARGUMENT; 95 } 96 97 if (buffer->is_token_list && 98 ((ZydisFormatterTokenConst*)buffer->string.vector.data - 1)->type == ZYDIS_TOKEN_INVALID) 99 { 100 return ZYAN_STATUS_INVALID_OPERATION; 101 } 102 103 ZYAN_ASSERT(buffer->string.vector.data); 104 ZYAN_ASSERT(buffer->string.vector.size); 105 106 *string = &buffer->string; 107 108 return ZYAN_STATUS_SUCCESS; 109 } 110 111 ZyanStatus ZydisFormatterBufferAppend(ZydisFormatterBuffer* buffer, ZydisTokenType type) 112 { 113 if (!buffer) 114 { 115 return ZYAN_STATUS_INVALID_ARGUMENT; 116 } 117 118 if (!buffer->is_token_list) 119 { 120 return ZYAN_STATUS_SUCCESS; 121 } 122 123 const ZyanUSize len = buffer->string.vector.size; 124 ZYAN_ASSERT((len > 0) && (len < 256)); 125 if (buffer->capacity <= len + sizeof(ZydisFormatterToken)) 126 { 127 return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE; 128 } 129 130 ZydisFormatterToken* const last = (ZydisFormatterToken*)buffer->string.vector.data - 1; 131 last->next = (ZyanU8)len; 132 133 const ZyanUSize delta = len + sizeof(ZydisFormatterToken); 134 buffer->capacity -= delta; 135 buffer->string.vector.data = (ZyanU8*)buffer->string.vector.data + delta; 136 buffer->string.vector.size = 1; 137 buffer->string.vector.capacity = ZYAN_MIN(buffer->capacity, 255); 138 *(char*)buffer->string.vector.data = '\0'; 139 140 ZydisFormatterToken* const token = (ZydisFormatterToken*)buffer->string.vector.data - 1; 141 token->type = type; 142 token->next = 0; 143 144 return ZYAN_STATUS_SUCCESS; 145 } 146 147 ZyanStatus ZydisFormatterBufferRemember(const ZydisFormatterBuffer* buffer, ZyanUPointer* state) 148 { 149 if (!buffer || !state) 150 { 151 return ZYAN_STATUS_INVALID_ARGUMENT; 152 } 153 154 if (buffer->is_token_list) 155 { 156 *state = (ZyanUPointer)buffer->string.vector.data; 157 } else 158 { 159 *state = (ZyanUPointer)buffer->string.vector.size; 160 } 161 162 return ZYAN_STATUS_SUCCESS; 163 } 164 165 ZyanStatus ZydisFormatterBufferRestore(ZydisFormatterBuffer* buffer, ZyanUPointer state) 166 { 167 if (!buffer) 168 { 169 return ZYAN_STATUS_INVALID_ARGUMENT; 170 } 171 172 if (buffer->is_token_list) 173 { 174 const ZyanUSize delta = (ZyanUPointer)buffer->string.vector.data - state; 175 buffer->capacity += delta; 176 buffer->string.vector.data = (void*)state; 177 buffer->string.vector.size = 1; // TODO: Restore size? 178 buffer->string.vector.capacity = ZYAN_MIN(buffer->capacity, 255); 179 *(char*)buffer->string.vector.data = '\0'; 180 } else 181 { 182 buffer->string.vector.size = (ZyanUSize)state; 183 ZYDIS_STRING_NULLTERMINATE(&buffer->string); 184 } 185 186 return ZYAN_STATUS_SUCCESS; 187 } 188 189 /* ---------------------------------------------------------------------------------------------- */ 190 191 /* ============================================================================================== */ 192