Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


additions for syscall hijacking
[palacios.git] / palacios / src / palacios / vmm_v3dec.c
1 /* 
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
11  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20 #include <palacios/vmm_decoder.h>
21 #include <palacios/vmm_instr_decoder.h>
22
23 #ifndef CONFIG_DEBUG_DECODER
24 #undef PrintDebug
25 #define PrintDebug(fmt, args...)
26 #endif
27
28
29 #define MASK(val, length) ({                                            \
30             uint64_t mask = 0x0LL;                                      \
31             switch (length) {                                           \
32                 case 1:                                                 \
33                     mask = 0x00000000000000ffLL;                        \
34                     break;                                              \
35                 case 2:                                                 \
36                     mask = 0x000000000000ffffLL;                        \
37                     break;                                              \
38                 case 4:                                                 \
39                     mask = 0x00000000ffffffffLL;                        \
40                     break;                                              \
41                 case 8:                                                 \
42                     mask = 0xffffffffffffffffLL;                        \
43                     break;                                              \
44             }                                                           \
45             val & mask;                                                 \
46         })
47
48 static v3_op_type_t op_form_to_type(op_form_t form);
49 static int parse_operands(struct guest_info * core, uint8_t * instr_ptr, struct x86_instr * instr, op_form_t form);
50
51
52 int v3_disasm(struct guest_info * info, void *instr_ptr, addr_t * rip, int mark) {
53     return -1;
54 }
55
56
57 int v3_init_decoder(struct guest_info * core) { 
58     return 0;
59 }
60
61
62 int v3_deinit_decoder(struct guest_info * core) {
63     return 0;
64 }
65
66
67 int v3_encode(struct guest_info * info, struct x86_instr * instr, uint8_t * instr_buf) {
68     return -1;
69 }
70
71
72 int v3_decode(struct guest_info * core, addr_t instr_ptr, struct x86_instr * instr) {
73     op_form_t form = INVALID_INSTR; 
74     int ret = 0;
75     int length = 0;
76
77
78     V3_Print("Decoding Instruction at %p\n", (void *)instr_ptr);
79
80     memset(instr, 0, sizeof(struct x86_instr));
81
82     // scan for prefixes
83     length = v3_get_prefixes((uint8_t *)instr_ptr, &(instr->prefixes));
84
85
86     // REX prefix
87     if (v3_get_vm_cpu_mode(core) == LONG) {
88         uint8_t prefix = *(uint8_t *)(instr_ptr + length);
89
90         if ((prefix & 0xf0) == 0x40) {
91             instr->prefixes.rex = 1;
92
93             instr->prefixes.rex_rm = (prefix & 0x01);
94             instr->prefixes.rex_sib_idx = ((prefix & 0x02) >> 1);
95             instr->prefixes.rex_reg = ((prefix & 0x04) >> 2);
96             instr->prefixes.rex_op_size = ((prefix & 0x08) >> 3);
97
98             length += 1;
99         }
100     }
101
102
103     form = op_code_to_form((uint8_t *)(instr_ptr + length), &length);
104
105     V3_Print("\t decoded as (%s)\n", op_form_to_str(form));
106
107     if (form == INVALID_INSTR) {
108         PrintError("Could not find instruction form (%x)\n", *(uint32_t *)(instr_ptr + length));
109         return -1;
110     }
111
112     instr->op_type = op_form_to_type(form);
113
114     ret = parse_operands(core, (uint8_t *)(instr_ptr + length), instr, form);
115
116     if (ret == -1) {
117         PrintError("Could not parse instruction operands\n");
118         return -1;
119     }
120     length += ret;
121
122     instr->instr_length += length;
123
124     v3_print_instr(instr);
125
126     return 0;
127 }
128
129
130 static int parse_operands(struct guest_info * core, uint8_t * instr_ptr, 
131                           struct x86_instr * instr, op_form_t form) {
132     // get operational mode of the guest for operand width
133     uint8_t operand_width = get_operand_width(core, instr, form);
134     uint8_t addr_width = get_addr_width(core, instr);
135     int ret = 0;
136     uint8_t * instr_start = instr_ptr;
137     
138
139     PrintDebug("\tOperand width=%d, Addr width=%d\n", operand_width, addr_width);
140
141     switch (form) {
142         case ADC_IMM2_8:
143         case ADD_IMM2_8:
144         case AND_IMM2_8:
145         case OR_IMM2_8:
146         case SUB_IMM2_8:
147         case XOR_IMM2_8:
148         case MOV_IMM2_8:
149         case ADC_IMM2:
150         case ADD_IMM2:
151         case AND_IMM2:  
152         case OR_IMM2:
153         case SUB_IMM2:
154         case XOR_IMM2: 
155         case MOV_IMM2:{
156             uint8_t reg_code = 0;
157
158             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand), &reg_code);
159
160             if (ret == -1) {
161                 PrintError("Error decoding operand\n");
162                 return -1;
163             }
164
165             instr_ptr += ret;
166
167             instr->src_operand.type = IMM_OPERAND;
168             instr->src_operand.size = operand_width;
169
170
171             if (operand_width == 1) {
172                 instr->src_operand.operand = *(uint8_t *)instr_ptr;
173             } else if (operand_width == 2) {
174                 instr->src_operand.operand = *(uint16_t *)instr_ptr;
175             } else if (operand_width == 4) {
176                 instr->src_operand.operand = *(uint32_t *)instr_ptr;
177             } else {
178                 PrintError("Illegal operand width (%d)\n", operand_width);
179                 return -1;
180             }
181
182             instr->src_operand.read = 1;
183             instr->dst_operand.write = 1;
184
185             instr_ptr += operand_width;
186
187             instr->num_operands = 2;
188
189             break;
190         }
191         case ADC_2MEM_8:
192         case ADD_2MEM_8:
193         case AND_2MEM_8:
194         case OR_2MEM_8:
195         case SUB_2MEM_8:
196         case XOR_2MEM_8:
197         case MOV_2MEM_8:
198         case ADC_2MEM:
199         case ADD_2MEM:
200         case AND_2MEM:
201         case OR_2MEM:
202         case SUB_2MEM:
203         case XOR_2MEM:
204         case MOV_2MEM: {
205             uint8_t reg_code = 0;
206
207             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand), &reg_code);
208
209             if (ret == -1) {
210                 PrintError("Error decoding operand\n");
211                 return -1;
212             }
213
214             instr_ptr += ret;
215
216             instr->src_operand.type = REG_OPERAND;
217             instr->src_operand.size = operand_width;
218
219             instr->src_operand.read = 1;
220             instr->dst_operand.write = 1;
221
222
223             decode_gpr(core, reg_code, &(instr->src_operand));
224
225             instr->num_operands = 2;
226             break;
227         }
228         case ADC_MEM2_8:
229         case ADD_MEM2_8:
230         case AND_MEM2_8:
231         case OR_MEM2_8:
232         case SUB_MEM2_8:
233         case XOR_MEM2_8:
234         case MOV_MEM2_8:
235         case ADC_MEM2:
236         case ADD_MEM2:
237         case AND_MEM2:
238         case OR_MEM2:
239         case SUB_MEM2:
240         case XOR_MEM2:
241         case MOV_MEM2: {
242             uint8_t reg_code = 0;
243
244             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->src_operand), &reg_code);
245
246             if (ret == -1) {
247                 PrintError("Error decoding operand\n");
248                 return -1;
249             }
250
251             instr_ptr += ret;
252
253             instr->dst_operand.size = operand_width;
254             instr->dst_operand.type = REG_OPERAND;
255             decode_gpr(core, reg_code, &(instr->dst_operand));
256
257             instr->src_operand.read = 1;
258             instr->dst_operand.write = 1;
259
260             instr->num_operands = 2;
261
262             break;
263         }
264         case MOVSX_8:
265         case MOVZX_8: {
266             uint8_t reg_code = 0;
267
268             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->src_operand), &reg_code);
269             instr->src_operand.size = 1;
270
271             if (ret == -1) {
272                 PrintError("Error decoding operand\n");
273                 return -1;
274             }
275
276             instr_ptr += ret;
277
278             instr->dst_operand.size = operand_width;
279             instr->dst_operand.type = REG_OPERAND;
280             decode_gpr(core, reg_code, &(instr->dst_operand));
281
282             instr->src_operand.read = 1;
283             instr->dst_operand.write = 1;
284
285             instr->num_operands = 2;
286
287             break;
288         }
289         case MOVSX:
290         case MOVZX: {
291             uint8_t reg_code = 0;
292
293             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->src_operand), &reg_code);
294             instr->src_operand.size = 2;
295
296             if (ret == -1) {
297                 PrintError("Error decoding operand\n");
298                 return -1;
299             }
300
301             instr_ptr += ret;
302
303             instr->dst_operand.size = operand_width;
304             instr->dst_operand.type = REG_OPERAND;
305             decode_gpr(core, reg_code, &(instr->dst_operand));
306
307             instr->src_operand.read = 1;
308             instr->dst_operand.write = 1;
309
310             instr->num_operands = 2;
311
312             break;
313         }
314         case ADC_IMM2SX_8:
315         case ADD_IMM2SX_8:
316         case AND_IMM2SX_8:
317         case OR_IMM2SX_8:
318         case SUB_IMM2SX_8:
319         case XOR_IMM2SX_8: {
320             uint8_t reg_code = 0;
321
322             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand), &reg_code);
323
324             if (ret == -1) {
325                 PrintError("Error decoding operand\n");
326                 return -1;
327             }
328
329             instr_ptr += ret;
330
331             instr->src_operand.type = IMM_OPERAND;
332             instr->src_operand.size = operand_width;
333             instr->src_operand.operand = (addr_t)MASK((sint64_t)*(sint8_t *)instr_ptr, operand_width);  // sign extend.
334
335             instr->src_operand.read = 1;
336             instr->dst_operand.write = 1;
337
338             instr_ptr += 1;
339
340             instr->num_operands = 2;
341
342             break;
343         }
344         case MOVS:
345         case MOVS_8: {
346             instr->is_str_op = 1;
347             
348             if (instr->prefixes.rep == 1) {
349                 instr->str_op_length = MASK(core->vm_regs.rcx, operand_width);
350             } else {
351                 instr->str_op_length = 1;
352             }
353
354             // Source: DS:(E)SI
355             // Destination: ES:(E)DI
356
357             instr->src_operand.type = MEM_OPERAND;
358             instr->src_operand.size = operand_width;
359             instr->src_operand.operand = get_addr_linear(core,  MASK(core->vm_regs.rsi, addr_width), &(core->segments.ds));
360
361
362             instr->dst_operand.type = MEM_OPERAND;
363             instr->dst_operand.size = operand_width;
364             instr->dst_operand.operand = get_addr_linear(core, MASK(core->vm_regs.rdi, addr_width), &(core->segments.es));
365
366
367             instr->src_operand.read = 1;
368             instr->dst_operand.write = 1;
369
370             instr->num_operands = 2;
371
372             break;
373         }
374         case MOV_2CR: {
375             uint8_t reg_code = 0;
376             
377             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->src_operand),
378                                     &reg_code);
379
380             if (ret == -1) {
381                 PrintError("Error decoding operand for (%s)\n", op_form_to_str(form));
382                 return -1;
383             }
384                 
385             instr_ptr += ret;
386
387             instr->dst_operand.type = REG_OPERAND;
388             instr->dst_operand.size = operand_width;
389             decode_cr(core, reg_code, &(instr->dst_operand));
390             
391             instr->src_operand.read = 1;
392             instr->dst_operand.write = 1;
393
394             instr->num_operands = 2;
395             break;
396         }
397         case MOV_CR2: {
398             uint8_t reg_code = 0;
399             
400             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand),
401                                     &reg_code);
402             
403             if (ret == -1) {
404                 PrintError("Error decoding operand for (%s)\n", op_form_to_str(form));
405                 return -1;
406             }
407
408             instr_ptr += ret;
409             
410             instr->src_operand.type = REG_OPERAND;
411             instr->src_operand.size = operand_width;
412             decode_cr(core, reg_code, &(instr->src_operand));
413
414             instr->src_operand.read = 1;
415             instr->dst_operand.write = 1;
416
417             instr->num_operands = 2;
418             break;
419         }
420         case STOS:
421         case STOS_8: {
422             instr->is_str_op = 1;
423
424             if (instr->prefixes.rep == 1) {
425                 instr->str_op_length = MASK(core->vm_regs.rcx, operand_width);
426             } else {
427                 instr->str_op_length = 1;
428             }
429
430             instr->src_operand.size = operand_width;
431             instr->src_operand.type = REG_OPERAND;
432             instr->src_operand.operand = (addr_t)&(core->vm_regs.rax);
433
434             instr->dst_operand.type = MEM_OPERAND;
435             instr->dst_operand.size = operand_width;
436             instr->dst_operand.operand = get_addr_linear(core, MASK(core->vm_regs.rdi, addr_width), &(core->segments.es));
437
438             instr->src_operand.read = 1;
439             instr->dst_operand.write = 1;
440
441             instr->num_operands = 2;
442
443             break;
444         }
445         case INVLPG: {
446             uint8_t reg_code = 0;
447             
448             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand), &reg_code);
449             
450             if (ret == -1) {
451                 PrintError("Error decoding operand for (%s)\n", op_form_to_str(form));
452                 return -1;
453             }
454             
455             instr_ptr += ret;
456             
457             instr->num_operands = 1;
458             break;
459         }
460         case CLTS: {
461             // no operands. 
462             break;
463             
464         }
465         default:
466             PrintError("Invalid Instruction form: %s\n", op_form_to_str(form));
467             return -1;
468     }
469
470     return (instr_ptr - instr_start);
471 }
472
473
474 static v3_op_type_t op_form_to_type(op_form_t form) { 
475     switch (form) {
476         case LMSW:
477             return V3_OP_LMSW;
478         case SMSW:
479             return V3_OP_SMSW;
480         case CLTS:
481             return V3_OP_CLTS;
482         case INVLPG:
483             return V3_OP_INVLPG;
484
485         case MOV_CR2:
486             return V3_OP_MOVCR2;
487         case MOV_2CR:
488             return V3_OP_MOV2CR;
489
490     // KCH: for syscall interposition
491     case INT:
492         return V3_OP_INT;
493
494
495         case MOV_MEM2_8:
496         case MOV_MEM2:
497         case MOV_2MEM_8:
498         case MOV_2MEM:
499         case MOV_MEM2AL_8:
500         case MOV_MEM2AX:
501         case MOV_AL2MEM_8:
502         case MOV_AX2MEM:
503         case MOV_IMM2_8:
504         case MOV_IMM2:
505             return V3_OP_MOV;
506
507         case MOVS_8:
508         case MOVS:
509             return V3_OP_MOVS;
510
511         case MOVSX_8:
512         case MOVSX:
513             return V3_OP_MOVSX;
514
515         case MOVZX_8:
516         case MOVZX:
517             return V3_OP_MOVZX;
518
519
520             
521         case ADC_2MEM_8:
522         case ADC_2MEM:
523         case ADC_MEM2_8:
524         case ADC_MEM2:
525         case ADC_IMM2_8:
526         case ADC_IMM2:
527         case ADC_IMM2SX_8:
528             return V3_OP_ADC;
529
530
531         case ADD_2MEM_8:
532         case ADD_2MEM:
533         case ADD_MEM2_8:
534         case ADD_MEM2:
535         case ADD_IMM2_8:
536         case ADD_IMM2:
537         case ADD_IMM2SX_8:
538             return V3_OP_ADD;
539
540         case AND_MEM2_8:
541         case AND_MEM2:
542         case AND_2MEM_8:
543         case AND_2MEM:
544         case AND_IMM2_8:
545         case AND_IMM2:
546         case AND_IMM2SX_8:
547             return V3_OP_AND;
548
549         case OR_2MEM_8:
550         case OR_2MEM:
551         case OR_MEM2_8:
552         case OR_MEM2:
553         case OR_IMM2_8:
554         case OR_IMM2:
555         case OR_IMM2SX_8:
556             return V3_OP_OR;
557
558         case SUB_2MEM_8:
559         case SUB_2MEM:
560         case SUB_MEM2_8:
561         case SUB_MEM2:
562         case SUB_IMM2_8:
563         case SUB_IMM2:
564         case SUB_IMM2SX_8:
565             return V3_OP_SUB;
566
567         case XOR_2MEM_8:
568         case XOR_2MEM:
569         case XOR_MEM2_8:
570         case XOR_MEM2:
571         case XOR_IMM2_8:
572         case XOR_IMM2:
573         case XOR_IMM2SX_8:
574             return V3_OP_XOR;
575
576         case INC_8:
577         case INC:
578             return V3_OP_INC;
579
580         case DEC_8:
581         case DEC:
582             return V3_OP_DEC;
583
584         case NEG_8:
585         case NEG: 
586             return V3_OP_NEG;
587
588         case NOT_8:
589         case NOT:
590             return V3_OP_NOT;
591
592         case XCHG_8:
593         case XCHG:
594             return V3_OP_XCHG;
595             
596         case SETB:
597             return V3_OP_SETB;
598         case SETBE:
599             return V3_OP_SETBE;
600         case SETL:
601             return V3_OP_SETL;
602         case SETLE:
603             return V3_OP_SETLE;
604         case SETNB:
605             return V3_OP_SETNB;
606         case SETNBE:
607             return V3_OP_SETNBE;
608         case SETNL:
609             return V3_OP_SETNL;
610         case SETNLE:
611             return V3_OP_SETNLE;
612         case SETNO:
613             return V3_OP_SETNO;
614         case SETNP:
615             return V3_OP_SETNP;
616         case SETNS:
617             return V3_OP_SETNS;
618         case SETNZ:
619             return V3_OP_SETNZ;
620         case SETP:
621             return V3_OP_SETP;
622         case SETS:
623             return V3_OP_SETS;
624         case SETZ:
625             return V3_OP_SETZ;
626         case SETO:
627             return V3_OP_SETO;
628             
629         case STOS_8:
630         case STOS:
631             return V3_OP_STOS;
632
633         case HLT:
634         case PUSHF:
635         case POPF:
636         case MOV_DR2:
637         case MOV_2DR:
638         case MOV_SR2:
639         case MOV_2SR:
640
641         default:
642             return V3_INVALID_OP;
643
644     }
645 }