1use vmi_arch_amd64::{
2 Cr0, Cr2, Cr3, Cr4, Dr0, Dr1, Dr2, Dr3, Dr6, Dr7, Gdtr, Idtr, Registers, Rflags, Selector,
3};
4use zerocopy::{FromBytes, IntoBytes};
5
6macro_rules! static_assert_eq {
7 ($a:expr, $b:expr) => {
8 const _: () = [(); 1][($a == $b) as usize ^ 1];
9 };
10}
11
12#[allow(missing_docs)]
13pub const SIZE_OF_80387_REGISTERS: usize = 80;
14#[allow(missing_docs)]
15pub const MAXIMUM_SUPPORTED_EXTENSION: usize = 512;
16
17#[allow(missing_docs, non_camel_case_types, non_snake_case)]
18#[repr(C)]
19#[derive(Debug, Clone, Copy, FromBytes, IntoBytes)]
20pub struct FLOATING_SAVE_AREA {
21 pub ControlWord: u32,
22 pub StatusWord: u32,
23 pub TagWord: u32,
24 pub ErrorOffset: u32,
25 pub ErrorSelector: u32,
26 pub DataOffset: u32,
27 pub DataSelector: u32,
28 pub RegisterArea: [u8; SIZE_OF_80387_REGISTERS],
29 pub Spare0: u32,
30}
31
32static_assert_eq!(size_of::<FLOATING_SAVE_AREA>(), 112);
33
34#[allow(missing_docs, non_camel_case_types, non_snake_case)]
35#[repr(C)]
36#[derive(Debug, Clone, Copy, FromBytes, IntoBytes)]
37pub struct CONTEXT_X86 {
38 pub ContextFlags: u32,
39
40 pub Dr7: u32,
41 pub Dr0: u32,
42 pub Dr1: u32,
43 pub Dr2: u32,
44 pub Dr3: u32,
45 pub Dr6: u32,
46
47 pub FloatSave: FLOATING_SAVE_AREA,
48
49 pub SegGs: u32,
50 pub SegFs: u32,
51 pub SegEs: u32,
52 pub SegDs: u32,
53
54 pub Edi: u32,
55 pub Esi: u32,
56 pub Ebx: u32,
57 pub Edx: u32,
58 pub Ecx: u32,
59 pub Eax: u32,
60
61 pub Ebp: u32,
62 pub Eip: u32,
63 pub SegCs: u32,
64 pub EFlags: u32,
65 pub Esp: u32,
66 pub SegSs: u32,
67
68 pub ExtendedRegisters: [u8; MAXIMUM_SUPPORTED_EXTENSION],
69}
70
71static_assert_eq!(size_of::<CONTEXT_X86>(), 716);
72
73#[allow(missing_docs, non_camel_case_types, non_snake_case)]
74#[repr(C, align(16))]
75#[derive(Debug, Clone, Copy, FromBytes, IntoBytes)]
76pub struct M128A {
77 pub Low: u64,
78 pub High: i64,
79}
80
81#[allow(missing_docs, non_camel_case_types, non_snake_case)]
82#[repr(C, align(16))]
83#[derive(Debug, Clone, Copy, FromBytes, IntoBytes)]
84pub struct XSAVE_FORMAT {
85 pub ControlWord: u16,
86 pub StatusWord: u16,
87 pub TagWord: u8,
88 pub Reserved1: u8,
89 pub ErrorOpcode: u16,
90 pub ErrorOffset: u32,
91 pub ErrorSelector: u16,
92 pub Reserved2: u16,
93 pub DataOffset: u32,
94 pub DataSelector: u16,
95 pub Reserved3: u16,
96 pub MxCsr: u32,
97 pub MxCsr_Mask: u32,
98 pub FloatRegisters: [M128A; 8],
99 pub XmmRegisters: [M128A; 16],
100 pub Reserved4: [u8; 96],
101}
102
103static_assert_eq!(size_of::<XSAVE_FORMAT>(), 512);
104
105#[allow(missing_docs, non_camel_case_types, non_snake_case)]
106#[repr(C, align(16))]
107#[derive(Debug, Clone, Copy, FromBytes, IntoBytes)]
108pub struct CONTEXT_AMD64 {
109 pub P1Home: u64,
110 pub P2Home: u64,
111 pub P3Home: u64,
112 pub P4Home: u64,
113 pub P5Home: u64,
114 pub P6Home: u64,
115
116 pub ContextFlags: u32,
117 pub MxCsr: u32,
118
119 pub SegCs: u16,
120 pub SegDs: u16,
121 pub SegEs: u16,
122 pub SegFs: u16,
123 pub SegGs: u16,
124 pub SegSs: u16,
125 pub EFlags: u32,
126
127 pub Dr0: u64,
128 pub Dr1: u64,
129 pub Dr2: u64,
130 pub Dr3: u64,
131 pub Dr6: u64,
132 pub Dr7: u64,
133
134 pub Rax: u64,
135 pub Rcx: u64,
136 pub Rdx: u64,
137 pub Rbx: u64,
138 pub Rsp: u64,
139 pub Rbp: u64,
140 pub Rsi: u64,
141 pub Rdi: u64,
142 pub R8: u64,
143 pub R9: u64,
144 pub R10: u64,
145 pub R11: u64,
146 pub R12: u64,
147 pub R13: u64,
148 pub R14: u64,
149 pub R15: u64,
150
151 pub Rip: u64,
152
153 pub FltSave: XSAVE_FORMAT,
155
156 pub VectorRegister: [M128A; 26],
178 pub VectorControl: u64,
179
180 pub DebugControl: u64,
181 pub LastBranchToRip: u64,
182 pub LastBranchFromRip: u64,
183 pub LastExceptionToRip: u64,
184 pub LastExceptionFromRip: u64,
185}
186
187static_assert_eq!(size_of::<CONTEXT_AMD64>(), 1232);
188
189#[allow(missing_docs, non_camel_case_types, non_snake_case)]
190#[repr(C)]
191#[derive(Debug, Clone, Copy, FromBytes, IntoBytes)]
192pub struct KDESCRIPTOR_X86 {
193 pub Pad: u16,
194 pub Limit: u16,
195 pub Base: u32,
196}
197
198static_assert_eq!(size_of::<KDESCRIPTOR_X86>(), 8);
199
200#[allow(missing_docs, non_camel_case_types, non_snake_case)]
201#[repr(C)]
202#[derive(Debug, Clone, Copy, FromBytes, IntoBytes)]
203pub struct KSPECIAL_REGISTERS_X86 {
204 pub Cr0: u32,
205 pub Cr2: u32,
206 pub Cr3: u32,
207 pub Cr4: u32,
208 pub KernelDr0: u32,
209 pub KernelDr1: u32,
210 pub KernelDr2: u32,
211 pub KernelDr3: u32,
212 pub KernelDr6: u32,
213 pub KernelDr7: u32,
214 pub Gdtr: KDESCRIPTOR_X86,
215 pub Idtr: KDESCRIPTOR_X86,
216 pub Tr: u16,
217 pub Ldtr: u16,
218 pub Reserved: [u32; 6],
219}
220
221static_assert_eq!(size_of::<KSPECIAL_REGISTERS_X86>(), 84);
222
223#[allow(missing_docs, non_camel_case_types, non_snake_case)]
224#[repr(C)]
225#[derive(Debug, Clone, Copy, FromBytes, IntoBytes)]
226pub struct KDESCRIPTOR_AMD64 {
227 pub Pad: [u16; 3],
228 pub Limit: u16,
229 pub Base: u64,
230}
231
232static_assert_eq!(size_of::<KDESCRIPTOR_AMD64>(), 16);
233
234#[allow(missing_docs, non_camel_case_types, non_snake_case)]
235#[repr(C)]
236#[derive(Debug, Clone, Copy, FromBytes, IntoBytes)]
237pub struct KSPECIAL_REGISTERS_AMD64 {
238 pub Cr0: u64,
239 pub Cr2: u64,
240 pub Cr3: u64,
241 pub Cr4: u64,
242 pub KernelDr0: u64,
243 pub KernelDr1: u64,
244 pub KernelDr2: u64,
245 pub KernelDr3: u64,
246 pub KernelDr6: u64,
247 pub KernelDr7: u64,
248 pub Gdtr: KDESCRIPTOR_AMD64,
249 pub Idtr: KDESCRIPTOR_AMD64,
250 pub Tr: u16,
251 pub Ldtr: u16,
252 pub MxCsr: u32,
253 pub DebugControl: u64,
254 pub LastBranchToRip: u64,
255 pub LastBranchFromRip: u64,
256 pub LastExceptionToRip: u64,
257 pub LastExceptionFromRip: u64,
258 pub Cr8: u64,
259 pub MsrGsBase: u64,
260 pub MsrGsSwap: u64,
261 pub MsrStar: u64,
262 pub MsrLStar: u64,
263 pub MsrCStar: u64,
264 pub MsrSyscallMask: u64,
265 }
269
270static_assert_eq!(size_of::<KSPECIAL_REGISTERS_AMD64>(), 216);
271
272#[allow(missing_docs)]
276pub trait WindowsSpecialRegisters {
277 fn cr0(&self) -> Cr0;
278 fn cr2(&self) -> Cr2;
279 fn cr3(&self) -> Cr3;
280 fn cr4(&self) -> Cr4;
281 fn kernel_dr0(&self) -> Dr0;
282 fn kernel_dr1(&self) -> Dr1;
283 fn kernel_dr2(&self) -> Dr2;
284 fn kernel_dr3(&self) -> Dr3;
285 fn kernel_dr6(&self) -> Dr6;
286 fn kernel_dr7(&self) -> Dr7;
287 fn gdtr(&self) -> Gdtr;
288 fn idtr(&self) -> Idtr;
289 fn tr(&self) -> Selector;
290 fn ldtr(&self) -> Selector;
291
292 fn msr_gs_base(&self) -> Option<u64> {
293 None
294 }
295
296 fn msr_gs_swap(&self) -> Option<u64> {
297 None
298 }
299
300 fn msr_star(&self) -> Option<u64> {
301 None
302 }
303
304 fn msr_lstar(&self) -> Option<u64> {
305 None
306 }
307
308 fn msr_cstar(&self) -> Option<u64> {
309 None
310 }
311
312 fn msr_syscall_mask(&self) -> Option<u64> {
313 None
314 }
315}
316
317impl WindowsSpecialRegisters for KSPECIAL_REGISTERS_X86 {
318 fn cr0(&self) -> Cr0 {
319 Cr0(self.Cr0 as u64)
320 }
321
322 fn cr2(&self) -> Cr2 {
323 Cr2(self.Cr2 as u64)
324 }
325
326 fn cr3(&self) -> Cr3 {
327 Cr3(self.Cr3 as u64)
328 }
329
330 fn cr4(&self) -> Cr4 {
331 Cr4(self.Cr4 as u64)
332 }
333
334 fn kernel_dr0(&self) -> Dr0 {
335 Dr0(self.KernelDr0 as u64)
336 }
337
338 fn kernel_dr1(&self) -> Dr1 {
339 Dr1(self.KernelDr1 as u64)
340 }
341
342 fn kernel_dr2(&self) -> Dr2 {
343 Dr2(self.KernelDr2 as u64)
344 }
345
346 fn kernel_dr3(&self) -> Dr3 {
347 Dr3(self.KernelDr3 as u64)
348 }
349
350 fn kernel_dr6(&self) -> Dr6 {
351 Dr6(self.KernelDr6 as u64)
352 }
353
354 fn kernel_dr7(&self) -> Dr7 {
355 Dr7(self.KernelDr7 as u64)
356 }
357
358 fn gdtr(&self) -> Gdtr {
359 Gdtr {
360 limit: self.Gdtr.Limit as u32,
361 base: self.Gdtr.Base as u64,
362 }
363 }
364
365 fn idtr(&self) -> Idtr {
366 Idtr {
367 limit: self.Idtr.Limit as u32,
368 base: self.Idtr.Base as u64,
369 }
370 }
371
372 fn tr(&self) -> Selector {
373 Selector(self.Tr)
374 }
375
376 fn ldtr(&self) -> Selector {
377 Selector(self.Ldtr)
378 }
379}
380
381impl WindowsSpecialRegisters for KSPECIAL_REGISTERS_AMD64 {
382 fn cr0(&self) -> Cr0 {
383 Cr0(self.Cr0)
384 }
385
386 fn cr2(&self) -> Cr2 {
387 Cr2(self.Cr2)
388 }
389
390 fn cr3(&self) -> Cr3 {
391 Cr3(self.Cr3)
392 }
393
394 fn cr4(&self) -> Cr4 {
395 Cr4(self.Cr4)
396 }
397
398 fn kernel_dr0(&self) -> Dr0 {
399 Dr0(self.KernelDr0)
400 }
401
402 fn kernel_dr1(&self) -> Dr1 {
403 Dr1(self.KernelDr1)
404 }
405
406 fn kernel_dr2(&self) -> Dr2 {
407 Dr2(self.KernelDr2)
408 }
409
410 fn kernel_dr3(&self) -> Dr3 {
411 Dr3(self.KernelDr3)
412 }
413
414 fn kernel_dr6(&self) -> Dr6 {
415 Dr6(self.KernelDr6)
416 }
417
418 fn kernel_dr7(&self) -> Dr7 {
419 Dr7(self.KernelDr7)
420 }
421
422 fn gdtr(&self) -> Gdtr {
423 Gdtr {
424 limit: self.Gdtr.Limit as u32,
425 base: self.Gdtr.Base,
426 }
427 }
428
429 fn idtr(&self) -> Idtr {
430 Idtr {
431 limit: self.Idtr.Limit as u32,
432 base: self.Idtr.Base,
433 }
434 }
435
436 fn tr(&self) -> Selector {
437 Selector(self.Tr)
438 }
439
440 fn ldtr(&self) -> Selector {
441 Selector(self.Ldtr)
442 }
443
444 fn msr_gs_base(&self) -> Option<u64> {
445 Some(self.MsrGsBase)
446 }
447
448 fn msr_gs_swap(&self) -> Option<u64> {
449 Some(self.MsrGsSwap)
450 }
451
452 fn msr_star(&self) -> Option<u64> {
453 Some(self.MsrStar)
454 }
455
456 fn msr_lstar(&self) -> Option<u64> {
457 Some(self.MsrLStar)
458 }
459
460 fn msr_cstar(&self) -> Option<u64> {
461 Some(self.MsrCStar)
462 }
463
464 fn msr_syscall_mask(&self) -> Option<u64> {
465 Some(self.MsrSyscallMask)
466 }
467}
468
469#[allow(missing_docs)]
473pub trait WindowsContext {
474 fn rax(&self) -> u64;
475 fn rbx(&self) -> u64;
476 fn rcx(&self) -> u64;
477 fn rdx(&self) -> u64;
478 fn rbp(&self) -> u64;
479 fn rsi(&self) -> u64;
480 fn rdi(&self) -> u64;
481 fn rsp(&self) -> u64;
482
483 fn r8(&self) -> Option<u64> {
484 None
485 }
486
487 fn r9(&self) -> Option<u64> {
488 None
489 }
490
491 fn r10(&self) -> Option<u64> {
492 None
493 }
494
495 fn r11(&self) -> Option<u64> {
496 None
497 }
498
499 fn r12(&self) -> Option<u64> {
500 None
501 }
502
503 fn r13(&self) -> Option<u64> {
504 None
505 }
506
507 fn r14(&self) -> Option<u64> {
508 None
509 }
510
511 fn r15(&self) -> Option<u64> {
512 None
513 }
514
515 fn rip(&self) -> u64;
516 fn rflags(&self) -> Rflags;
517
518 fn dr0(&self) -> Dr0;
519 fn dr1(&self) -> Dr1;
520 fn dr2(&self) -> Dr2;
521 fn dr3(&self) -> Dr3;
522 fn dr6(&self) -> Dr6;
523 fn dr7(&self) -> Dr7;
524
525 fn seg_cs(&self) -> Selector;
526 fn seg_ds(&self) -> Selector;
527 fn seg_es(&self) -> Selector;
528 fn seg_fs(&self) -> Selector;
529 fn seg_gs(&self) -> Selector;
530 fn seg_ss(&self) -> Selector;
531}
532
533impl WindowsContext for CONTEXT_X86 {
534 fn rax(&self) -> u64 {
535 self.Eax as u64
536 }
537
538 fn rbx(&self) -> u64 {
539 self.Ebx as u64
540 }
541
542 fn rcx(&self) -> u64 {
543 self.Ecx as u64
544 }
545
546 fn rdx(&self) -> u64 {
547 self.Edx as u64
548 }
549
550 fn rbp(&self) -> u64 {
551 self.Ebp as u64
552 }
553
554 fn rsi(&self) -> u64 {
555 self.Esi as u64
556 }
557
558 fn rdi(&self) -> u64 {
559 self.Edi as u64
560 }
561
562 fn rsp(&self) -> u64 {
563 self.Esp as u64
564 }
565
566 fn rip(&self) -> u64 {
567 self.Eip as u64
568 }
569
570 fn rflags(&self) -> Rflags {
571 Rflags(self.EFlags as u64)
572 }
573
574 fn dr0(&self) -> Dr0 {
575 Dr0(self.Dr0 as u64)
576 }
577
578 fn dr1(&self) -> Dr1 {
579 Dr1(self.Dr1 as u64)
580 }
581
582 fn dr2(&self) -> Dr2 {
583 Dr2(self.Dr2 as u64)
584 }
585
586 fn dr3(&self) -> Dr3 {
587 Dr3(self.Dr3 as u64)
588 }
589
590 fn dr6(&self) -> Dr6 {
591 Dr6(self.Dr6 as u64)
592 }
593
594 fn dr7(&self) -> Dr7 {
595 Dr7(self.Dr7 as u64)
596 }
597
598 fn seg_cs(&self) -> Selector {
599 Selector(self.SegCs as u16)
600 }
601
602 fn seg_ds(&self) -> Selector {
603 Selector(self.SegDs as u16)
604 }
605
606 fn seg_es(&self) -> Selector {
607 Selector(self.SegEs as u16)
608 }
609
610 fn seg_fs(&self) -> Selector {
611 Selector(self.SegFs as u16)
612 }
613
614 fn seg_gs(&self) -> Selector {
615 Selector(self.SegGs as u16)
616 }
617
618 fn seg_ss(&self) -> Selector {
619 Selector(self.SegSs as u16)
620 }
621}
622
623impl WindowsContext for CONTEXT_AMD64 {
624 fn rax(&self) -> u64 {
625 self.Rax
626 }
627
628 fn rbx(&self) -> u64 {
629 self.Rbx
630 }
631
632 fn rcx(&self) -> u64 {
633 self.Rcx
634 }
635
636 fn rdx(&self) -> u64 {
637 self.Rdx
638 }
639
640 fn rbp(&self) -> u64 {
641 self.Rbp
642 }
643
644 fn rsi(&self) -> u64 {
645 self.Rsi
646 }
647
648 fn rdi(&self) -> u64 {
649 self.Rdi
650 }
651
652 fn rsp(&self) -> u64 {
653 self.Rsp
654 }
655
656 fn r8(&self) -> Option<u64> {
657 Some(self.R8)
658 }
659
660 fn r9(&self) -> Option<u64> {
661 Some(self.R9)
662 }
663
664 fn r10(&self) -> Option<u64> {
665 Some(self.R10)
666 }
667
668 fn r11(&self) -> Option<u64> {
669 Some(self.R11)
670 }
671
672 fn r12(&self) -> Option<u64> {
673 Some(self.R12)
674 }
675
676 fn r13(&self) -> Option<u64> {
677 Some(self.R13)
678 }
679
680 fn r14(&self) -> Option<u64> {
681 Some(self.R14)
682 }
683
684 fn r15(&self) -> Option<u64> {
685 Some(self.R15)
686 }
687
688 fn rip(&self) -> u64 {
689 self.Rip
690 }
691
692 fn rflags(&self) -> Rflags {
693 Rflags(self.EFlags as u64)
694 }
695
696 fn dr0(&self) -> Dr0 {
697 Dr0(self.Dr0)
698 }
699
700 fn dr1(&self) -> Dr1 {
701 Dr1(self.Dr1)
702 }
703
704 fn dr2(&self) -> Dr2 {
705 Dr2(self.Dr2)
706 }
707
708 fn dr3(&self) -> Dr3 {
709 Dr3(self.Dr3)
710 }
711
712 fn dr6(&self) -> Dr6 {
713 Dr6(self.Dr6)
714 }
715
716 fn dr7(&self) -> Dr7 {
717 Dr7(self.Dr7)
718 }
719
720 fn seg_cs(&self) -> Selector {
721 Selector(self.SegCs)
722 }
723
724 fn seg_ds(&self) -> Selector {
725 Selector(self.SegDs)
726 }
727
728 fn seg_es(&self) -> Selector {
729 Selector(self.SegEs)
730 }
731
732 fn seg_fs(&self) -> Selector {
733 Selector(self.SegFs)
734 }
735
736 fn seg_gs(&self) -> Selector {
737 Selector(self.SegGs)
738 }
739
740 fn seg_ss(&self) -> Selector {
741 Selector(self.SegSs)
742 }
743}
744
745pub trait WindowsRegistersAdapter {
747 fn write_context(&mut self, context: &impl WindowsContext);
749
750 fn write_special_registers(&mut self, special_registers: &impl WindowsSpecialRegisters);
752}
753
754impl WindowsRegistersAdapter for Registers {
755 fn write_context(&mut self, context: &impl WindowsContext) {
756 self.rax = context.rax();
757 self.rbx = context.rbx();
758 self.rcx = context.rcx();
759 self.rdx = context.rdx();
760 self.rbp = context.rbp();
761 self.rsi = context.rsi();
762 self.rdi = context.rdi();
763 self.rsp = context.rsp();
764 if let Some(r8) = context.r8() {
765 self.r8 = r8;
766 }
767 if let Some(r9) = context.r9() {
768 self.r9 = r9;
769 }
770 if let Some(r10) = context.r10() {
771 self.r10 = r10;
772 }
773 if let Some(r11) = context.r11() {
774 self.r11 = r11;
775 }
776 if let Some(r12) = context.r12() {
777 self.r12 = r12;
778 }
779 if let Some(r13) = context.r13() {
780 self.r13 = r13;
781 }
782 if let Some(r14) = context.r14() {
783 self.r14 = r14;
784 }
785 if let Some(r15) = context.r15() {
786 self.r15 = r15;
787 }
788 self.rip = context.rip();
789 self.rflags = context.rflags();
790
791 self.dr0 = context.dr0();
792 self.dr1 = context.dr1();
793 self.dr2 = context.dr2();
794 self.dr3 = context.dr3();
795 self.dr6 = context.dr6();
796 self.dr7 = context.dr7();
797
798 self.cs.selector = context.seg_cs();
799 self.ds.selector = context.seg_ds();
800 self.es.selector = context.seg_es();
801 self.fs.selector = context.seg_fs();
802 self.gs.selector = context.seg_gs();
803 self.ss.selector = context.seg_ss();
804 }
805
806 fn write_special_registers(&mut self, special_registers: &impl WindowsSpecialRegisters) {
807 self.cr0 = special_registers.cr0();
808 self.cr2 = special_registers.cr2();
809 self.cr3 = special_registers.cr3();
810 self.cr4 = special_registers.cr4();
811 self.dr0 = special_registers.kernel_dr0();
812 self.dr1 = special_registers.kernel_dr1();
813 self.dr2 = special_registers.kernel_dr2();
814 self.dr3 = special_registers.kernel_dr3();
815 self.dr6 = special_registers.kernel_dr6();
816 self.dr7 = special_registers.kernel_dr7();
817
818 let gdtr = special_registers.gdtr();
819 self.gdtr.limit = gdtr.limit;
820 self.gdtr.base = gdtr.base;
821
822 let idtr = special_registers.idtr();
823 self.idtr.limit = idtr.limit;
824 self.idtr.base = idtr.base;
825
826 self.tr.selector = special_registers.tr();
827 self.ldtr.selector = special_registers.ldtr();
828
829 if let Some(msr_star) = special_registers.msr_star() {
836 self.msr_star = msr_star;
837 }
838
839 if let Some(msr_lstar) = special_registers.msr_lstar() {
840 self.msr_lstar = msr_lstar;
841 }
842
843 if let Some(msr_cstar) = special_registers.msr_cstar() {
844 self.msr_cstar = msr_cstar;
845 }
846
847 if let Some(msr_syscall_mask) = special_registers.msr_syscall_mask() {
848 self.msr_syscall_mask = msr_syscall_mask;
849 }
850 }
851}