I want to start virtual technology on my AMD computer. So I need to get the invisible part of the segment register, such as limit, base and attribute to fill the state save area of vmcb. I tried to use the following code to read the invisible part and finished filling the related part, but it always failed with exit code -1
meaning "Invalid guest state in VMCB".
pRegister->selector = Asm_ReadCs() & 0xFFF8;
PCODE_SEGMENT_DESCRIPTOR pCodeSegmentDescriptor = NULL;
switch (((PSEGMENT_SELECTOR) & (pRegister->selector))->TI)
{
case 0:
pCodeSegmentDescriptor = (ULONG64)(Gdtr.base) + (((PSEGMENT_SELECTOR) & (pRegister->selector))->SI) * sizeof(PVOID);
break;
case 1:
pLdt = (ULONG64)(Gdtr.base) + Ldtr * sizeof(PVOID);
pCodeSegmentDescriptor = *pLdt + (((PSEGMENT_SELECTOR) & (pRegister->selector))->SI) * sizeof(PVOID);
break;
}
pRegister->HiddenPart.base = pCodeSegmentDescriptor->BaseAddress_LowPart
| (pCodeSegmentDescriptor->BaseAddress_MiddlePart << 16)
| (pCodeSegmentDescriptor->BaseAddress_HighPart << 24);
pRegister->HiddenPart.limit = pCodeSegmentDescriptor->SegmentLimt_LowPart
| (pCodeSegmentDescriptor->SegmentLimt_HighPart &0xF << 16);
if (pCodeSegmentDescriptor->P == 0)
{
pRegister->HiddenPart.attrib = 0;
}
else
{
pRegister->HiddenPart.attrib = pCodeSegmentDescriptor->A
| (pCodeSegmentDescriptor->R << 1)
| (pCodeSegmentDescriptor->C << 2)
| (pCodeSegmentDescriptor->Reserved_0 << 3)
| (pCodeSegmentDescriptor->Reserved_1 << 4)
| (pCodeSegmentDescriptor->DPL << 5)
| (pCodeSegmentDescriptor->P << 7)
| (pCodeSegmentDescriptor->AVL << 12)
| (pCodeSegmentDescriptor->L << 13)
| (pCodeSegmentDescriptor->D << 14)
| (pCodeSegmentDescriptor->G << 15);
}
I want to know how to get the right invisible part of segment register.