Entering usermode question

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.
LPeter
Member
Member
Posts: 30
Joined: Wed Jan 28, 2015 7:41 am

Entering usermode question

Post by LPeter »

Hi!
Well first, hi for everyone on this forum!
I've successfully entered user-mode, however I don't understand every part of it. I've set up my TSS, that's ok. And this is the code which enters usermode:

Code: Select all

	cli
	mov ax, 0x23
	mov ds, ax
	mov es, ax
	mov fs, ax
	mov gs, ax
	; Now perform the switch
	push 0x23
	push esp
	pushfd
	push 0x1b
	lea eax, [a]
	push eax
	iretd
a:
    add esp, 4
This part is a huge black-hole for me. I've understood everything so far, except this part. Why do I need to enter like this?

Thank you!
Peter
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: Entering usermode question

Post by alexfru »

Have you tried reading CPU documentation or have you just copied code from somewhere?
LPeter
Member
Member
Posts: 30
Joined: Wed Jan 28, 2015 7:41 am

Re: Entering usermode question

Post by LPeter »

I've read that IRETD needs SS, ESP, EFLAGS, CS, EIP.
And NULL is 0x0, code is 0x8, data is 0x10, user code is 0x18 and user data is 0x20.
Then for example why do I push 0x1b instead of 0x18?
By the way I only search for code if I can't get something to work, then I try to understand my mistakes.
Techel
Member
Member
Posts: 215
Joined: Fri Jan 30, 2015 4:57 pm
Location: Germany
Contact:

Re: Entering usermode question

Post by Techel »

The low 2 bits of a segmentselector in a segment register is the RPL (except in CS where it the the CPL). The RPL overrides the CPL if it is greater than the CPL when accessing a segment by this selector. The RPL must not be less than the CPL, so when in ring 3 the RPL have to be 3 too.
LPeter
Member
Member
Posts: 30
Joined: Wed Jan 28, 2015 7:41 am

Re: Entering usermode question

Post by LPeter »

Roflo wrote:The low 2 bits of a segmentselector in a segment register is the RPL (except in CS where it the the CPL). The RPL overrides the CPL if it is greater than the CPL when accessing a segment by this selector. The RPL must not be less than the CPL, so when in ring 3 the RPL have to be 3 too.
Right, thank you!
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: Entering usermode question

Post by alexfru »

LPeter wrote:I've read that IRETD needs SS, ESP, EFLAGS, CS, EIP.
And NULL is 0x0, code is 0x8, data is 0x10, user code is 0x18 and user data is 0x20.
Then for example why do I push 0x1b instead of 0x18?
By the way I only search for code if I can't get something to work, then I try to understand my mistakes.
It's hard to understand what's wrong when you clearly don't know what's right.

You may have read about basic GDT setup and about IRET somewhere (tutorials, pieces of someone else's code, etc). However, the question about 0x1b vs 0x18 (and the original question, which wasn't even specific enough to start answering) undoubtedly indicates that you haven't spent enough time or effort or both reading and understanding x86 segmentation as described in CPU manuals (freely downloadable, in case you didn't know).
LPeter
Member
Member
Posts: 30
Joined: Wed Jan 28, 2015 7:41 am

Re: Entering usermode question

Post by LPeter »

alexfru wrote:
LPeter wrote:I've read that IRETD needs SS, ESP, EFLAGS, CS, EIP.
And NULL is 0x0, code is 0x8, data is 0x10, user code is 0x18 and user data is 0x20.
Then for example why do I push 0x1b instead of 0x18?
By the way I only search for code if I can't get something to work, then I try to understand my mistakes.
It's hard to understand what's wrong when you clearly don't know what's right.

You may have read about basic GDT setup and about IRET somewhere (tutorials, pieces of someone else's code, etc). However, the question about 0x1b vs 0x18 (and the original question, which wasn't even specific enough to start answering) undoubtedly indicates that you haven't spent enough time or effort or both reading and understanding x86 segmentation as described in CPU manuals (freely downloadable, in case you didn't know).
You are probably right, I didn't read too much of CPU manuals. I'll fix my lack of knowledge.
ExeTwezz
Member
Member
Posts: 104
Joined: Sun Sep 21, 2014 7:16 am
Libera.chat IRC: exetwezz

Re: Entering usermode question

Post by ExeTwezz »

LPeter wrote:You are probably right, I didn't read too much of CPU manuals. I'll fix my lack of knowledge.
Andrew Tanenbaum's books are very good.
LPeter
Member
Member
Posts: 30
Joined: Wed Jan 28, 2015 7:41 am

Re: Entering usermode question

Post by LPeter »

ExeTwezz wrote:
LPeter wrote:You are probably right, I didn't read too much of CPU manuals. I'll fix my lack of knowledge.
Andrew Tanenbaum's books are very good.
Then I'm lucky, have it on the bookshelf. :)
User avatar
Waszka
Member
Member
Posts: 38
Joined: Tue Apr 22, 2014 11:30 am
Location: Poland

Re: Entering usermode question

Post by Waszka »

Hi,
I don't want to create another thread about entering user mode but in my case I get immediate GPF when entering user mode.

I have set up GDT entries for user mode and TSS. I wanted to try to enter Ring 3 with interrupts disabled (just to be sure I can enter it).

Code: Select all

asm(".intel_syntax noprefix\n\t"
      "cli \n"
      "mov ax, 0x23 \n"
      "mov ds, ax \n"
      "mov es, ax \n"
      "mov fs, ax \n"
      "mov gs, ax \n"

      "mov ebx, 0x23 \n"
      "push ebx \n"
      "push esp \n"
      "pushfd \n"

      "pop eax \n"
      "and eax, 0xFFFFFDFF  \n" ; turn IF flag to not generate interrupts
      "push eax \n"

      "mov ebx, 0x1B \n"
      "push ebx \n"
      "lea eax, [a] \n"
      "push eax \n"
      "iretd \n"
      "a: \n"
      "jmp a \n"     ; infinite loop
      "add esp, 4 \n"


      "xor eax, eax \n"
      "lea ebx, [testStr] \n"
      "int 0x80 \n"
      ".att_syntax prefix");
However I get:

Code: Select all

00046662829i[CPU0 ] CPU is in protected mode (active)
00046662829i[CPU0 ] CS.mode = 32 bit
00046662829i[CPU0 ] SS.mode = 32 bit
00046662829i[CPU0 ] EFER   = 0x00000000
00046662829i[CPU0 ] | EAX=c0006fbd  EBX=0000001b  ECX=000004b0  EDX=c000b174
00046662829i[CPU0 ] | ESP=c02ff838  EBP=c0300000  ESI=00000010  EDI=c02ffe10
00046662829i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf SF zf af PF cf
00046662829i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00046662829i[CPU0 ] |  CS:001b( 0003| 0|  3) 00000000 ffffffff 1 1
00046662829i[CPU0 ] |  DS:0023( 0004| 0|  3) 00000000 ffffffff 1 1
00046662829i[CPU0 ] |  SS:0023( 0004| 0|  3) 00000000 ffffffff 1 1
00046662829i[CPU0 ] |  ES:0023( 0004| 0|  3) 00000000 ffffffff 1 1
00046662829i[CPU0 ] |  FS:0023( 0004| 0|  3) 00000000 ffffffff 1 1
00046662829i[CPU0 ] |  GS:0023( 0004| 0|  3) 00000000 ffffffff 1 1
00046662829i[CPU0 ] | EIP=c0006fbd (c0006fbd)
00046662829i[CPU0 ] | CR0=0xe0000011 CR2=0xfffffffc
00046662829i[CPU0 ] | CR3=0x00132000 CR4=0x00000000
(0).[46662829] [0x0000000000406fbd] 001b:00000000c0006fbd (unk. ctxt): jmp .-2 (0xc0006fbd)      ; ebfe
00046662829e[CPU0 ] exception(): 3rd (14) exception with no resolution, shutdown status is 00h, resetting
00046662829i[SYS  ] bx_pc_system_c::Reset(HARDWARE) called
00046662829i[CPU0 ] cpu hardware reset
As you can see I have good RPL and all segments point to GDT entries for user mode.
What could cause GPF here? Or maybe I should ask: how can I check GPF error?
Bochs resets the machine after fault and I can't access registers prior to error :/
User avatar
Bender
Member
Member
Posts: 449
Joined: Wed Aug 21, 2013 3:53 am
Libera.chat IRC: bender|
Location: Asia, Singapore

Re: Entering usermode question

Post by Bender »

I don't think "3rd (14)" is a GPF; it's rather a PF (page fault).

As for debugging with Bochs, you should compile it with certain options, you can find how to use it here: http://bochs.sourceforge.net/doc/docboo ... ugger.html
"In a time of universal deceit - telling the truth is a revolutionary act." -- George Orwell
(R3X Runtime VM)(CHIP8 Interpreter OS)
User avatar
Waszka
Member
Member
Posts: 38
Joined: Tue Apr 22, 2014 11:30 am
Location: Poland

Re: Entering usermode question

Post by Waszka »

Bender wrote:I don't think "3rd (14)" is a GPF; it's rather a PF (page fault).

As for debugging with Bochs, you should compile it with certain options, you can find how to use it here: http://bochs.sourceforge.net/doc/docboo ... ugger.html
Oh man.... #-o
Thanks, I forgot to allow pages to be user accessible :P

EDIT: So it works but only if I disable IF. After enabling it I get this error again...
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Entering usermode question

Post by Combuster »

That means your TSS is either nowhere, or hasn't been filled out with the proper items.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Waszka
Member
Member
Posts: 38
Joined: Tue Apr 22, 2014 11:30 am
Location: Poland

Re: Entering usermode question

Post by Waszka »

Combuster wrote:That means your TSS is either nowhere, or hasn't been filled out with the proper items.
Thanks for the answer.
TSS is there but I guess there can be some errors with values inside it. I'll check that. ;)

Code: Select all

<bochs:2> info gdt
Global Descriptor Table (base=0x00000000c000c9a0, limit=47):
GDT[0x00]=??? descriptor hi=0x00000000, lo=0x00000000
GDT[0x01]=Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Non-Conforming, Accessed, 32-bit
GDT[0x02]=Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
GDT[0x03]=Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Non-Conforming, Accessed, 32-bit
GDT[0x04]=Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
GDT[0x05]=32-Bit TSS (Busy) at 0xc000c900, length 0x0c968

<bochs:3> info gdt 5
Global Descriptor Table (base=0x00000000c000c9a0, limit=47):
GDT[0x05]=32-Bit TSS (Busy) at 0xc000c900, length 0x0c968
ExeTwezz
Member
Member
Posts: 104
Joined: Sun Sep 21, 2014 7:16 am
Libera.chat IRC: exetwezz

Re: Entering usermode question

Post by ExeTwezz »

Waszka wrote:Thanks for the answer.
TSS is there but I guess there can be some errors with values inside it. I'll check that. ;)
You can use

Code: Select all

info tss
to check the TSS fields.
Post Reply