Skip to content

Commit 9aff4d5

Browse files
committed
The ugliest code
It's here!
1 parent 103ba57 commit 9aff4d5

File tree

2 files changed

+315
-17
lines changed

2 files changed

+315
-17
lines changed

Parser.c

+305-17
Original file line numberDiff line numberDiff line change
@@ -106,44 +106,319 @@ int decodeInstructionType(char* instruction, int prefixOffset, ParsedInstruction
106106
return 0;
107107
}
108108

109-
void decodeOperands(char* instruction, int offset, int op16bit, ParsedInstruction* instr_args)
109+
void decodeAndn(char* instruction, int offset, ParsedInstruction* instr_args)
110110
{
111-
unsigned char mod = instruction[offset]>>6;
111+
unsigned char mod = instruction[offset] >> 6;
112112
unsigned char reg = (instruction[offset] & 0b00111000) >> 3;
113113
unsigned char rm = instruction[offset] & 0x07;
114114
unsigned char vvvv = (~(instruction[offset - 1]) >> 3) & 0b00001111;
115115

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)
117121
{
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;
120288
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;
122308
}
123309
else
124310
{
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+
}
126326
}
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;
127334

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)
131348
{
132349
if (op16bit)
133-
instr_args->src1 = rm & 0x10;
350+
instr_args->src1 = rm | 0x10;
134351
else
135352
instr_args->src1 = rm;
353+
instr_args->length = offset;
354+
return;
136355
}
137356

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+
}
139410
}
140411

141412
ParsedInstruction parse(char* instruction)
142413
{
143414
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;
144419
int prefixOffset = 0, length = 0;
145420

146-
prefixOffset = getPrefixes(instruction);
421+
prefixOffset = getPrefix(instruction);
147422

148423
length += prefixOffset;
149424

@@ -152,13 +427,26 @@ ParsedInstruction parse(char* instruction)
152427
if (instr_args.type==INSTR_UNKNOWN)
153428
return instr_args;
154429

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+
156442

157443
return instr_args;
158444
}
159445

160446
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;
164452
}

Parser.h

+10
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,18 @@ typedef struct {
2121
} mem;
2222
} ParsedInstruction;
2323

24+
extern int getPrefix(ParsedInstruction *instruction);
25+
2426
extern int decodeInstructionType(char* instruction, int prefixOffset, ParsedInstruction* instr_args);
2527

28+
extern void decodeAndn(char* instruction, int offset, ParsedInstruction* instr_args);
29+
30+
extern void decodeBextr(char* instruction, int offset, ParsedInstruction* instr_args);
31+
32+
extern void decodeBlsX(char* instruction, int offset, ParsedInstruction* instr_args);
33+
34+
extern void decodeXcnt(char* instruction, int offset, int op16bit, ParsedInstruction* instr_args);
35+
2636
extern ParsedInstruction parse(char* instruction);
2737

2838
extern void* getEffectiveVA(

0 commit comments

Comments
 (0)