I have this following code, but i'm with trouble of AV in NtOpenFile() (of HandleFile(POBJECT_ATTRIBUTES poa) ) returning 0xC0000005 STATUS_ACCESS_VIOLATION.
Follows: DbgPrint + complete code (tested on Win 7 x86 inside a VirtualBox, listing folders/files of Windows Media Player (off) ).
PS: usermode application sends path name to driver.
How solve?
Follows: DbgPrint + complete code (tested on Win 7 x86 inside a VirtualBox, listing folders/files of Windows Media Player (off) ).
PS: usermode application sends path name to driver.
How solve?
Code: Select all
#include <ntifs.h>
#include <WinDef.h>
#define ALLOCSIZE PAGE_SIZE
//#define _REAL_DELETE_
#ifdef _REAL_DELETE_
#define USE_DELETE_ON_CLOSE FILE_DELETE_ON_CLOSE
#define FILE_ACCESS FILE_GENERIC_READ|DELETE
#else
#define USE_DELETE_ON_CLOSE FILE_DIRECTORY_FILE
#define FILE_ACCESS FILE_GENERIC_READ
#endif
#define echo(x) x
#define label(x) echo(x)__LINE__
#define RTL_CONSTANT_STRINGW(s) { sizeof( s ) - sizeof( (s)[0] ), sizeof( s ),(PWSTR)(s) }
#define STATIC_UNICODE_STRING(name, str) static const WCHAR label(__)[] = L##str; static const UNICODE_STRING name = RTL_CONSTANT_STRINGW(label(__))
#define STATIC_OBJECT_ATTRIBUTES(oa, name) STATIC_UNICODE_STRING(label(m), name); static OBJECT_ATTRIBUTES oa = { sizeof oa, 0, (PUNICODE_STRING)&label(m), OBJ_CASE_INSENSITIVE }
NTKERNELAPI NTSTATUS ZwQueryDirectoryFile(IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass,
IN BOOLEAN ReturnSingleEntry,
IN PUNICODE_STRING FileName OPTIONAL,
IN BOOLEAN RestartScan);
NTSYSCALLAPI NTSTATUS NTAPI NtClose(HANDLE);
TSTATUS HandleFile(POBJECT_ATTRIBUTES poa, UNICODE_STRING us)
{
IO_STATUS_BLOCK iosb;
HANDLE hFile;
NTSTATUS status;
DbgPrint("FileName....: %wZ \n", &us);
if (0 <= (status = NtOpenFile(&hFile, FILE_READ_ATTRIBUTES, poa, &iosb, FILE_SHARE_VALID_FLAGS, 0)))
{
NtClose(hFile);
}
DbgPrint("NtOpenFile(): 0x%X \n", status);
return status;
}
void ntTraverse(POBJECT_ATTRIBUTES poa, ULONG FileAttributes, int nLevel, PSTR prefix)
{
if (IoGetRemainingStackSize() < PAGE_SIZE)
{
DbgPrint("no stack!\n");
return;
}
if (!nLevel)
{
DbgPrint("!nLevel\n");
return;
}
NTSTATUS status;
IO_STATUS_BLOCK iosb;
UNICODE_STRING ObjectName;
OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, &ObjectName };
DbgPrint("DIRECTORY...: %s[<%wZ>]\n", prefix, poa->ObjectName);
#ifdef _REAL_DELETE_
if (FileAttributes & FILE_ATTRIBUTE_READONLY)
{
if (0 <= ZwOpenFile(&oa.RootDirectory, FILE_WRITE_ATTRIBUTES, poa, &iosb, FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REPARSE_POINT))
{
FILE_BASIC_INFORMATION fbi = { 0 };
fbi.FileAttributes = FILE_ATTRIBUTE_NORMAL;
ZwSetInformationFile(oa.RootDirectory, &iosb, &fbi, sizeof(fbi), FileBasicInformation);
NtClose(oa.RootDirectory);
}
}
#endif
if (0 <= (status = ZwOpenFile(&oa.RootDirectory, FILE_ACCESS, poa, &iosb, FILE_SHARE_VALID_FLAGS,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_REPARSE_POINT | FILE_OPEN_FOR_BACKUP_INTENT | USE_DELETE_ON_CLOSE)))
{
if (FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
PVOID buffer = ExAllocatePoolWithTag(PagedPool, ALLOCSIZE, 'tset');
if (buffer)
{
union Data {
PVOID pv;
PBYTE pb;
PFILE_DIRECTORY_INFORMATION DirInfo;
};
union Data data;
while (0 <= (status = ZwQueryDirectoryFile(oa.RootDirectory, NULL, NULL, NULL, &iosb,
data.pv = buffer, ALLOCSIZE, FileDirectoryInformation, 0, NULL, FALSE)))
{
ULONG NextEntryOffset = 0;
do
{
data.pb += NextEntryOffset;
ObjectName.Buffer = data.DirInfo->FileName;
switch (ObjectName.Length = (USHORT)data.DirInfo->FileNameLength)
{
case 2 * sizeof(WCHAR) :
if (ObjectName.Buffer[1] != '.') break;
case sizeof(WCHAR) :
if (ObjectName.Buffer[0] == '.') continue;
}
ObjectName.MaximumLength = ObjectName.Length;
#ifndef _REAL_DELETE_
if (data.DirInfo->FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
#endif
{
ntTraverse(&oa, data.DirInfo->FileAttributes, nLevel - 1, prefix - 1);
}
#ifndef _REAL_DELETE_
else
#endif
{
//DbgPrint("%s%8I64u <%wZ>\n", prefix, data.DirInfo->EndOfFile.QuadPart, &ObjectName);
HandleFile(&oa, ObjectName);
}
} while (NextEntryOffset = data.DirInfo->NextEntryOffset);
if (ALLOCSIZE - iosb.Information > FIELD_OFFSET(FILE_DIRECTORY_INFORMATION, FileName[256]))
{
break;
}
}
ExFreePoolWithTag(buffer, 'tset');
if (status == STATUS_NO_MORE_FILES)
{
status = STATUS_SUCCESS;
}
}
}
NtClose(oa.RootDirectory);
}
if (0 > status)
{
DbgPrint("---- %x %wZ\n", status, poa->ObjectName);
}
}
void ntTraverse_()
{
char prefix[MAXUCHAR + 1];
memset(prefix, '\t', MAXUCHAR);
prefix[MAXUCHAR] = 0;
STATIC_OBJECT_ATTRIBUTES(oa, "\\??\\C:\\Program Files\\Windows Media Player");
ntTraverse(&oa, FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_READONLY, MAXUCHAR, prefix + MAXUCHAR);
}