How to get invisible part of segment register

113 Views Asked by At

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.

0

There are 0 best solutions below