void fillGdtDataItem(
int
index,short selector)
{
GdtTable gdtTable
=
{
0
};
AsmGetGdtTable(&gdtTable);
selector &
=
0xFFF8
;
ULONG limit
=
__segmentlimit(selector);
PULONG item
=
(PULONG)(gdtTable.Base
+
selector);
LARGE_INTEGER itemBase
=
{
0
};
itemBase.LowPart
=
(
*
item &
0xFFFF0000
) >>
16
;
item
+
=
1
;
itemBase.LowPart |
=
(
*
item &
0xFF000000
) | ((
*
item &
0xFF
) <<
16
);
/
/
属性
ULONG attr
=
(
*
item &
0x00F0FF00
) >>
8
;
if
(selector
=
=
0
)
{
attr |
=
1
<<
16
;
}
__vmx_vmwrite(GUEST_ES_BASE
+
index
*
2
, itemBase.QuadPart);
__vmx_vmwrite(GUEST_ES_LIMIT
+
index
*
2
, limit);
__vmx_vmwrite(GUEST_ES_AR_BYTES
+
index
*
2
, attr);
__vmx_vmwrite(GUEST_ES_SELECTOR
+
index
*
2
, selector);
}
void VmxInitGuest(ULONG64 GuestEip, ULONG64 GuestEsp)
{
fillGdtDataItem(
0
, AsmReadES());
fillGdtDataItem(
1
, AsmReadCS());
fillGdtDataItem(
2
, AsmReadSS());
fillGdtDataItem(
3
, AsmReadDS());
fillGdtDataItem(
4
, AsmReadFS());
fillGdtDataItem(
5
, AsmReadGS());
fillGdtDataItem(
6
, AsmReadLDTR());
GdtTable gdtTable
=
{
0
};
AsmGetGdtTable(&gdtTable);
ULONG trSelector
=
AsmReadTR();
trSelector &
=
0xFFF8
;
ULONG trlimit
=
__segmentlimit(trSelector);
LARGE_INTEGER trBase
=
{
0
};
PULONG trItem
=
(PULONG)(gdtTable.Base
+
trSelector);
/
/
读TR
trBase.LowPart
=
((trItem[
0
] >>
16
) &
0xFFFF
) | ((trItem[
1
] &
0xFF
) <<
16
) | ((trItem[
1
] &
0xFF000000
));
trBase.HighPart
=
trItem[
2
];
/
/
属性
ULONG attr
=
(trItem[
1
] &
0x00F0FF00
) >>
8
;
__vmx_vmwrite(GUEST_TR_BASE, trBase.QuadPart);
__vmx_vmwrite(GUEST_TR_LIMIT, trlimit);
__vmx_vmwrite(GUEST_TR_AR_BYTES, attr);
__vmx_vmwrite(GUEST_TR_SELECTOR, trSelector);
__vmx_vmwrite(GUEST_CR0, __readcr0());
__vmx_vmwrite(GUEST_CR4, __readcr4());
__vmx_vmwrite(GUEST_CR3, __readcr3());
__vmx_vmwrite(GUEST_DR7, __readdr(
7
));
__vmx_vmwrite(GUEST_RFLAGS, __readeflags());
__vmx_vmwrite(GUEST_RSP, GuestEsp);
__vmx_vmwrite(GUEST_RIP, GuestEip);
__vmx_vmwrite(VMCS_LINK_POINTER,
-
1
);
__vmx_vmwrite(GUEST_IA32_DEBUGCTL, __readmsr(IA32_MSR_DEBUGCTL));
__vmx_vmwrite(GUEST_IA32_PAT, __readmsr(IA32_MSR_PAT));
__vmx_vmwrite(GUEST_IA32_EFER, __readmsr(IA32_MSR_EFER));
__vmx_vmwrite(GUEST_FS_BASE, __readmsr(IA32_FS_BASE));
__vmx_vmwrite(GUEST_GS_BASE, __readmsr(IA32_GS_BASE));
__vmx_vmwrite(GUEST_SYSENTER_CS, __readmsr(
0x174
));
__vmx_vmwrite(GUEST_SYSENTER_ESP, __readmsr(
0x175
));
__vmx_vmwrite(GUEST_SYSENTER_EIP, __readmsr(
0x176
));
/
/
IDT GDT
GdtTable idtTable;
__sidt(&idtTable);
__vmx_vmwrite(GUEST_GDTR_BASE, gdtTable.Base);
__vmx_vmwrite(GUEST_GDTR_LIMIT, gdtTable.limit);
__vmx_vmwrite(GUEST_IDTR_LIMIT, idtTable.limit);
__vmx_vmwrite(GUEST_IDTR_BASE, idtTable.Base);
}