⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test.c

📁 在win2000sp4 + VM6基本稳定。 原理不多说了
💻 C
字号:
#include <ntddk.h>
#include "fastIO.h"
#include "test.h"
#include "DeviceControl.h"
/*
 *	驱动主入口函数
 */ 
NTSTATUS
DriverEntry(
	IN PDRIVER_OBJECT DriverObject,
	IN PUNICODE_STRING RegistryPath)
{
	int i;
	NTSTATUS status;
	UNICODE_STRING nameString;
	UNICODE_STRING DosNameLink;
	PDEVICE_OBJECT FilterDevice;
	//首先创建一个CDO
	RtlInitUnicodeString(&nameString, L"\\FileSystem\\SFilter");
	status = IoCreateDevice(
							DriverObject,
							0,
							&nameString,
							FILE_DEVICE_DISK_FILE_SYSTEM,
							FILE_DEVICE_SECURE_OPEN,
							FALSE,
							&g_CDO	
							);
	if (!NT_SUCCESS(status))
	{
		KdPrint(("DriverEntry:Error Create cdo, status = %08x\n", status));
		return status;
	}	
	//安装分发函数
	for (i=0; i<=IRP_MJ_MAXIMUM_FUNCTION; i++)
	{
		DriverObject->MajorFunction[i] = SfPassThrough;
	}

    DriverObject->MajorFunction[IRP_MJ_CREATE] = FsDeviceCreate;
	DriverObject->MajorFunction[IRP_MJ_CLOSE] = FsDeviceClose;
	DriverObject->MajorFunction[IRP_MJ_CLEANUP] = FsDeviceClose;

	DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = FsDirectoryControl;
	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = FsDeviceControl;
	
	DriverObject->DriverUnload = DriverUnload;
	//创建连接名
	RtlInitUnicodeString(&DosNameLink,L"\\DosDevices\\SFilter");	
    status=IoCreateSymbolicLink(&DosNameLink,&nameString);
	//Fast IO
	InitFastIo(DriverObject);
	//准备绑定C:\的设备
	RtlInitUnicodeString(&nameString, L"\\DosDevices\\C:\\");
	if (!AttachToDiskDevice(&nameString, &FilterDevice))
	{
		KdPrint(("DrierEntry Failed..\n"));
		IoDeleteDevice(FilterDevice);
		return STATUS_DEVICE_CONFIGURATION_ERROR;
	}
	InitializeListHead(&g_HideObjHead);
	HideMe(RegistryPath);
	return status;//STATUS_DEVICE_CONFIGURATION_ERROR;
}

/*
 *	从注册表中得到镜像sys文件路径
 */
VOID HideMe(IN PUNICODE_STRING RegistryPath)
{
	NTSTATUS status;
	HANDLE hkey;
	OBJECT_ATTRIBUTES oa;
	ULONG size = 0;
	UNICODE_STRING valname;
	PWCHAR pStr = NULL;
	PKEY_VALUE_PARTIAL_INFORMATION vpip;
	
	InitializeObjectAttributes(&oa, RegistryPath, 0, NULL, NULL);
	status = ZwOpenKey(&hkey, KEY_READ, &oa);
	if (NT_SUCCESS(status))
	{
		RtlInitUnicodeString(&valname, L"ImagePath");
		status = ZwQueryValueKey(hkey, &valname, KeyValuePartialInformation, NULL, 0, &size);
		if ((STATUS_OBJECT_NAME_NOT_FOUND == status) || 
			(size == 0))
		{
			return;
		}
		vpip = (PKEY_VALUE_PARTIAL_INFORMATION) ExAllocatePool(PagedPool, size);
		if (!vpip)
		{
			return;
		}
		status = ZwQueryValueKey(hkey, &valname, KeyValuePartialInformation, vpip, size, &size);
		if (!NT_SUCCESS(status))
		{
			return;
		}
		//得到镜像文件的路径
		pStr = (PWCHAR)(vpip->Data + vpip->DataLength);
		while (*pStr != L'\\')
		{
			pStr--;
		}
		AddHideObject(pStr + 1, CDO_FLAG_FILE);
		//KdPrint(("%ws", pStr + 1));
		ExFreePool(vpip);
		ZwClose(hkey);
	}
}

/*
 *驱动卸载	
 */
VOID
DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
	//卸载资源
	PDEVICE_OBJECT DO = DriverObject->DeviceObject;
	PDEVICE_OBJECT NextDO = NULL;
	PDEVICE_EXTENSION DevEx = NULL;
	UNICODE_STRING DosNameLink;
	PLIST_ENTRY pdLink = NULL;
	PHIDE_FILE  pHideObj = NULL;
	//释放隐藏文件链表
	while(!IsListEmpty(&g_HideObjHead))
	{
		pdLink = RemoveHeadList(&g_HideObjHead);
		pHideObj = (PHIDE_FILE)CONTAINING_RECORD(pdLink, HIDE_FILE, linkfield);
		ExFreePool(pHideObj);
	}
	//卸载驱动
	if (DriverObject)
	{
		while(DO) 
		{
			KdPrint (("Unload Device...\n"));
			NextDO = DO->NextDevice;
			DevEx = DO->DeviceExtension;
			if (DevEx)
			{
				if (DevEx->AttachedToDevice)
				{
					IoDetachDevice(DevEx->AttachedToDevice);
				}
			}
			IoDeleteDevice(DO);
			DO = NextDO;
		}
	}
	//释放FastIo
	DestoryFastIo(DriverObject);
	//删除符号链接
	RtlInitUnicodeString(&DosNameLink,L"\\DosDevices\\SFilter");	
	IoDeleteSymbolicLink(&DosNameLink);	
}

/*
 *	驱动控制设备通信
 */
NTSTATUS
FsDeviceControl(IN PDEVICE_OBJECT DeviceObject,
				IN PIRP Irp)
{
	NTSTATUS status = STATUS_NOT_IMPLEMENTED;
	PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
	ULONG ControlCode;
	PVOID lpInBuf = NULL;

	if (g_CDO == DeviceObject)
	{
		ControlCode = irpSp->Parameters.DeviceIoControl.IoControlCode;
		lpInBuf = irpSp->Parameters.DeviceIoControl.Type3InputBuffer;
		lpInBuf = Irp->AssociatedIrp.SystemBuffer;
		KdPrint(("Control Code:[%08x]\n", ControlCode));
		switch (ControlCode)
		{
		case CDO_ADD_FILE:
			AddHideObject(lpInBuf, CDO_FLAG_FILE);
			break;
		case CDO_ADD_DIRECTORY:
			AddHideObject(lpInBuf, CDO_FLAG_DIRECTORY);
			break;
		case CDO_REMOVE_FILE:
		case CDO_REMOVE_DIRECTORY:
			//暂时不处理
			break;
		}
		Irp->IoStatus.Status = STATUS_SUCCESS;
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
		return Irp->IoStatus.Status;
	}
	else
	{
		return SfPassThrough(DeviceObject, Irp);
	}
}

NTSTATUS
FsDeviceCreate(IN PDEVICE_OBJECT DeviceObject,
			   IN PIRP Irp)
{
	PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation (Irp);
	if (g_CDO == DeviceObject)
	{
		KdPrint(("CDO Created!\n"));
		Irp->IoStatus.Information = 0;
		Irp->IoStatus.Status = STATUS_SUCCESS;
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
		return STATUS_SUCCESS;
	}
	//测试是否是我隐藏的文件,如果是直接返回Create失败
	
	return SfPassThrough(DeviceObject, Irp);
}

NTSTATUS
FsDeviceClose(IN PDEVICE_OBJECT DeviceObject,
			  IN PIRP Irp)
{
	if (g_CDO == DeviceObject)
	{
		KdPrint(("CDO Closed!\n"));
		Irp->IoStatus.Information = 0;
		Irp->IoStatus.Status = STATUS_SUCCESS;
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
		return STATUS_SUCCESS;
	}
	return SfPassThrough(DeviceObject, Irp);
}
/*
 *	驱动的目录处理函数
 */
NTSTATUS
FsDirectoryControl(IN PDEVICE_OBJECT DeviceObject,
				   IN PIRP Irp)
{
	NTSTATUS status;
	PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);	//当前Irp(IO_STACK_LOCATION)的参数
	PDEVICE_EXTENSION devExt = DeviceObject->DeviceExtension;
	PFILE_BOTH_DIR_INFORMATION dirInfo = NULL;
	KEVENT waitEvent;
	//UNICODE_STRING path;
	ASSERT(g_CDO != DeviceObject);
	ASSERT(IS_MY_DEVICE_OBJECT(DeviceObject));
	if (IRP_MN_QUERY_DIRECTORY != irpSp->MinorFunction)
	{
		goto SkipHandle;
	}
	if (Irp->RequestorMode == KernelMode)
	{
		goto SkipHandle;
	}
    if (FileBothDirectoryInformation != ((PQUERY_DIRECTORY)&irpSp->Parameters)->FileInformationClass) 
	{	
        goto SkipHandle;
    }
	//设置完成回调函数
    KeInitializeEvent(&waitEvent, NotificationEvent, FALSE);
    IoCopyCurrentIrpStackLocationToNext(Irp);
	//IoSetCompletionRoutine(Irp,CompletionRoutine,context,InvokeOnSuccess,InvokeOnError,InvokeOnCancel);
    IoSetCompletionRoutine(	
							Irp,
							DirControlCompletion,		//CompletionRoutine
							&waitEvent,					//context parameter
							TRUE,
							TRUE,
							TRUE
							);

	status = IoCallDriver(devExt->AttachedToDevice, Irp);
	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;
    }
	//KdPrint(("Hook Directory.\n"));
	HandleDirectory(Irp->UserBuffer,  &((PQUERY_DIRECTORY)&irpSp->Parameters)->Length);
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return status;

SkipHandle:
	IoSkipCurrentIrpStackLocation(Irp);
	return IoCallDriver(devExt->AttachedToDevice, Irp);
}

BOOLEAN
HandleDirectory(IN OUT PFILE_BOTH_DIR_INFORMATION DirInfo, IN PULONG lpBufLenth)
{
	//处理目录操作
	PFILE_BOTH_DIR_INFORMATION currentDirInfo = DirInfo;
	PFILE_BOTH_DIR_INFORMATION lastDirInfo = NULL;
	ULONG offset = 0;
	ULONG position = 0;
	ULONG newLenth = *lpBufLenth;
	WCHAR fileName[] = L"Test.txt";
	do
	{
		offset = currentDirInfo->NextEntryOffset;
		//if (!(FILE_ATTRIBUTE_DIRECTORY & currentDirInfo->FileAttributes) &&
		//	 (0 == wcsncmp(currentDirInfo->FileName, fileName, currentDirInfo->FileNameLength>>1)))
		if (IS_MY_HIDE_OBJECT(currentDirInfo->FileName, 
							  currentDirInfo->FileNameLength,
							  currentDirInfo->FileAttributes))
		{
			//Now We Will Test The FileName
			//KdPrint(("%08x Hided File:%ws[%d]\n", currentDirInfo->FileAttributes, currentDirInfo->FileName, currentDirInfo->FileNameLength));
			if (0 == offset)
			{
				//KdPrint(("l[%d][%d][%d][%d]\n", newLenth, *lpBufLenth, position, newLenth-(*lpBufLenth - position)));
				//Reset Last DirInfo NextEntryOffset To Zero!!!
				if (lastDirInfo)
				{
					lastDirInfo->NextEntryOffset = 0;
					newLenth -= *lpBufLenth - position;
				}
				else
				{
					currentDirInfo->NextEntryOffset = 0;
					*lpBufLenth = 0;
					return TRUE;
				}
			}
			else
			{
				//KdPrint(("n[%d][%d][%d]\n", newLenth, *lpBufLenth, position));
				RtlMoveMemory(currentDirInfo, (PUCHAR)currentDirInfo + offset, *lpBufLenth - position - offset);
				newLenth -= offset;
				position += offset;
			}
		}
		else
		{
			//KdPrint(("%08x Directory:%ws\n", currentDirInfo->FileAttributes, currentDirInfo->FileName));
			//Move Next
			position += offset;
			lastDirInfo = currentDirInfo;
			currentDirInfo = (PFILE_BOTH_DIR_INFORMATION)((PUCHAR)currentDirInfo + offset);
		}
	} while (0 != offset);
	*lpBufLenth = newLenth;
	return TRUE;
}

/*
 *	测试是否是要隐藏的对象
 */
BOOLEAN
IS_MY_HIDE_OBJECT(const WCHAR *Name, ULONG NameLenth, ULONG Flag)
{
	PLIST_ENTRY headListEntry = &g_HideObjHead;
	PLIST_ENTRY tmpListEntry = headListEntry;
	PHIDE_FILE tmpHideFile = NULL;
	ULONG ObjFlag = (FILE_ATTRIBUTE_DIRECTORY & Flag)?CDO_FLAG_DIRECTORY:CDO_FLAG_FILE;

	if (IsListEmpty(&g_HideObjHead))
	{
		return FALSE;
	}
	while (tmpListEntry->Flink != headListEntry)
	{
		tmpListEntry = tmpListEntry->Flink;
		tmpHideFile = (PHIDE_FILE)CONTAINING_RECORD(tmpListEntry, HIDE_FILE, linkfield);
		if ((ObjFlag == tmpHideFile->Flag) &&
			(0 == wcsncmp(Name, tmpHideFile->Name, NameLenth>>1)))
		{
			KdPrint(("Find Obj\n"));
			return TRUE;
		}
	}
	return FALSE;
}

NTSTATUS
DirControlCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
{
	//if (Irp->PendingReturned) IoMarkIrpPending(Irp);
	KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
	return STATUS_MORE_PROCESSING_REQUIRED;	//注:必须返回这个值
}
BOOLEAN
IS_MY_DEVICE_OBJECT(PDEVICE_OBJECT DeviceObject)
{
	return DeviceObject->DriverObject == g_CDO->DriverObject;
}

/*
 * 	挂载到指定的磁盘设备
 */
BOOLEAN 
AttachToDiskDevice(IN PUNICODE_STRING pDiskName, OUT PDEVICE_OBJECT *pOurDevice)
{
	NTSTATUS status;
	PDEVICE_EXTENSION DevEx;
	PDEVICE_OBJECT DiskDeviceObject;
	PDEVICE_OBJECT NewDeviceObject;

	IO_STATUS_BLOCK ioStatus;
	OBJECT_ATTRIBUTES objectAttributes;
	PFILE_OBJECT fileObject = NULL;
	HANDLE ntFileHandle;
	// We have to figure out what device to hook - first open the volume's 
	// root directory
	//
	InitializeObjectAttributes(&objectAttributes, pDiskName, OBJ_CASE_INSENSITIVE, NULL, NULL );
	status = ZwCreateFile(&ntFileHandle, SYNCHRONIZE|FILE_ANY_ACCESS, 
							&objectAttributes, &ioStatus, NULL, 0, 
							FILE_SHARE_READ|FILE_SHARE_WRITE, 
							FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE, 
							NULL, 0);

	if (!NT_SUCCESS(status))
	{
		DbgPrint(("Filemon: Could not open drive\n"));
		return FALSE;
	}
	KdPrint(("Open Device is OK\n"));
	//
	// Got the file handle, so now look-up the file-object it refers to
	//
	status = ObReferenceObjectByHandle(ntFileHandle, FILE_READ_DATA, NULL, KernelMode, &fileObject, NULL);
	if(!NT_SUCCESS(status)) 
	{
		DbgPrint(("Filemon: Could not get fileobject from handle\n"));
		ZwClose(ntFileHandle);
		return FALSE;			
	}
	DiskDeviceObject = IoGetRelatedDeviceObject(fileObject);
	if(!DiskDeviceObject) 
	{
		DbgPrint(("Filemon: Could not get related device object\n"));
		goto ErrHand;
	}
	//创建挂载设备
	status = IoCreateDevice(
							g_CDO->DriverObject,
							sizeof(DEVICE_EXTENSION),
							NULL,
							DiskDeviceObject->DeviceType,
							FILE_DEVICE_SECURE_OPEN,
							FALSE,
							&NewDeviceObject
							);
	if (!NT_SUCCESS(status)) 
	{
		goto ErrHand;
	}
	NewDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
	*pOurDevice = NewDeviceObject;

	DevEx = NewDeviceObject->DeviceExtension;
	DevEx->AttachedToDevice = DiskDeviceObject;
	DevEx->DeviceName.Length = 0;
	DevEx->DeviceName.MaximumLength = sizeof(DevEx->DeviceNameBuffer);
	DevEx->DeviceName.Buffer = DevEx->DeviceNameBuffer;
	//RtlFillMemory(DevEx->DeviceName.Buffer, sizeof(DevEx->DeviceNameBuffer), 0);
	SfGetObjectName(g_CDO, &(DevEx->DeviceName));

	//执行挂载
	DevEx->AttachedToDevice = IoAttachDeviceToDeviceStack(NewDeviceObject, DiskDeviceObject);
	if (!DevEx->AttachedToDevice)
	{
		goto ErrHand;
	}

	KdPrint(("Attath Device is OK\n"));
	ObDereferenceObject(fileObject);
	ZwClose(ntFileHandle);
	return TRUE;

ErrHand:
	KdPrint(("AttachDevice Failed status %08x\n", status));
	ObDereferenceObject(fileObject);
	ZwClose(ntFileHandle);
	return  FALSE;
}


/*
 *	不处理的Irp
 */
NTSTATUS
SfPassThrough(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
	PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
	//不处理
	//ASSERT(IS_MY_DEVICE_OBJECT(DeviceObject));
	if (g_CDO == DeviceObject)
	{
		KdPrint((("ERROR CDO:[%08x]\n"), irpSp->MajorFunction, irpSp->MinorFunction));
		_asm int 3;
		Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
		Irp->IoStatus.Information = 0;
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
		return STATUS_INVALID_DEVICE_REQUEST;
	}
	IoSkipCurrentIrpStackLocation(Irp);
	return IoCallDriver(((PDEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedToDevice, Irp);
}

/*
 *	得到一个对象的名称
 */
VOID
SfGetObjectName(
	IN PVOID Object,
	IN OUT PUNICODE_STRING Name
)
{
	NTSTATUS status;
	CHAR nibuf[512]; //buffer that receives NAME information and name

	POBJECT_NAME_INFORMATION nameInfo = (POBJECT_NAME_INFORMATION)nibuf;
	ULONG retLength;
	
	status = ObQueryNameString(Object, nameInfo, sizeof(nibuf), &retLength);
	
	Name->Length = 0;
	if (NT_SUCCESS( status )) 
	{
		RtlCopyUnicodeString(Name, &nameInfo->Name);
		//KdPrint(("Object %wZ,Len = %d.[%d]\n", Name, retLength, Name->Length));
	}
}

/*
 *	添加一个隐藏对象
 */
VOID
AddHideObject(PWCHAR Name, ULONG Flag)
{
	//添加一个隐藏
	PHIDE_FILE newHideObj;
	newHideObj = ExAllocatePoolWithTag(PagedPool, sizeof(HIDE_FILE), 'NHFO');
	newHideObj->Flag = Flag;
	wcscpy(newHideObj->Name, Name);
	InsertTailList(&g_HideObjHead, &newHideObj->linkfield);
	KdPrint(("Add Hide Obj:%ws", Name));
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -