@@ -106,44 +106,319 @@ int decodeInstructionType(char* instruction, int prefixOffset, ParsedInstruction
106
106
return 0 ;
107
107
}
108
108
109
- void decodeOperands (char * instruction , int offset , int op16bit , ParsedInstruction * instr_args )
109
+ void decodeAndn (char * instruction , int offset , ParsedInstruction * instr_args )
110
110
{
111
- unsigned char mod = instruction [offset ]>> 6 ;
111
+ unsigned char mod = instruction [offset ] >> 6 ;
112
112
unsigned char reg = (instruction [offset ] & 0b00111000 ) >> 3 ;
113
113
unsigned char rm = instruction [offset ] & 0x07 ;
114
114
unsigned char vvvv = (~(instruction [offset - 1 ]) >> 3 ) & 0b00001111 ;
115
115
116
- if (instr_args -> type == INSTR_POPCNT || instr_args -> type == INSTR_LZCNT || instr_args -> type == INSTR_TZCNT || instr_args -> type == INSTR_BEXTR || instr_args == INSTR_ANDN )
116
+ instr_args -> dest = reg ;
117
+ instr_args -> src1 = vvvv ;
118
+
119
+ //second src is register
120
+ if (mod == 3 )
117
121
{
118
- if (op16bit )
119
- instr_args -> dest = reg & 0x10 ;
122
+ instr_args -> src2 = rm ;
123
+ instr_args -> length = offset ;
124
+ return ;
125
+ }
126
+ //second src is memory
127
+ instr_args -> src2 = MEM_32 ;
128
+ //check the SIB byte
129
+ if (rm == 5 )
130
+ {
131
+ ++ offset ;
132
+ unsigned char ss = instruction [offset ] >> 6 ;
133
+ unsigned char index = (instruction [offset ] & 0b00111000 ) >> 3 ;
134
+ unsigned char base = instruction [offset ] & 0x07 ;
135
+ instr_args -> mem .scale = pow (2 , ss );
136
+ if (index != 5 )
137
+ instr_args -> mem .index = index ;
138
+ else
139
+ instr_args -> mem .index = UNDEF ;
140
+ if (base == 5 && mod == 0 )
141
+ instr_args -> mem .base = UNDEF ;
142
+ else
143
+ instr_args -> mem .base = base ;
144
+ }
145
+ //32 bit displacement
146
+ if (mod == 2 )
147
+ {
148
+ instr_args -> mem .disp = * ((int * )instruction [offset + 1 ]);
149
+ if (rm != 5 )
150
+ instr_args -> mem .index = rm ;
151
+ instr_args -> length = offset + 4 ;
152
+ return ;
153
+ }
154
+ //8 bit displacement
155
+ else if (mod == 1 )
156
+ {
157
+ instr_args -> mem .disp = instruction [offset + 1 ];
158
+ if (rm != 5 )
159
+ instr_args -> mem .index = rm ;
160
+ instr_args -> length = offset + 1 ;
161
+ return ;
162
+ }
163
+ else
164
+ {
165
+ //32 bit displacement without index
166
+ if (rm == 6 )
167
+ {
168
+ instr_args -> mem .index = UNDEF ;
169
+ instr_args -> mem .disp = * ((int * )instruction [offset + 1 ]);
170
+ instr_args -> length = offset + 4 ;
171
+ return ;
172
+ }
173
+ else
174
+ {
175
+ if (rm != 5 )
176
+ instr_args -> mem .index = rm ;
177
+ instr_args -> length = offset ;
178
+ return ;
179
+ }
180
+ }
181
+ }
182
+
183
+ void decodeBextr (char * instruction , int offset , ParsedInstruction * instr_args )
184
+ {
185
+ unsigned char mod = instruction [offset ] >> 6 ;
186
+ unsigned char reg = (instruction [offset ] & 0b00111000 ) >> 3 ;
187
+ unsigned char rm = instruction [offset ] & 0x07 ;
188
+ unsigned char vvvv = (~(instruction [offset - 1 ]) >> 3 ) & 0b00001111 ;
189
+
190
+ instr_args -> dest = reg ;
191
+ instr_args -> src2 = vvvv ;
192
+
193
+ //first src is register
194
+ if (mod == 3 )
195
+ {
196
+ instr_args -> src1 = rm ;
197
+ instr_args -> length = offset ;
198
+ return ;
199
+ }
200
+ //first src is memory
201
+ instr_args -> src1 = MEM_32 ;
202
+ //check the SIB byte
203
+ if (rm == 5 )
204
+ {
205
+ ++ offset ;
206
+ unsigned char ss = instruction [offset ] >> 6 ;
207
+ unsigned char index = (instruction [offset ] & 0b00111000 ) >> 3 ;
208
+ unsigned char base = instruction [offset ] & 0x07 ;
209
+ instr_args -> mem .scale = pow (2 , ss );
210
+ if (index != 5 )
211
+ instr_args -> mem .index = index ;
212
+ else
213
+ instr_args -> mem .index = UNDEF ;
214
+ if (base == 5 && mod == 0 )
215
+ instr_args -> mem .base = UNDEF ;
216
+ else
217
+ instr_args -> mem .base = base ;
218
+ }
219
+ //32 bit displacement
220
+ if (mod == 2 )
221
+ {
222
+ instr_args -> mem .disp = * ((int * )instruction [offset + 1 ]);
223
+ if (rm != 5 )
224
+ instr_args -> mem .index = rm ;
225
+ instr_args -> length = offset + 4 ;
226
+ return ;
227
+ }
228
+ //8 bit displacement
229
+ else if (mod == 1 )
230
+ {
231
+ instr_args -> mem .disp = instruction [offset + 1 ];
232
+ if (rm != 5 )
233
+ instr_args -> mem .index = rm ;
234
+ instr_args -> length = offset + 1 ;
235
+ return ;
236
+ }
237
+ else
238
+ {
239
+ //32 bit displacement without index
240
+ if (rm == 6 )
241
+ {
242
+ instr_args -> mem .index = UNDEF ;
243
+ instr_args -> mem .disp = * ((int * )instruction [offset + 1 ]);
244
+ instr_args -> length = offset + 4 ;
245
+ return ;
246
+ }
247
+ else
248
+ {
249
+ if (rm != 5 )
250
+ instr_args -> mem .index = rm ;
251
+ instr_args -> length = offset ;
252
+ return ;
253
+ }
254
+ }
255
+ }
256
+
257
+ void decodeBlsX (char * instruction , int offset , ParsedInstruction * instr_args )
258
+ {
259
+ unsigned char mod = instruction [offset ] >> 6 ;
260
+ unsigned char rm = instruction [offset ] & 0x07 ;
261
+ unsigned char vvvv = (~(instruction [offset - 1 ]) >> 3 ) & 0b00001111 ;
262
+
263
+ instr_args -> dest = vvvv ;
264
+
265
+ //first src is register
266
+ if (mod == 3 )
267
+ {
268
+ instr_args -> src1 = rm ;
269
+ instr_args -> length = offset ;
270
+ return ;
271
+ }
272
+ //first src is memory
273
+ instr_args -> src1 = MEM_32 ;
274
+ //check the SIB byte
275
+ if (rm == 5 )
276
+ {
277
+ ++ offset ;
278
+ unsigned char ss = instruction [offset ] >> 6 ;
279
+ unsigned char index = (instruction [offset ] & 0b00111000 ) >> 3 ;
280
+ unsigned char base = instruction [offset ] & 0x07 ;
281
+ instr_args -> mem .scale = pow (2 , ss );
282
+ if (index != 5 )
283
+ instr_args -> mem .index = index ;
284
+ else
285
+ instr_args -> mem .index = UNDEF ;
286
+ if (base == 5 && mod == 0 )
287
+ instr_args -> mem .base = UNDEF ;
120
288
else
121
- instr_args -> dest = reg ;
289
+ instr_args -> mem .base = base ;
290
+ }
291
+ //32 bit displacement
292
+ if (mod == 2 )
293
+ {
294
+ instr_args -> mem .disp = * ((int * )instruction [offset + 1 ]);
295
+ if (rm != 5 )
296
+ instr_args -> mem .index = rm ;
297
+ instr_args -> length = offset + 4 ;
298
+ return ;
299
+ }
300
+ //8 bit displacement
301
+ else if (mod == 1 )
302
+ {
303
+ instr_args -> mem .disp = instruction [offset + 1 ];
304
+ if (rm != 5 )
305
+ instr_args -> mem .index = rm ;
306
+ instr_args -> length = offset + 1 ;
307
+ return ;
122
308
}
123
309
else
124
310
{
125
- instr_args -> dest = vvvv ;
311
+ //32 bit displacement without index
312
+ if (rm == 6 )
313
+ {
314
+ instr_args -> mem .index = UNDEF ;
315
+ instr_args -> mem .disp = * ((int * )instruction [offset + 1 ]);
316
+ instr_args -> length = offset + 4 ;
317
+ return ;
318
+ }
319
+ else
320
+ {
321
+ if (rm != 5 )
322
+ instr_args -> mem .index = rm ;
323
+ instr_args -> length = offset ;
324
+ return ;
325
+ }
126
326
}
327
+ }
328
+
329
+ void decodeXcnt (char * instruction , int offset , int op16bit , ParsedInstruction * instr_args )
330
+ {
331
+ unsigned char mod = instruction [offset ] >> 6 ;
332
+ unsigned char reg = (instruction [offset ] & 0b00111000 ) >> 3 ;
333
+ unsigned char rm = instruction [offset ] & 0x07 ;
127
334
128
- if (instr_args -> type == INSTR_ANDN )
129
- instr_args -> src1 = vvvv ;
130
- else if (mod == 3 )
335
+ //adjust the length of registers
336
+ if (op16bit )
337
+ {
338
+ instr_args -> src1 = MEM_16 ;
339
+ reg |= 0x10 ;
340
+ }
341
+ else
342
+ instr_args -> src1 = MEM_32 ;
343
+
344
+ instr_args -> dest = reg ;
345
+
346
+ //first src is register
347
+ if (mod == 3 )
131
348
{
132
349
if (op16bit )
133
- instr_args -> src1 = rm & 0x10 ;
350
+ instr_args -> src1 = rm | 0x10 ;
134
351
else
135
352
instr_args -> src1 = rm ;
353
+ instr_args -> length = offset ;
354
+ return ;
136
355
}
137
356
138
- //TBC - pewnie skonczy sie na refaktoryzacji do postaci funkcji dekodujacych operandy dla kazdej instrukcji oddzielnie
357
+ //check the SIB byte
358
+ if (rm == 5 )
359
+ {
360
+ ++ offset ;
361
+ unsigned char ss = instruction [offset ] >> 6 ;
362
+ unsigned char index = (instruction [offset ] & 0b00111000 ) >> 3 ;
363
+ unsigned char base = instruction [offset ] & 0x07 ;
364
+ instr_args -> mem .scale = pow (2 , ss );
365
+ if (index != 5 )
366
+ instr_args -> mem .index = index ;
367
+ else
368
+ instr_args -> mem .index = UNDEF ;
369
+ if (base == 5 && mod == 0 )
370
+ instr_args -> mem .base = UNDEF ;
371
+ else
372
+ instr_args -> mem .base = base ;
373
+ }
374
+ //32 bit displacement
375
+ if (mod == 2 )
376
+ {
377
+ instr_args -> mem .disp = * ((int * )instruction [offset + 1 ]);
378
+ if (rm != 5 )
379
+ instr_args -> mem .index = rm ;
380
+ instr_args -> length = offset + 4 ;
381
+ return ;
382
+ }
383
+ //8 bit displacement
384
+ else if (mod == 1 )
385
+ {
386
+ instr_args -> mem .disp = instruction [offset + 1 ];
387
+ if (rm != 5 )
388
+ instr_args -> mem .index = rm ;
389
+ instr_args -> length = offset + 1 ;
390
+ return ;
391
+ }
392
+ else
393
+ {
394
+ //32 bit displacement without index
395
+ if (rm == 6 )
396
+ {
397
+ instr_args -> mem .index = UNDEF ;
398
+ instr_args -> mem .disp = * ((int * )instruction [offset + 1 ]);
399
+ instr_args -> length = offset + 4 ;
400
+ return ;
401
+ }
402
+ else
403
+ {
404
+ if (rm != 5 )
405
+ instr_args -> mem .index = rm ;
406
+ instr_args -> length = offset ;
407
+ return ;
408
+ }
409
+ }
139
410
}
140
411
141
412
ParsedInstruction parse (char * instruction )
142
413
{
143
414
ParsedInstruction instr_args ;
415
+ instr_args .mem .base = UNDEF ;
416
+ instr_args .mem .disp = 0 ;
417
+ instr_args .mem .index = UNDEF ;
418
+ instr_args .mem .scale = 1 ;
144
419
int prefixOffset = 0 , length = 0 ;
145
420
146
- prefixOffset = getPrefixes (instruction );
421
+ prefixOffset = getPrefix (instruction );
147
422
148
423
length += prefixOffset ;
149
424
@@ -152,13 +427,26 @@ ParsedInstruction parse(char* instruction)
152
427
if (instr_args .type == INSTR_UNKNOWN )
153
428
return instr_args ;
154
429
155
- decodeOperands (instruction , length , prefixOffset , & instr_args );
430
+ switch (instr_args .type )
431
+ {
432
+ case INSTR_ANDN : decodeAndn (instruction , length , & instr_args ); break ;
433
+ case INSTR_BEXTR : decodeBextr (instruction , length , & instr_args ); break ;
434
+ case INSTR_BLSI : decodeBlsX (instruction , length , & instr_args ); break ;
435
+ case INSTR_BLSMSK : decodeBlsX (instruction , length , & instr_args ); break ;
436
+ case INSTR_BLSR : decodeBlsX (instruction , length , & instr_args ); break ;
437
+ case INSTR_LZCNT : decodeXcnt (instruction , length , prefixOffset , & instr_args ); break ;
438
+ case INSTR_POPCNT : decodeXcnt (instruction , length , prefixOffset , & instr_args ); break ;
439
+ case INSTR_TZCNT : decodeXcnt (instruction , length , prefixOffset , & instr_args ); break ;
440
+ }
441
+
156
442
157
443
return instr_args ;
158
444
}
159
445
160
446
void * getEffectiveVA (struct MemoryArgument mem , CALLER_CONTEXT * context ) {
161
- UNREFERENCED_PARAMETER (mem );
162
- UNREFERENCED_PARAMETER (context );
163
- return NULL ;
447
+ int index = mem .index != UNDEF ? getRegValue (mem .index , context ) : 0 ;
448
+ int scale = mem .scale ;
449
+ int base = mem .base != UNDEF ? getRegValue (mem .base , context ) : 0 ;
450
+ int disp = mem .disp ;
451
+ return index * scale + base + disp ;
164
452
}
0 commit comments