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>