OT: confusion?

Zero Warnings? :wink:

Best regards,

Michal Vodicka
Veridicom
(RKK - Skytale)
[WWW: http://www.veridicom.com , http://www.skytale.com]


From: Pavel Hrdina[SMTP:xxxxx@compelson.com]
Reply To: NT Developers Interest List
Sent: Tuesday, June 12, 2001 11:05 PM
To: NT Developers Interest List
Subject: [ntdev] Re: confusion?

Before someone from Microsoft tells me the truth I believe that two
letters ‘Z’ and ‘w’ in
that order must have some meaning (like Ke stands for Kernel, Ki stands
probably
for Kernel Internal, Mm stands for Memory Manager, Lpc stands for Local
Procedure
Call, etc. etc. …).

Paul

PS: It’s a challenge for you Microsoft to expose the next internal thing
in NT !


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

>What does Zw mean?

It means nothing. It was chosen because it was assumed no one could
ever come up with a 2 char meaning for Zw when adding a new component
into the kernel and hence there would be no conflict.

This is what I was told. So no flame email please. I know you are all
smart and can come up with something for Zw ^):

-Eliyas


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

Nope … Nuttin’

We had this discussion a year ago and ZW… stands for nothing … just 2
letters in the alphabet (English alphabet) to discriminate from other
functionality.

Gary G. Little
Staff Engineer
Broadband Storage, Inc.
xxxxx@Broadstor.com
xxxxx@inland.net

-----Original Message-----
From: Michal Vodicka [mailto:xxxxx@veridicom.cz.nospam]
Sent: Tuesday, June 12, 2001 2:27 PM
To: NT Developers Interest List
Subject: [ntdev] OT: confusion?

Zero Warnings? :wink:

Best regards,

Michal Vodicka
Veridicom
(RKK - Skytale)
[WWW: http://www.veridicom.com , http://www.skytale.com]


From: Pavel Hrdina[SMTP:xxxxx@compelson.com]
Reply To: NT Developers Interest List
Sent: Tuesday, June 12, 2001 11:05 PM
To: NT Developers Interest List
Subject: [ntdev] Re: confusion?

Before someone from Microsoft tells me the truth I believe that two
letters ‘Z’ and ‘w’ in
that order must have some meaning (like Ke stands for Kernel, Ki stands
probably
for Kernel Internal, Mm stands for Memory Manager, Lpc stands for Local
Procedure
Call, etc. etc. …).

Paul

PS: It’s a challenge for you Microsoft to expose the next internal thing
in NT !


You are currently subscribed to ntdev as: xxxxx@broadstor.com
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

One crucial point being missed is memory address validation in two routines.
If you are using NtXXXX routines, it always expects a virtul memory adress
location in user mode( 2GB /3GB), where as in ZwXXX expects address location
in kernel mode.If you try using NTXXX routines in Kernel memory, one gets
error to the above fact and same holds true ZwXXX routines in user mode.
We can conclude that NTXXX calls are like system calls avaible on UNIX
platforms( where this memory address validation is done, one cann’t use
system call from kernel)

The description of reality is slightly different and haven’t appeared
yet so here it is.
(For the rest of this explanation we assume the service table number 0 =
Native NT API)
Listen carefully all of you who don’t know much about it ! (and also you
from Microsoft)

Introduction:
There are two modes - kernel mode and user mode
and two sets of Native NT API - NtXxxxx and ZwXxxxx.

In user mode (represented by NTDLL.DLL) whole number of routines
in both sets is exported, but every routine is really a stub:
mov eax, ServiceNumber
lea edx, [esp+4]
int 2e
ret xx
In addition both export names (for eg. NtCreatePort and ZwCreatePort)
points to the same stub so it really doesn’t matter which set you use.
It really doesn’t have any other effect than the name in your import
table.

In kernel mode the situation is different. Not all routines are exported
(who knows why ? it really seems as a restrictive interntion for non-
bultin-NT-executive components made by Microsoft, but I’m asking
WHAT WAS THE RATIONAL REASON TO DO THAT ?) but the
implementation for every NtXxxxx routine resides in NTOSKRNL.EXE.
There is also a parallel set ZwXxxxx but it looks the same as in user
mode.

Now some exposition on previous mode:
int 2e handler (KiSystemService) saves the mode of caller into current
thread
and it can be later obtained by calling [Ke-or-Ex]GetPreviousMode().
Depending
on the mode of the caller the NT API implementation makes some
differencies,
for example every pointer passed to every routine from user mode should
be probed
if the object to what it points really resides completely in user mode
space and also
if the pointer is properly aligned, also when referencing any handle the
ObReferenceObjectByHandle() accepts an argument AccessMode, which should
reflect the real caller’s mode, also when you call some other routines
like
KeWaitForSingleObject() etc. etc. In the case the IoManager passes an
Irp to
some driver this caller’s mode is stored in Irp->RequestorMode because
most of drivers can’t bank on the context in which are called is really
the
requestor’s one. So this information isn’t lost but is saved in the Irp.

And finally the conclusion:
So it doesn’t matter what routine you use in user mode (both represent
really
the same code) and the call finally ends in kernel mode in routine
NtXxxxx with
previous mode set to UserMode.

But when you call ZwXxxx in kernel mode, you can be sure the routine
knows
that its caller was kernel mode code and not the user mode one (it’s
ensured
by KiSystemService like described above, it save current thread previous
mode
to the stack and sets the new one depending on CS register bit 0 - it’s
always
set to one for user mode code [CPL=3] but is always zero [CPL=0] for
kernel code).
The result effect is that you can pass kernel mode pointers to it, you
have
all privileges by default (so every call to Ps[Single]PrivileCheck()
returns TRUE)
and you have many others advantages against the more restricted user
mode code.
But this also has the dark side in that when you does something
incorrectly you
can crash whole operating system and the machine. So you must be very
careful -
at least like when you call every other executive support routine,
KeXxxx, MmXxxx,
IoXxxxxx, PsXxxxxx, … )

At the other side when you call NtXxxx in the kernel mode without you
are absolutely
sure the previous mode in the current thread is already set to kernel
mode (which is
true for example in every worker thread which by definition doesn’t have
any user
mode context) you can have troubles if the previous mode is set to user
mode.
In that case every routine which takes some pointer should return
STATUS_ACCESS_VIOLATION
because you probably pass kernel mode address to it but it thinks the
caller was in user
mode and this is not allowed for user mode code.
So you have the choice what routine to call only in a small amount of
routines which
don’t take any pointer like in NtClose/ZwClose or
NtMakeTemporaryObject/ZwMakeTemporaryObject.

The question which myself have to someone at Microsoft is what the Zw
stands for ?

Hope this helps to better understanding the NT API.

Paul

-----Original Message-----
From: xxxxx@lists.osr.com [
mailto:xxxxx
> mailto:xxxxx@lists.osr.com]On Behalf Of Pashupati Kumar
> Sent: Tuesday, June 12, 2001 12:07 PM
> To: NT Developers Interest List
> Subject: [ntdev] Re: confusion?
>
>
>
> > hi ,
> > can anybody please solve my confusion.
> > i am reading inside windows2000.
> >
> > it says the calls go like this
> > ( user mode )
> > WriteFile->NtwriteFile->Int2E->NtWriteFile->the actual
> > work.( kernel mode )
> >
> > in DDk there is this function called ZwWritefile.
> > When is this called?
>
> ZwWriteFile is interface given for NtWriteFile in Kernelmode. It also
> calls
> NtWriteFile finally
>
> so, ZwCreateFile->NtWriteFile
> ( parameter validation is not done + int2e is not required )
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@compelson.com
> To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com
>
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@Legato.COM
> To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

—
You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com</mailto:xxxxx>

It really depends , in fact , by the previous mode stored in
KTHREAD->PreviousMode , and also , a valid pointer to a TRAP_FRAME loaded
into KTHREAD->TrapFrame

in ntoskrnl.exe , ZwXxxxXxxx are only wrappers , arround a Int2E , or in
Windows XP,
arround a simulated interrupt. Validation is done considering PreviousMode.
It is crucial to understand that ZwXxxx is only a wrapper , and Pavel Hrdina
correctly outlined the isssue.
Check _KiSystemService implementation , and a syscall of your choiche , for
example NtCreateFile.

In ntdll.dll , both Zw and Nt points to the very same stub , wrapped over a
Int2e , or , in WinXP , when CPU allows , arround a sysenter instruction.

----- Original Message -----
From: “Pashupati Kumar”
To: “NT Developers Interest List”
Sent: Wednesday, June 13, 2001 7:21 AM
Subject: [ntdev] Re: confusion?

> One crucial point being missed is memory address validation in two
routines.
> If you are using NtXXXX routines, it always expects a virtul memory adress
> location in user mode( 2GB /3GB), where as in ZwXXX expects address
location
> in kernel mode.If you try using NTXXX routines in Kernel memory, one gets
> error to the above fact and same holds true ZwXXX routines in user mode.
> We can conclude that NTXXX calls are like system calls avaible on UNIX
> platforms( where this memory address validation is done, one cann’t use
> system call from kernel)
>
>
>
> > The description of reality is slightly different and haven’t appeared
> > yet so here it is.
> > (For the rest of this explanation we assume the service table number 0 =
> > Native NT API)
> > Listen carefully all of you who don’t know much about it ! (and also you
> > from Microsoft)
> >
> > Introduction:
> > There are two modes - kernel mode and user mode
> > and two sets of Native NT API - NtXxxxx and ZwXxxxx.
> >
> > In user mode (represented by NTDLL.DLL) whole number of routines
> > in both sets is exported, but every routine is really a stub:
> > mov eax, ServiceNumber
> > lea edx, [esp+4]
> > int 2e
> > ret xx
> > In addition both export names (for eg. NtCreatePort and ZwCreatePort)
> > points to the same stub so it really doesn’t matter which set you use.
> > It really doesn’t have any other effect than the name in your import
> > table.
> >
> > In kernel mode the situation is different. Not all routines are exported
> > (who knows why ? it really seems as a restrictive interntion for non-
> > bultin-NT-executive components made by Microsoft, but I’m asking
> > WHAT WAS THE RATIONAL REASON TO DO THAT ?) but the
> > implementation for every NtXxxxx routine resides in NTOSKRNL.EXE.
> > There is also a parallel set ZwXxxxx but it looks the same as in user
> > mode.
> >
> > Now some exposition on previous mode:
> > int 2e handler (KiSystemService) saves the mode of caller into current
> > thread
> > and it can be later obtained by calling [Ke-or-Ex]GetPreviousMode().
> > Depending
> > on the mode of the caller the NT API implementation makes some
> > differencies,
> > for example every pointer passed to every routine from user mode should
> > be probed
> > if the object to what it points really resides completely in user mode
> > space and also
> > if the pointer is properly aligned, also when referencing any handle the
> > ObReferenceObjectByHandle() accepts an argument AccessMode, which should
> > reflect the real caller’s mode, also when you call some other routines
> > like
> > KeWaitForSingleObject() etc. etc. In the case the IoManager passes an
> > Irp to
> > some driver this caller’s mode is stored in Irp->RequestorMode because
> > most of drivers can’t bank on the context in which are called is really
> > the
> > requestor’s one. So this information isn’t lost but is saved in the Irp.
> >
> > And finally the conclusion:
> > So it doesn’t matter what routine you use in user mode (both represent
> > really
> > the same code) and the call finally ends in kernel mode in routine
> > NtXxxxx with
> > previous mode set to UserMode.
> >
> > But when you call ZwXxxx in kernel mode, you can be sure the routine
> > knows
> > that its caller was kernel mode code and not the user mode one (it’s
> > ensured
> > by KiSystemService like described above, it save current thread previous
> > mode
> > to the stack and sets the new one depending on CS register bit 0 - it’s
> > always
> > set to one for user mode code [CPL=3] but is always zero [CPL=0] for
> > kernel code).
> > The result effect is that you can pass kernel mode pointers to it, you
> > have
> > all privileges by default (so every call to Ps[Single]PrivileCheck()
> > returns TRUE)
> > and you have many others advantages against the more restricted user
> > mode code.
> > But this also has the dark side in that when you does something
> > incorrectly you
> > can crash whole operating system and the machine. So you must be very
> > careful -
> > at least like when you call every other executive support routine,
> > KeXxxx, MmXxxx,
> > IoXxxxxx, PsXxxxxx, … )
> >
> > At the other side when you call NtXxxx in the kernel mode without you
> > are absolutely
> > sure the previous mode in the current thread is already set to kernel
> > mode (which is
> > true for example in every worker thread which by definition doesn’t have
> > any user
> > mode context) you can have troubles if the previous mode is set to user
> > mode.
> > In that case every routine which takes some pointer should return
> > STATUS_ACCESS_VIOLATION
> > because you probably pass kernel mode address to it but it thinks the
> > caller was in user
> > mode and this is not allowed for user mode code.
> > So you have the choice what routine to call only in a small amount of
> > routines which
> > don’t take any pointer like in NtClose/ZwClose or
> > NtMakeTemporaryObject/ZwMakeTemporaryObject.
> >
> > The question which myself have to someone at Microsoft is what the Zw
> > stands for ?
> >
> > Hope this helps to better understanding the NT API.
> >
> > Paul
> >
> >
> > -----Original Message-----
> > From: xxxxx@lists.osr.com [
> > mailto:xxxxx
> > mailto:xxxxx@lists.osr.com]On Behalf Of Pashupati Kumar
> > Sent: Tuesday, June 12, 2001 12:07 PM
> > To: NT Developers Interest List
> > Subject: [ntdev] Re: confusion?
> >
> >
> >
> > > hi ,
> > > can anybody please solve my confusion.
> > > i am reading inside windows2000.
> > >
> > > it says the calls go like this
> > > ( user mode )
> > > WriteFile->NtwriteFile->Int2E->NtWriteFile->the actual
> > > work.( kernel mode )
> > >
> > > in DDk there is this function called ZwWritefile.
> > > When is this called?
> >
> > ZwWriteFile is interface given for NtWriteFile in Kernelmode. It also
> > calls
> > NtWriteFile finally
> >
> > so, ZwCreateFile->NtWriteFile
> > ( parameter validation is not done + int2e is not required )
> >
> >
> > —
> > You are currently subscribed to ntdev as: xxxxx@compelson.com
> > To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com
> >
> >
> >
> > —
> > You are currently subscribed to ntdev as: xxxxx@Legato.COM
> > To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com
>
>
> —
> You are currently subscribed to ntdev as: danp@jb.rdsor.ro
> To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com
>

—
You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com</mailto:xxxxx>