1#![allow(dead_code)]
6use crate::parser::{Decoder, Encoder};
7
8use super::{
9 util::{TypeLoad, TypeSave},
10 *,
11};
12
13use std::{fs, io, mem::size_of};
14
15#[cfg(feature = "serde")]
16use serde::{Deserialize, Serialize};
17#[cfg(feature = "serde")]
18use serde_big_array::BigArray;
19
20const ATTR_G_SHIFT: usize = 23;
21const ATTR_B_SHIFT: usize = 22;
22const ATTR_L_SHIFT: usize = 21;
23const ATTR_AVL_SHIFT: usize = 20;
24const ATTR_P_SHIFT: usize = 15;
25const ATTR_DPL_SHIFT: usize = 13;
26const ATTR_S_SHIFT: usize = 12;
27const ATTR_TYPE_SHIFT: usize = 8;
28const ATTR_A_SHIFT: usize = 8;
29const ATTR_CS_SHIFT: usize = 11;
30const ATTR_C_SHIFT: usize = 10;
31const ATTR_R_SHIFT: usize = 9;
32const ATTR_E_SHIFT: usize = 10;
33const ATTR_W_SHIFT: usize = 9;
34
35const ATTR_G_MASK: usize = 1 << ATTR_G_SHIFT;
36const ATTR_B_MASK: usize = 1 << ATTR_B_SHIFT;
37const ATTR_L_MASK: usize = 1 << ATTR_L_SHIFT;
38const ATTR_AVL_MASK: usize = 1 << ATTR_AVL_SHIFT;
39const ATTR_P_MASK: u16 = 1 << ATTR_P_SHIFT;
40const ATTR_DPL_MASK: u16 = 1 << ATTR_DPL_SHIFT;
41const ATTR_S_MASK: u16 = 1 << ATTR_S_SHIFT;
42const ATTR_TYPE_MASK: u16 = 1 << ATTR_TYPE_SHIFT;
43const ATTR_A_MASK: u16 = 1 << ATTR_A_SHIFT;
44const ATTR_CS_MASK: u16 = 1 << ATTR_CS_SHIFT;
45const ATTR_C_MASK: u16 = 1 << ATTR_C_SHIFT;
46const ATTR_R_MASK: u16 = 1 << ATTR_R_SHIFT;
47const ATTR_E_MASK: u16 = 1 << ATTR_E_SHIFT;
48const ATTR_W_MASK: u16 = 1 << ATTR_W_SHIFT;
49
50#[repr(C, packed)]
54#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
55#[derive(Default, Clone, Copy)]
56pub struct VmcbSegment {
57 selector: u16,
60
61 attrib: u16,
63
64 limit: u32,
67
68 base: u64,
70}
71
72#[repr(C, packed)]
76#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
77#[derive(Copy, Clone)]
78pub struct Vmsa {
79 es: VmcbSegment,
81
82 cs: VmcbSegment,
84
85 ss: VmcbSegment,
87
88 ds: VmcbSegment,
90
91 fs: VmcbSegment,
93
94 gs: VmcbSegment,
96
97 gdtr: VmcbSegment,
99
100 ldtr: VmcbSegment,
102
103 idtr: VmcbSegment,
105
106 tr: VmcbSegment,
108
109 #[cfg_attr(feature = "serde", serde(with = "BigArray"))]
111 reserved_1: [u8; 43],
112
113 cpl: u8,
115
116 reserved_2: [u8; 4],
118
119 efer: u64,
121
122 #[cfg_attr(feature = "serde", serde(with = "BigArray"))]
124 reserved_3: [u8; 104],
125
126 xss: u64,
130
131 cr4: u64,
133
134 cr3: u64,
136
137 cr0: u64,
139
140 dr7: u64,
142
143 dr6: u64,
145
146 rflags: u64,
149
150 rip: u64,
152
153 #[cfg_attr(feature = "serde", serde(with = "BigArray"))]
155 reserved_4: [u8; 88],
156
157 rsp: u64,
159
160 reserved_5: [u8; 24],
162
163 rax: u64,
165
166 star: u64,
169
170 lstar: u64,
173
174 cstar: u64,
177
178 sfmask: u64,
181
182 kernel_gs_base: u64,
186
187 sysenter_cs: u64,
189
190 sysenter_esp: u64,
192
193 sysenter_eip: u64,
195
196 cr2: u64,
198
199 reserved_6: [u8; 32],
201
202 g_pat: u64,
204
205 dbgctl: u64,
207
208 br_from: u64,
210
211 br_to: u64,
213
214 last_excp_from: u64,
216
217 last_excp_to: u64,
219
220 #[cfg_attr(feature = "serde", serde(with = "BigArray"))]
222 reserved_7: [u8; 72],
223
224 spec_ctrl: u32,
227
228 reserved_7b: [u8; 4],
230
231 pkru: u32,
234
235 reserved_7a: [u8; 20],
237
238 reserved_8: u64,
240
241 rcx: u64,
243
244 rdx: u64,
246
247 rbx: u64,
249
250 reserved_9: u64,
252
253 rbp: u64,
255
256 rsi: u64,
258
259 rdi: u64,
261
262 r8: u64,
264
265 r9: u64,
267
268 r10: u64,
270
271 r11: u64,
273
274 r12: u64,
276
277 r13: u64,
279
280 r14: u64,
282
283 r15: u64,
285
286 reserved_10: [u8; 16],
288
289 sw_exit_code: u64,
291
292 sw_exit_info_1: u64,
294
295 sw_exit_info_2: u64,
298
299 sw_scratch: u64,
301
302 #[cfg_attr(feature = "serde", serde(with = "BigArray"))]
304 reserved_11: [u8; 56],
305
306 xcr0: u64,
308
309 valid_bitmap: [u8; 16],
311
312 x87_state_gpa: u64,
314}
315
316impl Default for Vmsa {
317 fn default() -> Self {
318 Self {
319 es: Default::default(),
320 cs: Default::default(),
321 ss: Default::default(),
322 ds: Default::default(),
323 fs: Default::default(),
324 gs: Default::default(),
325 gdtr: Default::default(),
326 ldtr: Default::default(),
327 idtr: Default::default(),
328 tr: Default::default(),
329 reserved_1: [0u8; 43],
330 cpl: Default::default(),
331 reserved_2: Default::default(),
332 efer: Default::default(),
333 reserved_3: [0u8; 104],
334 xss: Default::default(),
335 cr4: Default::default(),
336 cr3: Default::default(),
337 cr0: Default::default(),
338 dr7: Default::default(),
339 dr6: Default::default(),
340 rflags: Default::default(),
341 rip: Default::default(),
342 reserved_4: [0u8; 88],
343 rsp: Default::default(),
344 reserved_5: Default::default(),
345 rax: Default::default(),
346 star: Default::default(),
347 lstar: Default::default(),
348 cstar: Default::default(),
349 sfmask: Default::default(),
350 kernel_gs_base: Default::default(),
351 sysenter_cs: Default::default(),
352 sysenter_esp: Default::default(),
353 sysenter_eip: Default::default(),
354 cr2: Default::default(),
355 reserved_6: Default::default(),
356 g_pat: Default::default(),
357 dbgctl: Default::default(),
358 br_from: Default::default(),
359 br_to: Default::default(),
360 last_excp_from: Default::default(),
361 last_excp_to: Default::default(),
362 reserved_7: [0u8; 72],
363 spec_ctrl: Default::default(),
364 reserved_7b: Default::default(),
365 pkru: Default::default(),
366 reserved_7a: Default::default(),
367 reserved_8: Default::default(),
368 rcx: Default::default(),
369 rdx: Default::default(),
370 rbx: Default::default(),
371 reserved_9: Default::default(),
372 rbp: Default::default(),
373 rsi: Default::default(),
374 rdi: Default::default(),
375 r8: Default::default(),
376 r9: Default::default(),
377 r10: Default::default(),
378 r11: Default::default(),
379 r12: Default::default(),
380 r13: Default::default(),
381 r14: Default::default(),
382 r15: Default::default(),
383 reserved_10: Default::default(),
384 sw_exit_code: Default::default(),
385 sw_exit_info_1: Default::default(),
386 sw_exit_info_2: Default::default(),
387 sw_scratch: Default::default(),
388 reserved_11: [0u8; 56],
389 xcr0: Default::default(),
390 valid_bitmap: Default::default(),
391 x87_state_gpa: Default::default(),
392 }
393 }
394}
395
396impl Decoder<()> for Vmsa {
397 fn decode(reader: &mut impl Read, _: ()) -> Result<Self, std::io::Error> {
398 reader.load()
399 }
400}
401
402impl Encoder<()> for Vmsa {
403 fn encode(&self, writer: &mut impl Write, _: ()) -> Result<(), std::io::Error> {
404 writer.save(self)
405 }
406}
407
408impl Vmsa {
409 pub fn init_amd64(&mut self) {
411 self.cr0 = 1 << 4;
412 self.rip = 0xfff0;
413
414 self.cs.selector = 0xf000;
415 self.cs.base = 0xffff0000;
416 self.cs.limit = 0xffff;
417
418 self.ds.limit = 0xffff;
419
420 self.es.limit = 0xffff;
421 self.fs.limit = 0xffff;
422 self.gs.limit = 0xffff;
423 self.ss.limit = 0xffff;
424
425 self.gdtr.limit = 0xffff;
426 self.idtr.limit = 0xffff;
427
428 self.ldtr.limit = 0xffff;
429 self.tr.limit = 0xffff;
430
431 self.dr6 = 0xffff0ff0;
432 self.dr7 = 0x0400;
433 self.rflags = 0x2;
434 self.xcr0 = 0x1;
435 }
436
437 pub fn init_kvm(&mut self) {
439 self.cr4 = 0x40;
442
443 self.efer = 0x1000;
445
446 self.ldtr.attrib = 0x0082;
449
450 self.tr.attrib = 0x0083;
453
454 self.g_pat = 0x0007040600070406;
456 }
457
458 pub fn init_krun(&mut self, cpu: u64) {
461 self.rsi = 0x7000;
462 self.rbp = 0x8ff0;
463 self.rsp = 0x8ff0;
464
465 self.cs.attrib =
467 (ATTR_P_MASK | ATTR_S_MASK | ATTR_CS_MASK | ATTR_R_MASK) >> ATTR_TYPE_SHIFT;
468 self.ds.attrib = (ATTR_P_MASK | ATTR_S_MASK | ATTR_W_MASK | ATTR_A_MASK) >> ATTR_TYPE_SHIFT;
469 self.es.attrib = (ATTR_P_MASK | ATTR_S_MASK | ATTR_W_MASK | ATTR_A_MASK) >> ATTR_TYPE_SHIFT;
470 self.ss.attrib = (ATTR_P_MASK | ATTR_S_MASK | ATTR_W_MASK) >> ATTR_TYPE_SHIFT;
471 self.fs.attrib = (ATTR_P_MASK | ATTR_S_MASK | ATTR_W_MASK | ATTR_A_MASK) >> ATTR_TYPE_SHIFT;
472 self.gs.attrib = (ATTR_P_MASK | ATTR_S_MASK | ATTR_W_MASK | ATTR_A_MASK) >> ATTR_TYPE_SHIFT;
473
474 if cpu > 0 {
475 self.rip = 0;
476 self.rsp = 0;
477 self.rbp = 0;
478 self.rsi = 0;
479
480 self.cs.selector = 0x9100;
481 self.cs.base = 0x91000;
482 }
483 }
484
485 pub fn init_qemu(&mut self, _cpu: u64) {
488 self.ldtr.attrib = (ATTR_P_MASK | (2 << ATTR_TYPE_SHIFT)) >> ATTR_TYPE_SHIFT;
489 self.tr.attrib = (ATTR_P_MASK | (11 << ATTR_TYPE_SHIFT)) >> ATTR_TYPE_SHIFT;
490 self.cs.attrib = (ATTR_P_MASK | ATTR_S_MASK | ATTR_CS_MASK | ATTR_R_MASK | ATTR_A_MASK)
491 >> ATTR_TYPE_SHIFT;
492 self.ds.attrib = (ATTR_P_MASK | ATTR_S_MASK | ATTR_W_MASK | ATTR_A_MASK) >> ATTR_TYPE_SHIFT;
493 self.es.attrib = (ATTR_P_MASK | ATTR_S_MASK | ATTR_W_MASK | ATTR_A_MASK) >> ATTR_TYPE_SHIFT;
494 self.ss.attrib = (ATTR_P_MASK | ATTR_S_MASK | ATTR_W_MASK | ATTR_A_MASK) >> ATTR_TYPE_SHIFT;
495 self.fs.attrib = (ATTR_P_MASK | ATTR_S_MASK | ATTR_W_MASK | ATTR_A_MASK) >> ATTR_TYPE_SHIFT;
496 self.gs.attrib = (ATTR_P_MASK | ATTR_S_MASK | ATTR_W_MASK | ATTR_A_MASK) >> ATTR_TYPE_SHIFT;
497
498 self.g_pat = 0x0007040600070406;
499 }
500
501 pub fn cpu_sku(&mut self, mut family: u64, mut model: u64, mut stepping: u64) {
503 stepping &= 0xf;
504 model &= 0xff;
505 family &= 0xfff;
506
507 self.rdx = stepping;
508
509 if family > 0xf {
510 self.rdx |= 0xf00 | ((family - 0x0f) << 20);
511 } else {
512 self.rdx |= family << 8;
513 }
514
515 self.rdx |= ((model & 0xf) << 4) | ((model >> 4) << 16);
516 }
517
518 pub fn reset_addr(&mut self, ra: u32) {
520 let reset_cs = ra & 0xffff0000;
521 let reset_ip = ra & 0x0000ffff;
522
523 self.rip = u64::from(reset_ip);
524 self.cs.base = u64::from(reset_cs);
525 }
526
527 pub fn from_file(filename: &str) -> Result<Self, io::Error> {
531 let data = std::fs::read(filename)?;
532 if data.len() != 4096 {
533 return Err(io::Error::new(
534 io::ErrorKind::InvalidData,
535 format!("Expected VMSA length 4096, was {}", data.len()),
536 ));
537 }
538 let vmsa = Vmsa::decode(&mut &data[..], ())?;
539 Ok(vmsa)
540 }
541
542 pub fn to_file(&self, filename: &str) -> Result<(), io::Error> {
546 let mut vmsa_buf = Vec::new();
547 self.encode(&mut vmsa_buf, ())?;
548
549 const SIZE: usize = size_of::<Vmsa>();
550
551 let buf: &mut [u8] = &mut [0; 4096];
553 buf[..SIZE].copy_from_slice(&vmsa_buf[..]);
554
555 fs::write(filename, buf)?;
556 Ok(())
557 }
558}