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.
-
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.
-
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):
-
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.
-
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:
- 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.
-
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.
-
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.
- 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