Converting MDL from NonPagedPool to Locked?

I tracked down the source of the asserts under Checked WinXPSP2 during
MmMapLockedPages*(). I am creating an MDL for read-only kernel code VA
using IoAllocateMdl, and then call MmBuildMdlForNonPagedPool to add the
underlying physical pages to the MDL.

But, the resulting MDL has the MDL_SOURCE_IS_NONPAGED_POOL flag set, even
though the VA wasn’t alloc’ed from NPP but was part of a Non-paged code
segment. Because I can’t find a call for MmBuildMdlForNonPagedCodeSegment,
I “updated” the MDL flags by removing MDL_SOURCE_IS_NONPAGED_POOL and
adding MDL_PAGES_LOCKED. Now, I can use the MDL in MmMapLockedPages*
without problems.

This raises two questions:

First, is there a difference between non-paged and locked Virtual
addresses? If some code was originally paged, but then was locked,
would it be the same as NonPaged code (not NonPagedPool)? It seems
that NPP exists in a reserved memory range and that any non-paged
memory outside that range cannot be referred to as NonPaged “Pool”.

Second, since the “proper” system calls don’t exist for building an
MDL for non-paged but not non-paged-pool memory, what are the likely
consequences of my manipulation of MDL flags? I used the ntddk.h
struct and flag defs to minimize issues if things change, but I
doubt that Microsoft would bless this in any way. Or should I try
to find a way to build partial MDLs that eventually have the right
MDL flags?

Before you ask why I need to do this, I’m working with a major
security tool company to create a callback interface like that in
cmRegisterCallback, but for pre-process creation, termination, read,
write, etc. so that another driver (talking to a user-mode app)
can control the behavior by returning non-success in the Callback.

The official CreateProcess/Thread callbacks occur AFTER the process
creation, termination, etc., where it is too late to veto the request.


Oh, great Microsoft. If you could create back-ported callback
services for cmRegisterCallback and processRegisterCallback, you
would see a tremendous decrease in the number of drivers trying
to hook internal jump tables in the kernel. Adding them for
longhorn alone is not sufficient unless you can guarantee that all
other OS versions can be deactivated the day longhorn releases.


Suggestions, comments welcome. Flames about hooking the kernel
are not.

Jerry Schneider

You do realize, that your complaint about the process call backs is only
partially correct, I hope. Yes the process has been created, but it is
empty! No module has been loaded, no code has been run! The load image
notify is called when the module is loaded but before returning to the user
space.

If you think about these statements, you will see you can do this without
the dangerous, and non-portable hacks you are trying to do. Yes, it would
be nice if Microsoft would strengthen the callback functions and define a
clean model for stopping execution, but this type of hack is ridiculous.
Before you say but you need if for security, I have worked with a firm that
was founded by all ex-CIA and ex-NSA types, the product was to protect
systems for unspecified customers, and we did not hack the kernel this way!


Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Remove StopSpam from the email to reply

“Jerry Schneider” wrote in message news:xxxxx@ntdev…
>I tracked down the source of the asserts under Checked WinXPSP2 during
> MmMapLockedPages*(). I am creating an MDL for read-only kernel code VA
> using IoAllocateMdl, and then call MmBuildMdlForNonPagedPool to add the
> underlying physical pages to the MDL.
>
> But, the resulting MDL has the MDL_SOURCE_IS_NONPAGED_POOL flag set, even
> though the VA wasn’t alloc’ed from NPP but was part of a Non-paged code
> segment. Because I can’t find a call for MmBuildMdlForNonPagedCodeSegment,
> I “updated” the MDL flags by removing MDL_SOURCE_IS_NONPAGED_POOL and
> adding MDL_PAGES_LOCKED. Now, I can use the MDL in MmMapLockedPages*
> without problems.
>
> This raises two questions:
>
> First, is there a difference between non-paged and locked Virtual
> addresses? If some code was originally paged, but then was locked,
> would it be the same as NonPaged code (not NonPagedPool)? It seems
> that NPP exists in a reserved memory range and that any non-paged
> memory outside that range cannot be referred to as NonPaged “Pool”.
>
>
> Second, since the “proper” system calls don’t exist for building an
> MDL for non-paged but not non-paged-pool memory, what are the likely
> consequences of my manipulation of MDL flags? I used the ntddk.h
> struct and flag defs to minimize issues if things change, but I
> doubt that Microsoft would bless this in any way. Or should I try
> to find a way to build partial MDLs that eventually have the right
> MDL flags?
>
>
> Before you ask why I need to do this, I’m working with a major
> security tool company to create a callback interface like that in
> cmRegisterCallback, but for pre-process creation, termination, read,
> write, etc. so that another driver (talking to a user-mode app)
> can control the behavior by returning non-success in the Callback.
>
> The official CreateProcess/Thread callbacks occur AFTER the process
> creation, termination, etc., where it is too late to veto the request.
>
>
>
> Oh, great Microsoft. If you could create back-ported callback
> services for cmRegisterCallback and processRegisterCallback, you
> would see a tremendous decrease in the number of drivers trying
> to hook internal jump tables in the kernel. Adding them for
> longhorn alone is not sufficient unless you can guarantee that all
> other OS versions can be deactivated the day longhorn releases.
>
>
> Suggestions, comments welcome. Flames about hooking the kernel
> are not.
>
> Jerry Schneider
>

Don Burn wrote:

You do realize, that your complaint about the process call backs is only
partially correct, I hope. Yes the process has been created, but it is
empty! No module has been loaded, no code has been run! The load image
notify is called when the module is loaded but before returning to the user
space.

I first tried those callbacks and indeed could post-kill an undesired
process. Trying to extend this to post-unTerminating a process was
where the Microsoft-blessed approach fell apart. Try to prevent a
rogue app from reading the physicalmemory of Winlogin to dup handles
found there, etc., etc.

If you think about these statements, you will see you can do this without
the dangerous, and non-portable hacks you are trying to do. Yes, it would
be nice if Microsoft would strengthen the callback functions and define a
clean model for stopping execution, but this type of hack is ridiculous.

Actually, the hacks, err hooks, can be implemented as error-free as the
best drivers can, considering how often quality drivers suffer from flaws
like the recent article on the try/except handler bug. Yes, when the next
service pack is publicly released, I will have had to carefully examine
all of my hooked functions, but as we know, service packs often break
things that have to be hot-fixed, so I may actually be ahead of most of
the application suppliers in finding the SP-induced bugs.

Before you say but you need if for security, I have worked with a firm that
was founded by all ex-CIA and ex-NSA types, the product was to protect
systems for unspecified customers, and we did not hack the kernel this way!

I will agree that with a virgin OS, proper security tools prevent many types
of infiltration. It is unlikely, however, that the 98 million home computers
that have one or more back-doors used to send spam, steal identities, and
act as proxies for DDS attacks, will format their drives and reinstall a
new OS and protection software before attempting to reload their apps. The
malware crisis demands a solution, at almost any cost, err hack.

There are good security products available that do hack the kernel safely,
but they are outnumbered by rootkits, spyware, keyloggers and other garbage
that hack and mangle the kernel. The risk of creating an unstable platform
is clearly tilted towards the dark side.

“Jerry Schneider” wrote in message news:xxxxx@ntdev…
>
> There are good security products available that do hack the kernel safely,
> but they are outnumbered by rootkits, spyware, keyloggers and other
> garbage
> that hack and mangle the kernel. The risk of creating an unstable
> platform
> is clearly tilted towards the dark side.

Please name one, everyone I have seen that does this stuff is crap.


Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Remove StopSpam from the email to reply

Hello Jerry,
Tuesday, March 22, 2005, 9:37:59 PM, you wrote:

JS> I tracked down the source of the asserts under Checked WinXPSP2 during
JS> MmMapLockedPages*(). I am creating an MDL for read-only kernel code VA
JS> using IoAllocateMdl, and then call MmBuildMdlForNonPagedPool to add the
JS> underlying physical pages to the MDL.
allocate mdl, call MmProbeAndLockPages with KernelMode and
IoModifyAccess and you won’t have to play with mdl flags. now the mdl
is ready for MmMapLockedPages*.


Best regards,
Ivona Prenosilova

> JS> I tracked down the source of the asserts under Checked WinXPSP2 during

JS> MmMapLockedPages*(). I am creating an MDL for read-only kernel code VA
JS> using IoAllocateMdl, and then call MmBuildMdlForNonPagedPool to add the
JS> underlying physical pages to the MDL.

ivona prenosilova wrote:

allocate mdl, call MmProbeAndLockPages with KernelMode and
IoModifyAccess and you won’t have to play with mdl flags. now the mdl
is ready for MmMapLockedPages*.

Actually, I already tried that. It seems that probe&lock pages
does set the LOCKED flag, but when I call MmBuildMdlForNonPagedPool,
the NonPagedPool MDL flag gets set as well. (The functions says it
is gonna create an MDL for NPP, after all…)

The MmMapLockedPages* call still ASSERTS if the NonPagedPool flag is
set in the MDL. It would seem I need to build the MDL with something
other than MmBuildMdlForNonPagedPool, since that sets the NPP flag.
Or find a way to map pages like a MmMapNonPagedPool that doesn’t exist.

I don’t know if it’s riskier to rely on some concoction of MDL build
calls that seems to work, or if it’s just better to use the DDK
symbols to clear the flag…

Thanks

Jerry