I am hooking the function 'NtQueryDirectoryFile' to hide folder in the system , my code as below.
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include "MinHook.h"
#include <shlwapi.h>
#include <winsock2.h>
#if defined _M_X64
#pragma comment(lib, "libMinHook.x64.lib")
#elif defined _M_IX86
#pragma comment(lib, "libMinHook.x86.lib")
#endif
#define NT_SUCCESS(Status) ((NTSTATUS)(Status)>=0)
typedef LONG NTSTATUS;
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
typedef struct _IO_STATUS_BLOCK
{
NTSTATUS Status;
ULONG Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
typedef struct _UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef struct _STRING
{
USHORT Length;
USHORT MaximumLength;
PCHAR Buffer;
} ANSI_STRING, *PANSI_STRING;
typedef enum _FILE_INFORMATION_CLASS
{
FileDirectoryInformation = 1,
FileFullDirectoryInformation,
FileIdFullDirectoryInformation,
FileBothDirectoryInformation,
FileIdBothDirectoryInformation,
FileBasicInformation,
FileStandardInformation,
FileInternalInformation,
FileEaInformation,
FileAccessInformation,
FileNameInformation,
FileRenameInformation,
FileLinkInformation,
FileNamesInformation,
FileDispositionInformation,
FilePositionInformation,
FileFullEaInformation,
FileModeInformation,
FileAlignmentInformation,
FileAllInformation,
FileAllocationInformation,
FileEndOfFileInformation,
FileAlternateNameInformation,
FileStreamInformation,
FilePipeInformation,
FilePipeLocalInformation,
FilePipeRemoteInformation,
FileMailslotQueryInformation,
FileMailslotSetInformation,
FileCompressionInformation,
FileObjectIdInformation,
FileCompletionInformation,
FileMoveClusterInformation,
FileQuotaInformation,
FileReparsePointInformation,
FileNetworkOpenInformation,
FileAttributeTagInformation,
FileTrackingInformation,
FileMaximumInformation
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
typedef VOID (NTAPI *PIO_APC_ROUTINE)( IN PVOID ApcContext, IN PIO_STATUS_BLOCK IoStatusBlock, IN ULONG Reserved);
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_DIR_INFORMATION,*PFILE_BOTH_DIR_INFORMATION;
typedef struct _FILE_DIRECTORY_INFORMATION
{
ULONG NextEntryOffset;
ULONG FileIndex;
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;
typedef struct _FILE_FULL_DIR_INFORMATION
{
ULONG NextEntryOffset;
ULONG FileIndex;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
ULONG EaSize;
WCHAR FileName[1];
} FILE_FULL_DIR_INFORMATION, *PFILE_FULL_DIR_INFORMATION;
typedef struct _FILE_ID_FULL_DIR_INFORMATION
{
ULONG NextEntryOffset;
ULONG FileIndex;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
ULONG EaSize;
LARGE_INTEGER FileId;
WCHAR FileName[1];
} FILE_ID_FULL_DIR_INFORMATION, *PFILE_ID_FULL_DIR_INFORMATION;
typedef struct _FILE_ID_BOTH_DIR_INFORMATION
{
ULONG NextEntryOffset;
ULONG FileIndex;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
ULONG EaSize;
CCHAR ShortNameLength;
WCHAR ShortName[12];
LARGE_INTEGER FileId;
WCHAR FileName[1];
} FILE_ID_BOTH_DIR_INFORMATION, *PFILE_ID_BOTH_DIR_INFORMATION;
typedef struct _FILE_NAMES_INFORMATION
{
ULONG NextEntryOffset;
ULONG FileIndex;
ULONG FileNameLength;
WCHAR FileName[1];
} FILE_NAMES_INFORMATION, *PFILE_NAMES_INFORMATION;
ULONG getDirEntryFileLength(PVOID FileInformationBuffer,FILE_INFORMATION_CLASS FileInfoClass)
{
ULONG ulResult=0;
switch(FileInfoClass)
{
case FileDirectoryInformation:
ulResult=(ULONG)((PFILE_DIRECTORY_INFORMATION)FileInformationBuffer)->FileNameLength;
break;
case FileFullDirectoryInformation:
ulResult=(ULONG)((PFILE_FULL_DIR_INFORMATION)FileInformationBuffer)->FileNameLength;
break;
case FileIdFullDirectoryInformation:
ulResult=(ULONG)((PFILE_ID_FULL_DIR_INFORMATION)FileInformationBuffer)->FileNameLength;
break;
case FileBothDirectoryInformation:
ulResult=(ULONG)((PFILE_BOTH_DIR_INFORMATION)FileInformationBuffer)->FileNameLength;
break;
case FileIdBothDirectoryInformation:
ulResult=(ULONG)((PFILE_ID_BOTH_DIR_INFORMATION)FileInformationBuffer)->FileNameLength;
break;
case FileNamesInformation:
ulResult=(ULONG)((PFILE_NAMES_INFORMATION)FileInformationBuffer)->FileNameLength;
break;
}
return ulResult;
}
void setDirEntryLenToNext( PVOID FileInformationBuffer, FILE_INFORMATION_CLASS FileInfoClass, DWORD value)
{
switch(FileInfoClass)
{
case FileDirectoryInformation:
((PFILE_DIRECTORY_INFORMATION)FileInformationBuffer)->NextEntryOffset=value;
break;
case FileFullDirectoryInformation:
((PFILE_FULL_DIR_INFORMATION)FileInformationBuffer)->NextEntryOffset=value;
break;
case FileIdFullDirectoryInformation:
((PFILE_ID_FULL_DIR_INFORMATION)FileInformationBuffer)->NextEntryOffset=value;
break;
case FileBothDirectoryInformation:
((PFILE_BOTH_DIR_INFORMATION)FileInformationBuffer)->NextEntryOffset=value;
break;
case FileIdBothDirectoryInformation:
((PFILE_ID_BOTH_DIR_INFORMATION)FileInformationBuffer)->NextEntryOffset=value;
break;
case FileNamesInformation:
((PFILE_NAMES_INFORMATION)FileInformationBuffer)->NextEntryOffset=value;
break;
}
}
PVOID getDirEntryFileName(PVOID FileInformationBuffer, FILE_INFORMATION_CLASS FileInfoClass)
{
PVOID pvResult=NULL;
switch(FileInfoClass)
{
case FileDirectoryInformation:
pvResult=(PVOID)&((PFILE_DIRECTORY_INFORMATION)FileInformationBuffer)->FileName[0];
break;
case FileFullDirectoryInformation:
pvResult=(PVOID)&((PFILE_FULL_DIR_INFORMATION)FileInformationBuffer)->FileName[0];
break;
case FileIdFullDirectoryInformation:
pvResult=(PVOID)&((PFILE_ID_FULL_DIR_INFORMATION)FileInformationBuffer)->FileName[0];
break;
case FileBothDirectoryInformation:
pvResult=(PVOID)&((PFILE_BOTH_DIR_INFORMATION)FileInformationBuffer)->FileName[0];
break;
case FileIdBothDirectoryInformation:
pvResult=(PVOID)&((PFILE_ID_BOTH_DIR_INFORMATION)FileInformationBuffer)->FileName[0];
break;
case FileNamesInformation:
pvResult=(PVOID)&((PFILE_NAMES_INFORMATION)FileInformationBuffer)->FileName[0];
break;
}
return pvResult;
}
DWORD getDirEntryLenToNext(PVOID FileInformationBuffer, FILE_INFORMATION_CLASS FileInfoClass)
{
DWORD dwResult=0;
switch(FileInfoClass)
{
case FileDirectoryInformation:
dwResult=((PFILE_DIRECTORY_INFORMATION)FileInformationBuffer)->NextEntryOffset;
break;
case FileFullDirectoryInformation:
dwResult=((PFILE_FULL_DIR_INFORMATION)FileInformationBuffer)->NextEntryOffset;
break;
case FileIdFullDirectoryInformation:
dwResult=((PFILE_ID_FULL_DIR_INFORMATION)FileInformationBuffer)->NextEntryOffset;
break;
case FileBothDirectoryInformation:
dwResult=((PFILE_BOTH_DIR_INFORMATION)FileInformationBuffer)->NextEntryOffset;
break;
case FileIdBothDirectoryInformation:
dwResult=((PFILE_ID_BOTH_DIR_INFORMATION)FileInformationBuffer)->NextEntryOffset;
break;
case FileNamesInformation:
dwResult=((PFILE_NAMES_INFORMATION)FileInformationBuffer)->NextEntryOffset;
break;
}
return dwResult;
}
BOOL config_CheckString(char * str, char *str2)
{
if(StrStrIA(str, str2) != NULL)
return TRUE;
return FALSE;
}
extern "C" NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString,
BOOLEAN AllocateDestinationString);
extern "C" NTSYSAPI VOID NTAPI RtlFreeAnsiString(PANSI_STRING AnsiString);
extern "C" NTSYSAPI NTSTATUS NTAPI NtQueryDirectoryFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext,
PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass,
BOOLEAN ReturnSingleEntry, PUNICODE_STRING FileName, BOOLEAN RestartScan);
typedef NTSTATUS (WINAPI *NtQueryDirectoryFileNext)(HANDLE hFile, HANDLE hEvent, PIO_APC_ROUTINE IoApcRoutine, PVOID IoApcContext,
PIO_STATUS_BLOCK pIoStatusBlock, PVOID FileInformationBuffer, ULONG FileInformationBufferLength, FILE_INFORMATION_CLASS FileInfoClass,
BOOLEAN bReturnOnlyOneEntry, PUNICODE_STRING PathMask, BOOLEAN bRestartQuery);
NtQueryDirectoryFileNext Real_NtQueryDirectoryFile = NULL;
NTSTATUS WINAPI NtQueryDirectoryFileCallback(HANDLE hFile, HANDLE hEvent, PIO_APC_ROUTINE IoApcRoutine, PVOID IoApcContext,
PIO_STATUS_BLOCK pIoStatusBlock, PVOID FileInformationBuffer, ULONG FileInformationBufferLength, FILE_INFORMATION_CLASS FileInfoClass,
BOOLEAN bReturnOnlyOneEntry, PUNICODE_STRING PathMask, BOOLEAN bRestartQuery)
{
NTSTATUS rc;
char * ConfigHiddenFileDir = "pawaa software";//Name of the Folder to be Hide
rc = Real_NtQueryDirectoryFile( hFile, hEvent, IoApcRoutine, IoApcContext, pIoStatusBlock,
FileInformationBuffer, FileInformationBufferLength, FileInfoClass, bReturnOnlyOneEntry,
PathMask, bRestartQuery );
if(NT_SUCCESS(rc) && (FileInfoClass==FileDirectoryInformation || FileInfoClass == FileFullDirectoryInformation||
FileInfoClass == FileIdFullDirectoryInformation || FileInfoClass==FileBothDirectoryInformation||
FileInfoClass == FileIdBothDirectoryInformation || FileInfoClass==FileNamesInformation))
{
PVOID p = FileInformationBuffer;
PVOID pLast = NULL;
BOOL bLastOne,bFound;
UNICODE_STRING usName;
ANSI_STRING asName;
if (bReturnOnlyOneEntry) // if only one entry returned we should give the next if it suppose to be hidden
{
usName.Buffer = (PWSTR)getDirEntryFileName(FileInformationBuffer, FileInfoClass);
usName.Length=(USHORT)getDirEntryFileLength(FileInformationBuffer,FileInfoClass);
RtlUnicodeStringToAnsiString(&asName,&usName,TRUE);
bFound = config_CheckString(ConfigHiddenFileDir, asName.Buffer);
RtlFreeAnsiString(&asName);
if( bFound)
{
rc = Real_NtQueryDirectoryFile( hFile, hEvent, IoApcRoutine, IoApcContext, pIoStatusBlock,
FileInformationBuffer, FileInformationBufferLength, FileInfoClass, bReturnOnlyOneEntry,
PathMask, bRestartQuery);
if (rc != STATUS_SUCCESS)
return(rc);
usName.Buffer = (PWSTR)getDirEntryFileName(FileInformationBuffer,FileInfoClass);
usName.Length = (USHORT)getDirEntryFileLength(FileInformationBuffer,FileInfoClass);
RtlUnicodeStringToAnsiString(&asName,&usName,TRUE);
bFound = config_CheckString(ConfigHiddenFileDir,asName.Buffer);
RtlFreeAnsiString(&asName);
}
}
else // if full list hide the ones that should be hidden
{
do
{
bLastOne =!getDirEntryLenToNext(p,FileInfoClass);
// compare directory-name
if (getDirEntryFileLength(p,FileInfoClass))
{
usName.Buffer = (PWSTR) getDirEntryFileName(p,FileInfoClass);
usName.Length =(USHORT)getDirEntryFileLength(p,FileInfoClass);
RtlUnicodeStringToAnsiString(&asName,&usName,TRUE);
if (config_CheckString(ConfigHiddenFileDir,asName.Buffer))
{
RtlFreeAnsiString(&asName);
if(bLastOne)
{
if(p == FileInformationBuffer) rc = 0x80000006;
else setDirEntryLenToNext(pLast,FileInfoClass,0);
break;
}
else
{
int iPos = ((ULONG)p)-(ULONG)FileInformationBuffer;
int iLeft =(DWORD)FileInformationBufferLength - iPos - getDirEntryLenToNext(p,FileInfoClass);
RtlCopyMemory(p,(PVOID)((char*)p + getDirEntryLenToNext(p,FileInfoClass)),(DWORD)iLeft);
continue;
}
}
RtlFreeAnsiString(&asName);
}
pLast = p;
p =((char*)p+getDirEntryLenToNext(p,FileInfoClass));
} while(!bLastOne);
}
}
return rc;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
if (MH_Initialize() != MH_OK)
{
MessageBoxW(NULL, L"Failed Initialize", L"Info!", MB_ICONWARNING|MB_OK);
}
if (MH_CreateHook(&NtQueryDirectoryFile, &NtQueryDirectoryFileCallback, reinterpret_cast<void**>(&Real_NtQueryDirectoryFile)) != MH_OK)
{
MessageBoxW(NULL, L"connect Disabled by hooking", L"Info!", MB_ICONWARNING|MB_OK);
}
if (MH_EnableHook(&NtQueryDirectoryFile) != MH_OK)
{
MessageBoxW(NULL, L"Failed EnableHook connect", L"Info!", MB_ICONWARNING|MB_OK);
}
break;
case DLL_PROCESS_DETACH:
if (MH_DisableHook(&NtQueryDirectoryFile) != MH_OK){}
if (MH_Uninitialize() != MH_OK){}
break;
}
return TRUE;
}
From the above code i am trying to hide the folder but it is not working, so please help me if there any mistakes in the above code or else suggest me the way how can i achieve the folder hiding ....
If it still necessary to you... I hid folder on WIN 7 from explorer.exe with this function (not final version, probably has mistakes,must work on WIN XP and VISTA too):
NTSTATUS WINAPI NewZwQueryDirectoryFile( HANDLE FileHandle,
HANDLE Event,
PIO_APC_ROUTINE ApcRoutine,
PVOID ApcContext,
PIO_STATUS_BLOCK IoStatusBlock,
PVOID FileInformation,
ULONG Length,
FILE_INFORMATION_CLASS FileInformationClass,
BOOLEAN ReturnSingleEntry,
PUNICODE_STRING FileName,
BOOLEAN RestartScan
){
char infobuf[4096];
ULONG ResultLength = 0;
NtQueryObject(FileHandle,ObjectNameInformation,infobuf,sizeof(infobuf),&ResultLength);
OBJECT_NAME_INFORMATION * pinfo = (OBJECT_NAME_INFORMATION *) infobuf;
wchar_t * ps = pinfo->NameBuffer;
ps[ pinfo->Name.Length / 2 ] = 0;
NTSTATUS result = TrueZwQueryDirectoryFile(FileHandle,Event,ApcRoutine,ApcContext,IoStatusBlock,FileInformation,Length,
FileInformationClass,ReturnSingleEntry,FileName,RestartScan);
if ((FileInformationClass==FileBothDirectoryInformation || FileInformationClass==FileIdBothDirectoryInformation) && result == STATUS_SUCCESS){
if (lstrcmpi(ps,diskName)==0) {
if (FileInformationClass==FileBothDirectoryInformation) {
PFILE_BOTH_DIR_INFORMATION Prev,info = (PFILE_BOTH_DIR_INFORMATION)FileInformation;
UINT cnt=0;
while (info->NextEntryOffset>0) {
Prev=info;
info =(PFILE_BOTH_DIR_INFORMATION)((DWORD)info+(DWORD)info->NextEntryOffset);
UINT bl;
if (folderName[0]==0) bl = lstrcmp(info->FileName,nameProcess); else bl = lstrcmp(info->FileName,folderName);
if (bl){
if (info->NextEntryOffset==0){
Prev->NextEntryOffset=0;
Prev->FileIndex=info->FileIndex;
if (cnt==0) return STATUS_NO_SUCH_FILE;
}
else {
Prev->NextEntryOffset = Prev->NextEntryOffset+info->NextEntryOffset;
Prev->FileIndex = info->FileIndex;
}
}
cnt++;
}
}
else {
PFILE_ID_BOTH_DIR_INFORMATION Prev,info = (PFILE_ID_BOTH_DIR_INFORMATION)FileInformation;
UINT cnt=0;
while (info->NextEntryOffset>0) {
Prev=info;
info =(PFILE_ID_BOTH_DIR_INFORMATION)((DWORD)info+(DWORD)info->NextEntryOffset);
UINT bl;
if (folderName[0]==0) bl = lstrcmp(info->FileName,nameProcess); else bl = lstrcmp(info->FileName,folderName);
if (!bl){
if (info->NextEntryOffset==0){
Prev->NextEntryOffset=0;
Prev->FileIndex=info->FileIndex;
if (cnt==0) return STATUS_NO_SUCH_FILE;
}
else {
Prev->NextEntryOffset = Prev->NextEntryOffset+info->NextEntryOffset;
Prev->FileIndex = info->FileIndex;
}
}
cnt++;
}
}
}
}
return result;
}
Structs:
typedef struct _FILE_BOTH_DIR_INFORMATION {
ULONG NextEntryOffset;
ULONG FileIndex;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
ULONG EaSize;
CCHAR ShortNameLength;
WCHAR ShortName[12];
WCHAR FileName[1];
} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;
typedef struct _FILE_ID_BOTH_DIR_INFORMATION {
ULONG NextEntryOffset;
ULONG FileIndex;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
ULONG EaSize;
CCHAR ShortNameLength;
WCHAR ShortName[12];
CHAR Reserver[2];
LARGE_INTEGER FileId;
WCHAR FileName[1];
} FILE_ID_BOTH_DIR_INFORMATION, *PFILE_ID_BOTH_DIR_INFORMATION;
typedef enum _OBJECT_INFORMATION_CLASS {
ObjectBasicInformation, ObjectNameInformation, ObjectTypeInformation, ObjectAllInformation, ObjectDataInformation
} OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS;
typedef struct _OBJECT_NAME_INFORMATION {
UNICODE_STRING Name;
WCHAR NameBuffer[1];
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
TrueZwQueryDirectoryFile must call original ZwQueryDirectoryFile (or NtQueryDirectoryFile if you hook it). NtQueryOvbject return name of folder from "FileHandle" in kernel format. So you if you want hide for example "C:\Windows" convert it with GetLogicalDriveStrings and QueryDosDevice in current format.
User contributions licensed under CC BY-SA 3.0