// // Record: Modify by lwf : 07-06-20 // Purpose: Hide Install Directory and permit special process's access // for virtual encrypt disk using "(_stricmp((const char*)VENCRPYTDISK, FileSpyGetProcess(name)))" // Record: Modify For OS Restart BUG 07-07-06 //
做得狠一点的话就研究下NTFS/FAT的磁盘数据结构 把文件写进去然后标记为坏扇区
#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;
// This is our unload function
#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;
ULONG CR0VALUE;
ANSI_STRING ansiFileName,ansiDirName,HideDirFile;
UNICODE_STRING uniFileName;
RtlInitAnsiString(&HideDirFile,"HideFile.sys");
DbgPrint("hide: 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); //DbgPrint("ansiFileName :%s\n",ansiFileName.Buffer);
//DbgPrint("HideDirFile :%s\n",HideDirFile.Buffer);
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 );
// Add hooks here (remember to unhook if using DriverUnload) 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;
DbgPrint("OnUnload called\n");
status=UnHook();
return status;}NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath){
NTSTATUS status = STATUS_SUCCESS; DbgPrint("I loaded!"); // Initialize the pointer to the unload function
theDriverObject->DriverUnload = OnUnload;
// in the DriverObject
//hook
Hook(); return STATUS_SUCCESS;}
SpyDirControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PFILESPY_DEVICE_EXTENSION devExt;
PIO_STACK_LOCATION irpSp;
PFILE_OBJECT FileObject;
KEVENT waitEvent;
NTSTATUS status;
ULONG bufferLength;
ULONG newLength;
ULONG offset;
ULONG currentPosition;
PFILE_BOTH_DIR_INFORMATION dirInfo = NULL;
PFILE_BOTH_DIR_INFORMATION preDirInfo = NULL;
//CHAR name[PROCNAMELEN];
//PWSTR fileNameBuffer = UNICODE_NULL; if(gControlDeviceState == CLOSED || PsGetCurrentProcessId()==g_hProcessId)
{
return SpyDispatch(DeviceObject,Irp);
} devExt = DeviceObject->DeviceExtension;
irpSp = IoGetCurrentIrpStackLocation(Irp);
FileObject = irpSp->FileObject; PAGED_CODE();// if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject)) {
// Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
// Irp->IoStatus.Information = 0;
// IoCompleteRequest(Irp, IO_NO_INCREMENT);
// return STATUS_INVALID_DEVICE_REQUEST;
// } if (Irp->RequestorMode == KernelMode) { IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(devExt->NLExtHeader.AttachedToDeviceObject, Irp);
}
//
// Record: Add by lwf : 07-07-20
// Purpose: We care about volume filter device object
//
if (!devExt->NLExtHeader.StorageStackDeviceObject){
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(devExt->NLExtHeader.AttachedToDeviceObject, Irp);
} if (irpSp->MinorFunction != IRP_MN_QUERY_DIRECTORY){
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(devExt->NLExtHeader.AttachedToDeviceObject, Irp);
} if (FileBothDirectoryInformation != ((PQUERY_DIRECTORY)&irpSp->Parameters)->FileInformationClass) { IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(devExt->NLExtHeader.AttachedToDeviceObject, Irp);
} KeInitializeEvent(&waitEvent, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp,
SpyDirControlCompletion,
&waitEvent, //context parameter
TRUE,
TRUE,
TRUE
);
status = IoCallDriver(devExt->NLExtHeader.AttachedToDeviceObject, Irp);
//
// Wait for the operation to complete
//
if (STATUS_PENDING == status) {
status = KeWaitForSingleObject(&waitEvent,
Executive,
KernelMode,
FALSE,
NULL
);
ASSERT(STATUS_SUCCESS == status);
}
if (!NT_SUCCESS(status) ||(0 == irpSp->Parameters.QueryFile.Length)) { IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
//
// Record: add by lwf :07-06-30
// Purpose:Add for Test getting full path name
//
while (TRUE) { bufferLength = ((PQUERY_DIRECTORY)&irpSp->Parameters)->Length;
newLength = bufferLength;
currentPosition = 0;
dirInfo =(PFILE_BOTH_DIR_INFORMATION) Irp->UserBuffer;
preDirInfo = dirInfo; if ((!dirInfo) ||(dirInfo->NextEntryOffset > bufferLength)) { IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
do {
//DbgPrint("[FileSpy.sys]MajorFunction-SpyDirControl:%s", SpyGetProcess(name));
//
// Record: Modify by lwf : 07-06-20
// Purpose: Hide Install Directory and permit special process's access
// for virtual encrypt disk using "(_stricmp((const char*)VENCRPYTDISK, FileSpyGetProcess(name)))"
// Record: Modify For OS Restart BUG 07-07-06
//
offset = dirInfo->NextEntryOffset;
if (/*1*/(dirInfo->FileNameLength > 0)/*1*/ &&
/*2*/(IsDirectory(dirInfo->FileAttributes))/*2*/ &&
/*3*/(g_ulHiddenDirLen == dirInfo->FileNameLength + sizeof(WCHAR))/*3*/ &&
/*4*/(_wcsnicmp( dirInfo->FileName, g_szHiddenDir, dirInfo->FileNameLength / sizeof(WCHAR)) == 0)/*4*/){
DbgPrint("[FileSpy.sys]MajorFunction-SpyDirControl,FileNameLength:%d",dirInfo->FileNameLength);
if (0 == offset) { // the last one preDirInfo->NextEntryOffset = 0;
newLength = currentPosition; } else { if (preDirInfo != dirInfo) { preDirInfo->NextEntryOffset += dirInfo->NextEntryOffset;
dirInfo = (PFILE_BOTH_DIR_INFORMATION) ((PUCHAR) dirInfo + offset);
} else { RtlMoveMemory((PUCHAR) dirInfo,(PUCHAR) dirInfo + offset, bufferLength - currentPosition - offset);
newLength -= offset; }
}
// break;
}
else
{
currentPosition += offset;
preDirInfo = dirInfo;
dirInfo =(PFILE_BOTH_DIR_INFORMATION)((PUCHAR) dirInfo + offset);
} } while(0 != offset); if (0 == newLength) {
KeResetEvent(&waitEvent);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp,
SpyDirControlCompletion,
&waitEvent, //context parameter
TRUE,
TRUE,
TRUE
);
status = IoCallDriver(devExt->NLExtHeader.AttachedToDeviceObject, Irp);
//
// Wait for the operation to complete
//
if (STATUS_PENDING == status) {
status = KeWaitForSingleObject(&waitEvent,
Executive,
KernelMode,
FALSE,
NULL
);
ASSERT(STATUS_SUCCESS == status);
} if (!NT_SUCCESS(status) ||(0 == Irp->IoStatus.Information)) {
break;
} } else { Irp->IoStatus.Information = newLength;
break;
}
} //
// Record: add by lwf :07-06-30
// Purpose:Add for Test getting full path name
// Irp->IoStatus.Information = newLength;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
} BOOLEAN IsDirectory(
ULONG dirattr
)
//----------------------------------------------------------------------
//
// IsDirectory
//
// Check Whether File Object is Directory
//
//----------------------------------------------------------------------
{
return ( (dirattr != 0xffffffff) && (FILE_ATTRIBUTE_DIRECTORY & dirattr) );} //
// Record : Add by lwf : 07-06-19
// Purpose: Handle Setting Hidden Directory Control Code
//
case FILESPY_SetHiddenDir: if (InputBuffer == NULL || InputBufferLength <= 0) { IoStatus->Status = STATUS_INVALID_PARAMETER;
DbgPrint("[FileSpy.sys]IOCTLCODE-FILESPY_SetHiddenDir,Err: buffer or length invalid");
break;
} //
// Copy the device name and add a null to ensure that it is null
// terminated
// g_szHiddenDir = ExAllocatePoolWithTag( NonPagedPool,
InputBufferLength + sizeof(WCHAR),
FILESPY_POOL_TAG ); if (NULL == g_szHiddenDir) { IoStatus->Status = STATUS_INSUFFICIENT_RESOURCES;
DbgPrint("[FileSpy.sys]IOCTLCODE-FILESPY_SetHiddenDir,Err: alloc memory failed");
break;
} try { RtlCopyMemory( g_szHiddenDir, InputBuffer, InputBufferLength ); } except (EXCEPTION_EXECUTE_HANDLER) { IoStatus->Status = GetExceptionCode();
DbgPrint("[FileSpy.sys]IOCTLCODE-FILESPY_SetHiddenDir,Err: copy memory err-%0x",IoStatus->Status);
} if (NT_SUCCESS( IoStatus->Status )) { g_szHiddenDir[InputBufferLength / sizeof(WCHAR)] = UNICODE_NULL;
DbgPrint("[Filespy.sys]IOCTLCODE-SetHiddenDir.Dir:%ws-Len:%d",InputBuffer,InputBufferLength);
g_ulHiddenDirLen = InputBufferLength;//string length
IoStatus->Status = STATUS_SUCCESS;
} break;