Kernel Mode vs. User Mode

Kernel Mode vs. User Mode

Post by Ben Rus » Sat, 14 Aug 2004 04:13:06

Could someone double check my assumptions?

Assumption 1: A thread either executes in kernel mode or user mode.

Assumption 2: A thread, once it has executed kernel mode code, is always in
kernel mode.

Assumption 3: A thread can exist in both kernel mode or user mode at
different times during its execution.

Assumption 4: ::SetThreadContext() cannot be executed on a thread that is
executing in kernel-mode.

I'm trying to find some definitive resources on threads and how they switch
between "modes", or whether they do at all. So far I'm just piecing bits
together that I find scattered throughout the Internet. Any pointers would
be helpful.


Kernel Mode vs. User Mode

Post by Alex the 1 » Sat, 14 Aug 2004 08:20:03



No, threads rutinly go to kernel mode and back. Each system call you make in
an application goes to kernel mode(in the same thread context) it's
resolved, then the execution is resummed to the application.
Entring kernel mode dosn't involve a context switch, in kernel you are in
the context of the thread that made the call.

A thread is ether in kernel or in user mode.



What exactly are you traying to do, giving more informattion ussualy leads
to betters responses/help.


Kernel Mode vs. User Mode

Post by James Anto » Sat, 14 Aug 2004 08:33:18

Perhaps it will help if you use WinDbg to look at whatever threads are in
your favorite system. Use, for example, '!stacks 2'. You'll see lots of
threads. You'll see further that for many threads, parts of the stack are in
user space (usually ring 3) and parts in kernel space (ring 0, always). It's
the thread's state, captured (for WinDbg's purposes) in one or more frames,
that is important. The latest (topmost) state is what governs what a program
running under the thread can do at that moment.

So, for example, a given thread can change from ring 3 to ring 0 and back.

James Antognini
Windows DDK Support

This posting is provided "AS IS" with no warranties, and confers no rights.

Kernel Mode vs. User Mode

Post by Aaron Marg » Sat, 14 Aug 2004 10:50:20

Inside Windows 2000 by David Solomon and Mark Russinovich should be a good
resource for you. Unfortunately it's out of print, but you can get used
copies on Amazon.

-- Aaron

Kernel Mode vs. User Mode

Post by Steve Disp » Sat, 14 Aug 2004 13:01:27

Sort of; threads transition between user mode and kernel mode often.
Every time a user program calls a system call, the tread transitions.
The distinction between user mode and kernel mode is really just CPL.
Everything follows from that. Well, and you get a kernel stack when you
get into kernel mode, and you have to go through a trap gate to get there.

One interesting point is this - your thread can be running along in
usermode and can be commondered for use in kernel mode by an interrupt
handler, can be further used by various DPC functions, etc., before
resuming work in your user-mode code, without you ever having known
about it.

Nope, see above.


SetThreadContext is a usermode api, so no, it can't be called from
kernel mode code. Depending on how your code got into kernel mode, you
can indeed schedule an APC on your thread to call whatever function you
like while your thread is in kernel mode, assuming it's not already at
APC_LEVEL or above, and that you're not in a critical region.

There are kernel APIs that manipulate threads, too - see for example
NtSetContextThread and PsSetContextThread. These APIs only modify
usermode context. If the kernel wants to do something in a specific
thread context, it usually queues an APC to that thread. In fact, the
above-mentioned routines just queue a normal kernel APC to the target
thread when a user calls SetThreadContext. [Thanks to Ken Johnson of
Positive Networks for reviewing this explanation.]

If you have specific questions, feel free to post them here.


Steve Dispensa
Windows DDK MVP
Positive Networks

Kernel Mode vs. User Mode

Post by Ben Rus » Sun, 15 Aug 2004 00:37:42

hanks all for the responses. I hope my response isn't too wordy, so please
bare with me.....

I got a lot of my questions answered by you guys and by re-discovering the
Intel manuals online. Basically my interests are totally academic as I'm not
sure I could accomplish much else in this area right now with my
knowledge-level being so low. I'm clearly in the exploration and discovery
phase; so I appreciate all of the patience you have shown.

My "goal", I guess I might call it, was to have an application that
essentially set the TF bit and therefore set the processor into single step
mode. I would catch the exception in a debugger I've written and then reset
the bit, etc. Essentially this would enable me to get the CONTEXT for the
thread after every instruction, from which I was pulling the EIP (program
counter) and saving it into memory. The ultimate end was to trace the
program counter through the thread's execution and then print out a
dissasembly of the instructions executed (I'm currently building the
dissassembler). Anyway....the result turned out to be a ton of data; and so
I'm thinking of other ways to trace the execution of a program. One idea I
had was to look for each CALL instruction and replace it with an INT 3 and
the record each exception, etc (doing all of the appropriate back-patching
so that it would still be executed, etc.)

I have the EIP tracer utility done for the most part. I guess one of my main
questions was, which I think I have answered, to verify that I am getting
only user-mode instructions in the list of EIPs that I have dumped. But
since SetThreadContext() is what I'm using to change the TF bit and this
function is user-mode and therefore couldn't modify a thread executing under
kernel mode (I'm assuming this is correct), I know all of the EIPs I am
getting are for code that is executing in user space.

So, my question now is how can I get ahold of the GDT and index into it to
find various memory segments described by it. Say I wanted to be sure that a
region of memory I'm looking at isn't within the kernel-mode address space
as described by the GDT, or I wanted to write a utility which printed the
contents of the GDT to the screen, etc. (again, this is purely academic so
it may not be *practical*, but it is *interesting*). I know assembly and so
can do inline assembly code, but I would rather try to do it with the Win32
API. I see the instruction LGDT - is this what I would use? Or is there a
better way?

Thanks for the interesting talk,

"Steve Dispensa [MVP]" < XXXX@XXXXX.COM > wrote in message
news: XXXX@XXXXX.COM ...


Kernel Mode vs. User Mode

Post by Omega Re » Sun, 15 Aug 2004 01:18:40

> So, my question now is how can I get ahold of the GDT and index into it to

LGDT is used to load GDTR register, you have to use SGDT. However,
descriptor tables are accessible only from kernel mode because of their
memory protection settings (SGDT is not privileged instruction - but it
returns address of GDT that is in kernel address space). There are ways to
read kernel memory from user mode, but they are using undocumented tricks
to work (I can show you my descriptor dump utility).

Vulnerant omnes, ultima necat.

Kernel Mode vs. User Mode

Post by Ivan Brugi » Sun, 15 Aug 2004 02:45:35

lease look at the 'wt' functionality in the cdb/ntsd/windbg debuggers.
The overall goal of your task is doable till you are in user-mode, but,
if you need to track U-2-K and K-2-U transitions, and still do tracing,
then you should consider a different approach.
Even the Kernel Debugging support in NT-derivative OSes does
not allow you to trace through the trap-code.
This can be done with debuggers that supports ICEs and physical debug ports
of modern CPUs.

This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at

"Ben Rush" < XXXX@XXXXX.COM > wrote in message
news: XXXX@XXXXX.COM ...


Kernel Mode vs. User Mode

Post by Ben Rus » Sun, 15 Aug 2004 04:39:32

think my task is really moot, then, if it involves any real-world
applications. Please let me know if I'm wrong, but if I can't trace through
the "trap-code" (which I presume is the boundary between kernel and user
space) then at that point I'm practically at a loss as to when to start
tracing again because the thread has essentially "gone-silent" while its in
kernel space. I wouldn't know when to start tracing again; because when it
comes out of kernel space would be unknown to me.

I read the other night about the 'wt' functionality and have used it
lightly - but like I said I'm more interested in learning how to do it
myself than anything else at this point.

I think I'll try inserting INT 3 instructions at each CALL instruction, and
then after it gets caught I'll record that it got caught, back-patch the
CALL instruction, unwind the EIP and continue, etc. I think I could probably
trace well doing that. Besides, that will teach me more about modifying
executable code in-memory, etc.

"Ivan Brugiolo [MSFT]" < XXXX@XXXXX.COM > wrote in message
news:% XXXX@XXXXX.COM ...


Kernel Mode vs. User Mode

Post by Ben Rus » Sun, 15 Aug 2004 04:43:52


I would love to still be able to snoop the contents of the GDT. I think it
would be fascinating to learn about the undocumented tricks you speak of so
if you're fine sending me your tool I would be most appreciative. You may
contact me privately at (replace NOSPAM with @).

Using the DDK ( I think this is how its referred to) would I then able to
see the contents of this protected memory? Its my understanding that I can
create specialized kernel-priviledged threads using the DDK that can touch
kernel space. I have no problem learning something else to get this other
"goal" accomplished - after all, that's the point.

Kernel Mode vs. User Mode

Post by Ivan Brugi » Sun, 15 Aug 2004 05:13:44

Vieweing protected memory is not a problem solvable with DDK or other tools.
It's a problem of levereging the CPU protection mechanisms to allow
a user-mode process to have a view of the kernel address space.
This can be done with the call-gate (install an entry in the GDT that covers
the entire address space and that does not have the Privilege level set to
then use a segment register to dereference memory from that entry),
or by mapping the PhysicalMemory device.
Neither one of the two technique is supported, but, if you have a knowledge
of the protection mechanism of your CPU and the OS, they can get the job
A driver has access to the kernel address space, and it can do things that
the user-mode code cannot do ( because it runs at CPL = 3,
while the driver runs at CPL = 0 on average).

This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at



Kernel Mode vs. User Mode

Post by Alexander » Sun, 15 Aug 2004 05:29:06

Access to GDT goes through pagins mechanism. If the pages are set to be
readable for kernel only, it means one cannot even reload his ES, DS, etc. I
haven't tried this in Win32 apps, but it's interesting if it should work
without protection fault:

__asm {
push ds
pop ds

If it works, you probably shall be able to read GDT.



Kernel Mode vs. User Mode

Post by Omega Re » Sun, 15 Aug 2004 05:40:11

OK, here it is: ~omega/asm/
It uses \Device\PhysicalMemory for accessing kernel address space. The
source is entirely in assembler, nasm format. This tool produces text file
with GDT/IDT/LDT dump. For very detailed description of this method, follow
the link found in the source comment :)

Vulnerant omnes, ultima necat. ~omega

Kernel Mode vs. User Mode

Post by Ben Rus » Sun, 15 Aug 2004 05:53:16

Great Omega, you rock. I'll try to understand your code the best I can and
get back to you with any questions. The code looks clever.

Kernel Mode vs. User Mode

Post by Omega Re » Sun, 15 Aug 2004 06:14:44

Well, guys who discovered this rock, I just wrote it in assembler :)

Vulnerant omnes, ultima necat. ~omega