📄 fspykd.c
字号:
// Display name
//
xGetFieldValue( Address,
"FileSpy!_FILESPY_DEVICE_EXTENSION",
"UserNames.Length",
length );
xGetFieldValue( Address,
"FileSpy!_FILESPY_DEVICE_EXTENSION",
"UserNames.Buffer",
pName );
memRetVal = ReadMemory( pName, buffer, (ULONG)length, &result);
if (memRetVal && (result == (ULONG)length)) {
string1.Length = string1.MaximumLength = length;
string1.Buffer = (PWSTR) buffer;
dprintf( "\n\t %s %wZ",
"UserNames ",
&string1 );
}
} else {
dprintf( "\nNot a valid option" );
}
dprintf( "\n" );
}
VOID
DumpAttachments (
IN LONG Options,
USHORT Processor,
HANDLE hCurrentThread
)
/*++
Routine Description:
Dump the list of attached devices that is global to FileSpy.
Arguments:
Options - Ignored for now
Return Value:
None
--*/
{
ULONG64 address, next;
ULONG64 deviceExtensionAddress;
ULONG linkOffset;
UNREFERENCED_PARAMETER( Processor );
UNREFERENCED_PARAMETER( hCurrentThread );
address = GetExpression( "FileSpy!gSpyDeviceExtensionList" );
dprintf( "\nAttachedDeviceList: %08p", address );
//
// Establish offset of the linking entry..
//
xGetFieldOffset( "FileSpy!_FILESPY_DEVICE_EXTENSION",
"NextFileSpyDeviceLink",
&linkOffset );
xGetFieldValue( address, "nt!_LIST_ENTRY", "Flink", next );
while (next != address) {
deviceExtensionAddress = (next - linkOffset);
// i.e., CONTAINING_RECORD( next, _FILESPY_DEVICE_EXTENSION, NextFileSpyDeviceLink );
DumpDeviceExtension( deviceExtensionAddress,
Options,
Processor,
hCurrentThread );
if (CheckControlC()) {
return;
}
xGetFieldValue( next, "nt!_LIST_ENTRY", "Flink", next );
}
}
VOID
DumpFileNameCache (
IN LONG Options,
USHORT Processor,
HANDLE hCurrentThread
)
/*++
Routine Description:
Dump all the fileObjects and file names that are currently in the
file name cache
Arguments:
Options - 1 dumps just the file objects and file names
2 dumps the hash bucket labels along with the file objects
and file names
Return Value:
None
--*/
{
ULONG64 address;
ULONG64 next;
ULONG64 pName;
ULONG64 fileObject;
ULONG64 pHashEntry;
ULONG length;
ULONG result;
ULONG linkOffset;
UNICODE_STRING string;
LIST_ENTRY64 listEntry;
PUCHAR buffer;
INT i;
ULONG nameCount = 0;
UNREFERENCED_PARAMETER( Processor );
UNREFERENCED_PARAMETER( hCurrentThread );
address = GetExpression( "FileSpy!gHashTable" );
dprintf( "\nHashTable: %08p\n", address );
dprintf( " FileObject Length FileName\n" );
dprintf( " -----------------------------------------\n" );
xGetFieldOffset( "FileSpy!_HASH_ENTRY", "List", &linkOffset );
for (i=0; i < HASH_SIZE; i++) {
if (!ReadListEntry(address, &listEntry)) {
dprintf( "Can't read hash table\n" );
return;
}
if (Options > 1) {
dprintf ( "Hash Bucket[%3d]\n", i );
}
next = listEntry.Flink;
while (next != address) {
pHashEntry = next - linkOffset;// CONTAINING_RECORD( next, HASH_ENTRY, List );
xGetFieldValue( pHashEntry,
"FileSpy!_HASH_ENTRY",
"FileObject",
fileObject );
xGetFieldValue( pHashEntry,
"FileSpy!_HASH_ENTRY",
"Name.Length",
length );
//
// Get the names buffer pointer
//
xGetFieldValue( pHashEntry,
"FileSpy!_HASH_ENTRY",
"Name.Buffer",
pName );
//
// Allocate buffer to hold the string
//
buffer = LocalAlloc(LPTR, length);
if (buffer != NULL) {
string.MaximumLength = string.Length = (USHORT) length;
string.Buffer = (PWSTR) buffer;
if (ReadMemory( pName,
buffer,
length,
&result ) && (result == length)) {
dprintf (" %08p %4d %wZ\n",
fileObject,
length/sizeof(WCHAR),
&string );
}
//
// Free the buffer
//
LocalFree( buffer );
buffer = NULL;
} else {
dprintf( "\nCould not allocate buffer to hold filename\n" );
}
nameCount ++;
if (CheckControlC()) {
dprintf( "%u Names in cache\n", nameCount );
return;
}
if (!ReadListEntry(next, &listEntry)) {
dprintf( "Can't read hash table\n" );
return;
}
next = listEntry.Flink;
}
//
// Advance address to next hash entry
//
if (IsPtr64()) {
address += sizeof(LIST_ENTRY64);
} else {
address += sizeof(LIST_ENTRY);
}
}
dprintf( "%u Names in cache\n", nameCount );
}
VOID
ParseAndDump (
IN PCSTR args,
IN PSTRUCT_DUMP_ROUTINE DumpFunction,
USHORT Processor,
HANDLE hCurrentThread
)
/*++
Routine Description:
Parse command line arguments and dump an NTFS structure.
Arguments:
Args - String of arguments to parse.
DumpFunction - Function to call with parsed arguments.
Return Value:
None
--*/
{
UCHAR StringStructToDump[1024]; // See other KD routines for size
ULONG64 StructToDump = 0;
LONG Options = 0;
//
// If the caller specified an address then that's the item we dump
//
if (args) {
StructToDump = 0;
Options = 0;
StringStructToDump[0] = '\0';
(VOID) sscanf( args,"%s %lx", StringStructToDump, &Options );
StructToDump = GetExpression( StringStructToDump );
if (StructToDump == 0) {
dprintf( "unable to get expression %s\n",StringStructToDump );
return;
}
(*DumpFunction) ( StructToDump, Options, Processor, hCurrentThread );
dprintf( "\n" );
} else {
PrintHelp();
}
}
VOID
PrintHelp (
VOID
)
/*++
Routine Description:
Dump out one line of help for each DECLARE_API
Arguments:
None
Return Value:
None
--*/
{
int i;
for( i=0; Extensions[i]; i++ ) {
dprintf( " %s\n", Extensions[i] );
}
}
DECLARE_API( devext )
/*++
Routine Description:
Dump device extension struct
Arguments:
arg - [Address] [options]
Return Value:
None
--*/
{
UNREFERENCED_PARAMETER( dwCurrentPc );
UNREFERENCED_PARAMETER( hCurrentProcess );
ParseAndDump(args,
(PSTRUCT_DUMP_ROUTINE) DumpDeviceExtension,
(USHORT)dwProcessor,
hCurrentThread );
}
DECLARE_API( attachments )
/*++
Routine Description:
Dumps the list of devices we are currently attached to
Arguments:
arg - [options]
Return Value:
None
--*/
{
LONG options = 0;
UNREFERENCED_PARAMETER( dwCurrentPc );
UNREFERENCED_PARAMETER( hCurrentProcess );
(VOID)sscanf( args,"%lx", &options );
DumpAttachments( options, (USHORT)dwProcessor, hCurrentThread );
dprintf( "\n" );
}
DECLARE_API( filenames )
/*++
Routine Description:
Dumps all the entries in the file name cache
Arguments:
arg -
Return Value:
None
--*/
{
LONG options = 0;
UNREFERENCED_PARAMETER( dwCurrentPc );
UNREFERENCED_PARAMETER( hCurrentProcess );
(VOID)sscanf( args,"%lx", &options );
DumpFileNameCache( options, (USHORT)dwProcessor, hCurrentThread );
}
DECLARE_API( help )
/*++
Routine Description:
Dump the help for this debugger extension module.
Arguments:
arg - None
Return Value:
None
--*/
{
UNREFERENCED_PARAMETER( args );
UNREFERENCED_PARAMETER( dwCurrentPc );
UNREFERENCED_PARAMETER( hCurrentProcess );
UNREFERENCED_PARAMETER( hCurrentThread );
UNREFERENCED_PARAMETER( dwProcessor );
PrintHelp();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -