Incorrectly loading GDT pointer from the stack

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.
Post Reply
User avatar
ScropTheOSAdventurer
Member
Member
Posts: 86
Joined: Sun Aug 25, 2013 5:47 pm
Location: Nebraska, USA

Incorrectly loading GDT pointer from the stack

Post by ScropTheOSAdventurer »

Now, I understand this is an extremely basic question, but I can't find a straight answer anywhere else. Now, I was working on my GDT code, which I got working just fine. Here is the assembly for the first version of the assembly that takes a gdt pointer (which is a struct in this case) and refreshes the registers:

Code: Select all

.intel_syntax noprefix 


.extern thegdtptr #it is a struct in another file 

.global gdt_flush
.type gdt_flush, @function 
gdt_flush: 
	lgdt [thegdtptr] # should load our GDT ptr! 
	mov ax, 0x10
	mov ds, ax 
	mov es, ax
	mov fs, ax
	mov gs, ax  
	mov ss, ax 
	jmp 0x08:Section2 
Section2: 
	ret 


Now, I decided it would be neat if I could just pass the gdt pointer struct to gdt_flush like in any other function. So I changed it to this:

Code: Select all

.intel_syntax noprefix 


.extern thegdtptr #it is a struct in another file; this time I just forgot to take it out; decided to keep it in this post for the sake of accuracy 

.global gdt_flush
.type gdt_flush, @function 
gdt_flush: 
	lgdt [esp] # should load our GDT ptr! 
	mov ax, 0x10
	mov ds, ax 
	mov es, ax
	mov fs, ax
	mov gs, ax  
	mov ss, ax 
	jmp 0x08:Section2 
Section2: 
	ret 


Now, from what I understand, the struct should be in the range from address "esp" to "esp + 6", since the GDT pointer struct is 48 bits long. So, it should load just fine, correct? However, the new code caused a triple fault as soon as I attempted to reload the registers, so obviously I am loading from the stack incorrectly. I tried adding 6 to esp in the lgdt instruction, but that triple faulted too. So, can someone clear things up for me please?
Last edited by ScropTheOSAdventurer on Sun Mar 23, 2014 6:48 pm, edited 2 times in total.
"Procrastination is the art of keeping up with yesterday."
theesemtheesem
Member
Member
Posts: 31
Joined: Thu Mar 20, 2014 2:22 pm
Location: London, UK

Re: Incorrectly loading GDT pointer from the stack

Post by theesemtheesem »

Hi,

That won't work. Remember that when You do a call from assembler code, or especially if You call this code from a higher level language like C of Pascal, extra stuff is placed on the stack (like the return address amongst others).

So if You just load this from ESP, you will read something else instead. When You push your gdt pointer to the stack and do a CALL, a return address will be placed on the stack so that RET knows where to jump back to. In order for Your code to work as it is You would need to JMP to it, but then how will You come back? unless You push a return address first, then JMP to your flush function, load the GDT, pick up the return address with mov eax, [esp-6] or somesuch, and then JMP eax, but why bother?

Cheers,
Andrew
theesemtheesem
Member
Member
Posts: 31
Joined: Thu Mar 20, 2014 2:22 pm
Location: London, UK

Re: Incorrectly loading GDT pointer from the stack

Post by theesemtheesem »

Hi,

Have a look at these to see exactly how the stack looks like after a call:

http://en.wikipedia.org/wiki/Call_stack
http://www.tenouk.com/Bufferoverflowc/B ... low2a.html

Cheers,
Andrew
User avatar
ScropTheOSAdventurer
Member
Member
Posts: 86
Joined: Sun Aug 25, 2013 5:47 pm
Location: Nebraska, USA

Re: Incorrectly loading GDT pointer from the stack

Post by ScropTheOSAdventurer »

Well, I took the first reply (didn't see the second one before I tried) and assumed the return address was a 32 bit integer. So I added 4 to esp in the lgdt instruction. I honestly figured that was a shot in the dark, but the craziest thing is that it worked! However, from what I am getting on wikipedia, the parameters are pushed on TOP of the return address. I am going to do some more extensive debugging to make sure it actually is loading the gdt pointer properly.
"Procrastination is the art of keeping up with yesterday."
theesemtheesem
Member
Member
Posts: 31
Joined: Thu Mar 20, 2014 2:22 pm
Location: London, UK

Re: Incorrectly loading GDT pointer from the stack

Post by theesemtheesem »

Hi,
Remember that in stack terms "on top" really means "below",
so when You CALL a function then the very top of the stack will contain the return address, with all the
parameters "BELOW" it. But from the functions point of view, they will be "ON TOP" of it, hence
the wording in the wiki article.

So what gets passed to the function via the stack is:
[ret addr]
[param 1]
[param 2]
...

Hence if You skip the top 4 bytes You will access the first parameter, which is the gdt pointer in Your case.

Cheers,
Andrew
User avatar
ScropTheOSAdventurer
Member
Member
Posts: 86
Joined: Sun Aug 25, 2013 5:47 pm
Location: Nebraska, USA

Re: Incorrectly loading GDT pointer from the stack

Post by ScropTheOSAdventurer »

Thanks Andrew! Time to move to doing the IDT.... :)
"Procrastination is the art of keeping up with yesterday."
theesemtheesem
Member
Member
Posts: 31
Joined: Thu Mar 20, 2014 2:22 pm
Location: London, UK

Re: Incorrectly loading GDT pointer from the stack

Post by theesemtheesem »

Hi,

Good luck mate!

Cheers,
Andrew
Post Reply