Change GDT and update CS while in long mode

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
lodo1995
Posts: 16
Joined: Thu Nov 12, 2015 6:31 am

Re: Change GDT and update CS while in long mode

Post by lodo1995 »

Ok guys. Thank you for your time.
I'm feeling very stupid in this moment, because I just found out that all of those problems are caused by a stupid error.
The line

Code: Select all

pushq fun
should in fact be

Code: Select all

pushq $fun
This change solved the issues. Now that retfq does his job, changing the CS to 0x08.

Thank you again, and sorry if I wasted your time.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Change GDT and update CS while in long mode

Post by Brendan »

Hi,
lodo1995 wrote:I suppose I should use a far jump, but this code does not work (AT&T syntax):

Code: Select all

mov %rax, %cr3   # load paging structures (it works)
lgdt 6(%rcx)     # load gdt (it works)
mov $100, %rsp   # update stack pointer (it works)

# now what I tried unsuccessfully:
pushw $8         # new code segment selector
pushq fun        # function to execute next
retfq            # far return (pops address and code segment)
I'd assume that "pushw $8" stores 2 bytes on the stack, the "pushq fun" stores 8 more bytes (for a total of 10 bytes so far); and then the "retfq" takes 16 bytes from the stack leaving you with a corrupted mess.

A far jump would be more fun.. ;)


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
lodo1995
Posts: 16
Joined: Thu Nov 12, 2015 6:31 am

Re: Change GDT and update CS while in long mode

Post by lodo1995 »

The final code is this:

Code: Select all

    mov %rax, %cr3
    lgdt 6(%rcx)
    mov $128, %rsp
    pushq $8
    pushq $update_segments
    retfq
    
update_segments:
    mov $16, %ax
    mov %ax, %ds
    mov %ax, %es
    mov %ax, %fs
    mov %ax, %gs
    mov %ax, %ss
Thank you again to everybody.
intx13
Member
Member
Posts: 112
Joined: Wed Sep 07, 2011 3:34 pm

Re: Change GDT and update CS while in long mode

Post by intx13 »

I thought that only FS and GS could be adjusted in long mode, and the others were forced to a base address of 0000?

http://www.andrea-allievi.com/blog/x64- ... game-over/
lodo1995
Posts: 16
Joined: Thu Nov 12, 2015 6:31 am

Re: Change GDT and update CS while in long mode

Post by lodo1995 »

intx13 wrote:I thought that only FS and GS could be adjusted in long mode, and the others were forced to a base address of 0000?

http://www.andrea-allievi.com/blog/x64- ... game-over/
That's true, when in long mode, the GDT is only used to check permissions of segments. But you still have to load into the registers the offsets to the GDT entries (so that CPU knows which segments to check permissions for). The base and limit values into the GDT are ignored for every segment register. For FS and GS, special MSR are provided with their bases (if needed).
Post Reply