Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Before Posting...
Please check out the Community Guidelines in the Announcements and Administration Category.

Operand size for lgdt/lidt

Sergey_PisarevSergey_Pisarev Member - All Emails Posts: 141

Hello
I use lgdt/lidt instructions to load descriptor tables registers:

load_idtr proc
lidt tbyte ptr[rcx]
ret
load_idtr endp

load_gdtr proc
lgdt tbyte ptr[rcx]
ret
load_gdtr endp

However I get error "error A2024: invalid operand size for instruction".

nt uses these instructions for example in function KiRestoreProcessorControlState :
000000014019880F: 0F 01 51 56 lgdt tbyte ptr [rcx+56h]
0000000140198813: 0F 01 59 66 lidt tbyte ptr [rcx+66h]

So it looks like my code must be assembling correctly.

What is my mistake ?

Comments

  • anton_bassovanton_bassov Member Posts: 4,825

    idt tbyte ptr[rcx]

    ....

    lgdt tbyte ptr[rcx]

    ......

    What is my mistake ?

    Are you still wondering what your mistake is all about???

    Anton Bassov

  • Sergey_PisarevSergey_Pisarev Member - All Emails Posts: 141

    Strange but it works like this:

    load_gdtr proc
    lgdt fword ptr[rcx]
    ret
    load_gdtr endp

    However if I disassembling my driver i get tbyte modifier:
    load_gdtr:
    00000001400011F6: 0F 01 11 lgdt tbyte ptr [rcx]
    00000001400011F9: C3 ret

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 12,715
    edited September 26 via Email
    Sergey_Pisarev wrote:
    > I use lgdt/lidt instructions to load descriptor tables registers:
    >
    > load_idtr proc
    > lidt tbyte ptr[rcx]
    > ret
    > load_idtr endp
    >
    > load_gdtr proc
    > lgdt tbyte ptr[rcx]
    > ret
    > load_gdtr endp

    "tbyte ptr" is a 10-byte operand,  used only with the FBLD and FBST
    instructions.   Although the GDT is 10 bytes long in 64-bit mode, it's
    not useful, so I'm guessing MASM never added support for it. lidt and
    lgdt in 32-bit land need a 6-byte operand, which is an "fword ptr".  It
    doesn't matter whether it's lying; if that's what it takes to get MASM
    to generate 0F 01 51 56, the hardware will know what to do.

    What do you think you're going to be doing with this?  The use of rcx
    implies 64-bit mode, where the GDT is essentially vestigial. And why
    would you define a subroutine to do this instead of doing it inline?  It
    takes more characters to type the subroutine call than to do the
    instruction.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 12,715
    edited September 26 via Email
    Sergey_Pisarev wrote:
    > Strange but it works like this:
    >
    > load_gdtr proc
    > lgdt fword ptr[rcx]
    > ret
    > load_gdtr endp
    >
    > However if I disassembling my driver i get tbyte modifier:
    >
    > load_gdtr:
    > 00000001400011F6: 0F 01 11 lgdt tbyte ptr [rcx]
    > 00000001400011F9: C3 ret

    It's not really that hard to figure out, is it? The disassembler has to assume 32-bit or 64-bit mode. There is no way to tell that from the byte stream. In 32-bit mode, 0F 01 11 is "lgdt fword ptr [bx][di]". In 64-bit mode, 0F 01 11 is "lgdt tbyte ptr [rcx]". The type designations are only for human consumption; the types are not embedded in the instruction stream. Those come from the context.

    MASM has long been an orphan. My guess is that no one ever updated its internal tables to tell it that lgdt and lidt need a "tbyte ptr" in 64-bit mode, so it unconditionally expects an "fword ptr".

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • Sergey_PisarevSergey_Pisarev Member - All Emails Posts: 141
    via Email
    This is x64 only driver, so inline assembly is not available.

    I have function:
    get_gdtr proc
    sgdt tbyte ptr [rcx]
    ret
    get_gdtr endp

    It compiles and work no problem.

    I need to restore GDTR on unload to values that patchguard likes.
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!