NtQueryDirectoryFile
Поиск файла в wNT в какой-либо директории заключается в просмотре всех
файлов этой директории и файлов всех ее поддиректорий. Для перечисления файлов
используется функция NtQueryDirectoryFile.
NTSTATUS NtQueryDirectoryFile(
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 FileInformationLength,
IN FILE_INFORMATION_CLASS FileInformationClass,
IN BOOLEAN ReturnSingleEntry,
IN PUNICODE_STRING FileName OPTIONAL,
IN BOOLEAN RestartScan
);
Для нас важны параметры FileHandle, FileInformation
и FileInformationClass. FileHandle - хэндл объекта директории, который может
быть получен с использованием функции NtOpenFile. FileInformation - указатель
на выделенную память, куда функция запишет необходимые данные.
FileInformationClass определяет тип записей в FileInformation.
FileInformationClass перечислимого типа, но нам необходимы только
четыре его значения, используемые для просмотра содержимого директории.
#define FileDirectoryInformation 1
#define FileFullDirectoryInformation 2
#define FileBothDirectoryInformation 3
#define FileNamesInformation 12
структура записи в FileInformation для FileDirectoryInformation:
typedef struct _FILE_DIRECTORY_INFORMATION {
ULONG NextEntryOffset;
ULONG Unknown;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
WCHAR FileName[1];
} FILE_DIRECTORY_INFORMATION, *PFILE_DIRECTORY_INFORMATION;
для FileFullDirectoryInformation:
typedef struct _FILE_FULL_DIRECTORY_INFORMATION {
ULONG NextEntryOffset;
ULONG Unknown;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
ULONG EaInformationLength;
WCHAR FileName[1];
} FILE_FULL_DIRECTORY_INFORMATION, *PFILE_FULL_DIRECTORY_INFORMATION;
для FileBothDirectoryInformation:
typedef struct _FILE_BOTH_DIRECTORY_INFORMATION {
ULONG NextEntryOffset;
ULONG Unknown;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
ULONG EaInformationLength;
UCHAR AlternateNameLength;
WCHAR AlternateName[12];
WCHAR FileName[1];
} FILE_BOTH_DIRECTORY_INFORMATION, *PFILE_BOTH_DIRECTORY_INFORMATION;
и для FileNamesInformation:
typedef struct _FILE_NAMES_INFORMATION {
ULONG NextEntryOffset;
ULONG Unknown;
ULONG FileNameLength;
WCHAR FileName[1];
} FILE_NAMES_INFORMATION, *PFILE_NAMES_INFORMATION;
Функция записывает набор этих структур в буфер FileInformation.
Во всех этих типах структур для нас важны только три переменных.
NextEntryOffset - размер данного элемента списка. Первый элемент
расположен по адресу FileInformation + 0, а второй элемент по адресу
FileInformation + NextEntryOffset первого элемента. У последнего элемента
поле NextEntryOffset содержит нуль.
FileName - это полное имя файла.
FileNameLength - это длина имени файла.
Для скрытия файла, необходимо сравнить имя каждой возвращаемой записи
и имя файла, который мы хотим скрыть. Если мы хотим скрыть первую запись,
нужно сдвинуть следующие за ней структуры на размер первой записи. Это приведет
к тому, что первая запись будет затерта. Если мы хотим скрыть другую запись,
мы можем просто изменить значение NextEntryOffset предыдущей записи. Новое
значение NextEntryOffset будет нуль, если мы хотим скрыть последнюю запись,
иначе значение будет суммой полей NextEntryOffset записи, которую мы хотим
скрыть и предыдущей записи. Затем необходимо изменить значение поля Unknown
предыдущей записи, которое предоставляет индекс для последующего поиска.
Значение поля Unknown предыдущей записи должно равняться значению поля Unknown
записи, которую мы хотим скрыть.
Если нет ниодной записи, которую можно видеть, мы должны вернуть ошибку
STATUS_NO_SUCH_FILE.
#define STATUS_NO_SUCH_FILE 0xC000000F
Просьба писать ваши замечания, наблюдения и все остальное,
что поможет улучшить предоставляемую информацию на этом сайте.
ВСЕ КОММЕНТАРИИ МОДЕРИРУЮТСЯ ВРУЧНУЮ, ТАК ЧТО СПАМИТЬ БЕСПОЛЕЗНО!