Address of Page Frame Number Database

Dear All

Windows maintains the status of physical pages using the Page Frame Number database. This is the database read by the extension !memusage, !pfn etc. How do I find out the address of the pfn database in memory. Is the source code of the above windbg extensions publically available.

Thank you in advance for any answers.

Vijay Mukhi

VIJAY:

THE LONG AND SHORT: The symbol (which I can’t remember the name of
offhand) is not exported, so you are down to more imaginative solutions,
assuming you have the need and a situation that can tolerate techniques
such as these.

Of course, in keeping with the mantra of this list, I would point out
that all of these techniques, to varying degrees, are likely to break
with os version changes. That being said, if you are willing to put in
the time, some of these techniques can be developed, for a specific case
only, to the point that they are quite safe to use in the sense that it
is possible to determine when you can not proceed safely and just have
to bail out.

  1. The source code for !memusage is not available. However, take a
    look at the Debug Engine Reference in the WinDbg documentation. There
    are a few “interfaces” that can be used (IDebugSymbol in this case, I
    think) to find this information. In fact, the only thing that prevents
    this from being straightforward is that the documentation is, well,
    among the worst I have ever seen. As an added bonus, the interfaces are
    conveniently modeled after COM, and, as such, present the usual
    inconveniences and absolutely horrendous error reporting, with, in this
    case, none of the benefits, as the are not derived from IUnknown.

  2. There is a symbol for the the Page Frame Number Data
    (MmPageFrameDatabase - I think; I don’t have a KD running, and I’m about
    to head out the door), but it is not exported. Accordingly, the closest
    thing to a documented way to do this is to lookup the symbol using a
    debugger extension or something like that. As this is seldom practical,
    here are a few other ways that you can use to try to locate it. I have
    used all of them succesfully in situations similar to this. These
    techniques all fall in to the category of inadvisable except as a last
    resort, but, if you need it, this is where you stand (in no particular
    order, as they vary widely by use):

  3. Use DbgHelp to locate the correct PDB for a specific kernel and
    to parse the symbols. DIA would also work, possibly better under some
    circumstances. This, of course, assumes that you are running in user
    mode. If you can not use either of these, but still have access to the
    correct PDB, it is possible to parse the PDB directly to resolve the
    symbol. I’ve done this for something not terribly related to this, and,
    to be sure, it really sucked. The format of the PDB shell itself is not
    documented, but between Undocumented Windows 2000 Secrets and WINE,
    there is enough information to get to the global types and symbols,
    which are what you are interested in. The format of these were
    documented by Microsoft a few years back (CodeView), and with the
    supplemental source already mentioned, you can, after much work,
    reproduce global symbol information, and complete types as well. I
    imagine that is possible to construct more complicated things, like
    local symbols; I’ve never tried.

  4. Obtain the address of the processor control region; one of the
    undocumented reserved members points to the a KDDBG_GET_VERSION
    structure, which iteself contains the head of a list of
    KDDBG_DEBUG_BLOCK debugger data blocks. The structure names are
    aproximate (I don’t recall them off hand); the details can be obtained
    using dt -b -v nt!_KD* and dt -b -v nt!_DBG*. One of the members of the
    debugger data block is the offset of the pfn symbol. There is obviously
    a lot of grey here. The details of this are complicated, but, for
    equally complicated reasons, this technique is amazingly stable, and
    very profitable, as the debugger data block has an enormous number of
    variables that have the offsets to non-exported kernel symbols, as long
    as one invariant holds: the system must not be booted with /NODEBUG. If
    this is an option, I would recommend using this method.

And if you are truly desperate and have a lot of time to kill:

  1. Disassemble an exported kernel function that references the
    symbol, and use the result to develop a heuristic to find the reference
    to the symbol, given the address of the referencing function, which can
    be determined using MmGetSystemRoutineAddress. This is, to say the
    least, very complicated and non-deterministic stuff, but sometimes it is
    your only shot if the need is there. This is decidedly a last resort,
    and it is that only if the disassembly looks promising.

Hope this helps,

MM

>> xxxxx@vsnl.com 2006-09-06 02:52 >>>
Dear All

Windows maintains the status of physical pages using the Page Frame
Number database. This is the database read by the extension !memusage,
!pfn etc. How do I find out the address of the pfn database in memory.
Is the source code of the above windbg extensions publically available.

Thank you in advance for any answers.

Vijay Mukhi


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Dear Martin
Thank you vey much for the very useful reply. I used the following code to get the non exported variable MmPfnDatabase. 0xe8 is the offset of the MmPfnDataBase
#include <ntddk.h>
VOID OnUnload(PDRIVER_OBJECT DriverObject )
{
DbgPrint(“Unload5”);
}
NTSTATUS DriverEntry(PDRIVER_OBJECT d,PUNICODE_STRING r)
{
long MmPfnDatabase = *(long )(((long *)0x0ffdff034) + 0xe8);
DbgPrint( “0x%X”, MmPfnDatabase);
d->DriverUnload = OnUnload;
return STATUS_SUCCESS;
}

My question is how do I now read the undocumented pfnd structures. Is there any code that reads pfn structures on the publically available. Thanking all of you once again.

Vijay Mukhi
Helios</ntddk.h>

Windows kernel provides no ways for drivers to do this. WinDbg’s extension
require the symbols to work.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

----- Original Message -----
From:
To: “Windows System Software Devs Interest List”
Sent: Wednesday, September 06, 2006 10:52 AM
Subject: [ntdev] Address of Page Frame Number Database

> Dear All
>
> Windows maintains the status of physical pages using the Page Frame Number
database. This is the database read by the extension !memusage, !pfn etc. How
do I find out the address of the pfn database in memory. Is the source code of
the above windbg extensions publically available.
>
> Thank you in advance for any answers.
>
> Vijay Mukhi
>
> —
> Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

> 1. There is a symbol for the the Page Frame Number Data

(MmPageFrameDatabase - I think; I don’t have a KD running, and I’m about

MmPfnDatabase

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

> Thank you vey much for the very useful reply. I used the following code to
get the

non exported variable MmPfnDatabase. 0xe8 is the offset of the
MmPfnDataBase

The next Windows version or even service pack or even hotfix will break this.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

VIJAY:

Sorry it has taken so long for me to get back to you. It was a late
night, and I’m getting a late start today.

In any case, I do not know of any publicly available sources of code
that works with the PFN database; I have written code like this, and it
is not that difficult, but, unfortunately, I may not share it. However,
here are a few basic recommendations/things to consider/places to
start.

  1. As with so many things discussed on this list, an excellent places
    to start is Windows Internals 4. It provides an excellent overview,
    and, while there is no actual code, there is quite a bit of detail about
    the layout of some of the data.

  2. dt -v nt!_MM* & symbols

Take a look at all of the types that begin with this pattern: _MM* &
MM*. In particular, _MMPFN & _MMPFNENTRY. Depending on what you are
interested in accomplishing, some of the types involved are not normally
public (such as the definition of the debugger data block). If you can
get your hands on the 5270 WDK, do so. This is the WDK that went out
the door with the private symbols intact. It has since been pulled, and
I don’t think that it is legal to redistribute it, so if you don’t have
it, you’re out of luck, legally speaking. If you do, bear in mind that
the types are for a version of Windows that you are very unlikely to be
using, so you will still have to adjust some of them to suit the version
of Windows which you examine.

  1. Create C structs from PDB

Whatever symbol files you can get a hold of, one of the best things you
can do, in my opinion, is to write a program to create C structures for
all of the types contained in a pdb. I find it amazing how much one can
learn just by looking a list of all of the structure names. Three
relatively easy ways to do this are to either parse the output from
DiaDump2 (which comes with the DIA SDK), modify the source for the same
to suit your needs, or process the output from dt -b -v. In the case of
the first method, and to a lesser extent the second, be advised that
anonymous structures and unions present a significant problem.

I hope that this helps,

MM

>> xxxxx@vsnl.com 2006-09-06 05:31 >>>
Dear Martin
Thank you vey much for the very useful reply. I used the following code
to get the non exported variable MmPfnDatabase. 0xe8 is the offset of
the MmPfnDataBase
#include <ntddk.h>
VOID OnUnload(PDRIVER_OBJECT DriverObject )
{
DbgPrint(“Unload5”);
}
NTSTATUS DriverEntry(PDRIVER_OBJECT d,PUNICODE_STRING r)
{
long MmPfnDatabase = *(long )(((long *)0x0ffdff034) + 0xe8);
DbgPrint( “0x%X”, MmPfnDatabase);
d->DriverUnload = OnUnload;
return STATUS_SUCCESS;
}

My question is how do I now read the undocumented pfnd structures. Is
there any code that reads pfn structures on the publically available.
Thanking all of you once again.

Vijay Mukhi
Helios


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer</ntddk.h>

It very well may. Such is the nature of this problem. If you have
need, then you must handle different versions in your code.

>> xxxxx@storagecraft.com 2006-09-06 13:13 >>>
Thank you vey much for the very useful reply. I used the following
code to
get the
non exported variable MmPfnDatabase. 0xe8 is the offset of the
MmPfnDataBase

The next Windows version or even service pack or even hotfix will break
this.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer