文件过滤那么就是相关分发函数的处理
FilterCreate(创建)
FilterRead(一般不拦截,加解密处理)
FilterWrite(修改,加解密处理)
FilterSetInfo(删,重命名,IRP_MJ_SET_INFORMATION)
Filterclose(一般不拦截,写关闭拦截)
FIlterClean(写关闭)
代码片段
DriverObject->MajorFunction[IRP_MJ_CREATE] = sfCreate;
//DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] = SfCreate;
//DriverObject->MajorFunction[IRP_MJ_CREATE_MAILSLOT] = SfCreate;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = sfDeviceIoControl;//主要弹窗操作
DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = sfSetInformation;//监控文件操作
DriverObject->MajorFunction[IRP_MJ_WRITE] = sfWrite;
DriverObject->MajorFunction[IRP_MJ_READ] = sfRead;
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = SfFsControl;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = sfCleanup;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = sfClose;
NTSTATUS
sfCreate(PDEVICE_OBJECT lpDevice, PIRP lpIrp)
{
PLIST_ENTRY CurrentList = NULL;
USER_RESULT R3UserResult = User_Pass;
NAME_LOOKUP_FLAGS LookupFlags = 0;
PNAME_CONTROL lpNameControl = NULL;
NTSTATUS ntStatus = STATUS_SUCCESS;
ULONG ulInfo = 0;
BOOLEAN bSkipped = FALSE;
ULONG ulDisposition = 0;
KEVENT waitEvent = {0};
IO_STACK_LOCATION *lpIrpStack = IoGetCurrentIrpStackLocation(lpIrp);
PFILE_OBJECT lpFileObject = lpIrpStack->FileObject;
PTWOWAY pTwoWay = NULL;
WCHAR wszLongName[MAX_PATH] = {0};
WCHAR wszFileName[MAX_PATH] = {0};
WCHAR wszDeviceName[MAX_PATH] = {0};
UNICODE_STRING ustrDeviceName = {0};
UNICODE_STRING ustrRule = {0};
BOOLEAN bPopWindow = TRUE;
if (IS_MY_CONTROL_DEVICE_OBJECT(lpDevice))
{
lpIrp->IoStatus.Status = ntStatus;
lpIrp->IoStatus.Information = ulInfo;
IoCompleteRequest(lpIrp, IO_NO_INCREMENT);
return ntStatus;
}
else if (!IS_MY_DEVICE_OBJECT(lpDevice))
{
lpIrp->IoStatus.Status = ntStatus = STATUS_INVALID_PARAMETER;
lpIrp->IoStatus.Information = ulInfo;
IoCompleteRequest(lpIrp, IO_NO_INCREMENT);
return ntStatus;
}
else//过滤设备
{
PSFILTER_DEVICE_EXTENSION lpDevExt = (PSFILTER_DEVICE_EXTENSION)(lpDevice->DeviceExtension);
PIO_SECURITY_CONTEXT securityContext = lpIrpStack->Parameters.Create.SecurityContext;
if (
lpIrp->RequestorMode == KernelMode ||
IsDir(lpIrpStack) == TRUE ||
PsGetCurrentProcessId() == g_hSystemProcID ||
FlagOn(lpIrpStack->Flags, SL_OPEN_TARGET_DIRECTORY) ||
(lpIrp->Flags & IRP_PAGING_IO) ||//IRP_NOCHACHE并且非IRP_XXX_PAGING_IO,也就是用户设置FILE_NO_INTERMEDIATE_BUFFERING,不需要进入缓存,流程APP->io->fsd->disk,
(lpIrp->Flags & IRP_SYNCHRONOUS_PAGING_IO))//2.IRP_CACHE并且非IRP_XXX_PAGING_IP,就是FSD->>CC->mm,3IRP_PAGING_IO情况2中mm-》FSSD——》DISK只进入内存,并没有进入文件系统,反正是有内核内存管理器发的irp
{
bSkipped = TRUE;
goto _EXIT;
}
ulDisposition = (lpIrpStack->Parameters.Create.Options >> 24) & 0xFF;//高八位
if (ulDisposition == FILE_CREATE || ulDisposition == FILE_OVERWRITE || ulDisposition == FILE_OVERWRITE_IF)
{
//修改打开?
}
else
{
bPopWindow = FALSE;
}
// 在create时获取文件路径
if (FlagOn(lpIrpStack->Flags, SL_OPEN_TARGET_DIRECTORY))
{
SetFlag(LookupFlags, NLFL_OPEN_TARGET_DIR);
}
if (lpDevExt->NLExtHeader.DosName.Length != 0)
{
SetFlag(LookupFlags, NLFL_USE_DOS_DEVICE_NAME);
}
if (FlagOn(lpIrpStack->Parameters.Create.Options, FILE_OPEN_BY_FILE_ID))
{
SetFlag(LookupFlags, NLFL_OPEN_BY_ID);
}
SetFlag(LookupFlags, NLFL_IN_CREATE);
ntStatus = GetFileNameFromObject(&lpNameControl, LookupFlags, lpIrpStack->FileObject, lpDevice);//拿到文件名
if (lpNameControl == NULL ||
!NT_SUCCESS(ntStatus))
{
// 允许
bSkipped = TRUE;
goto _EXIT;
}
if (IsShortNamePath(lpNameControl->Name.Buffer))
{
//实际上应该处理短格式文件名
ConverShortToLongName(wszLongName, lpNameControl->Name.Buffer, sizeof(WCHAR)*MAX_PATH);
RtlCopyMemory(lpNameControl->Name.Buffer, wszLongName, sizeof(WCHAR)*MAX_PATH);
}
ustrDeviceName.Buffer = wszDeviceName;
ustrDeviceName.Length = 0;
ustrDeviceName.MaximumLength = sizeof(WCHAR)*MAX_PATH;
RtlCopyUnicodeString(&ustrDeviceName, &lpNameControl->Name);
//RtlCopyMemory(wszDeviceName, lpNameControl->Name.Buffer, MAX_PATH*sizeof(WCHAR));、
//UstrDeviceName:\device\harddiskvolume3\doc\1.txt
//wszFileName:C:\doc\1.txt要从上面类型转下面符号链接的格式
if (!GetNTLinkName(ustrDeviceName.Buffer, wszFileName))
{
bSkipped = TRUE;
goto _EXIT;
}
RtlInitUnicodeString(&ustrDeviceName, wszFileName);
RtlCopyUnicodeString(&lpNameControl->Name, &ustrDeviceName);
RtlInitUnicodeString(&ustrRule, L"C:\\WINDOWS\\SYSTEM32\\*\\*.SYS");//定义规则匹配,忽略大小写,必须全是大写
if (!IsPatternMatch(&ustrRule, &lpNameControl->Name, TRUE))
{
//bSkipped = TRUE;
//goto _EXIT;
bPopWindow = FALSE;
}
else
{
DbgPrint("File:%wZ\n", &lpNameControl->Name);
DbgPrint("Noted: rule matched\n");
}
if (bPopWindow)
{
R3UserResult = hipsGetResultFromUser(L"创建", lpNameControl->Name.Buffer, NULL, User_DefaultNon);
}
if (R3UserResult == User_Block)
{
//禁止
lpIrp->IoStatus.Information = 0;
lpIrp->IoStatus.Status = STATUS_ACCESS_DENIED;
IoCompleteRequest(lpIrp, IO_NO_INCREMENT);
ntStatus = STATUS_ACCESS_DENIED;
bSkipped = FALSE;
goto _EXIT;
}
//使用IOCOPY方式下发,需要最终的结果,成功失败
IoCopyCurrentIrpStackLocationToNext(lpIrp);
KeInitializeEvent(&waitEvent,
NotificationEvent,
FALSE);
IoSetCompletionRoutine(lpIrp,
FilterCreateCompletion,
&waitEvent,
TRUE,
TRUE,
TRUE);
ntStatus = IoCallDriver(((PSFILTER_DEVICE_EXTENSION)lpDevice->DeviceExtension)->NLExtHeader.AttachedToDeviceObject,
lpIrp);
if (ntStatus == STATUS_PENDING)
{
ntStatus = KeWaitForSingleObject(&waitEvent,
Executive,
KernelMode,
FALSE,
NULL);
}
ntStatus = lpIrp->IoStatus.Status;
if (NT_SUCCESS(ntStatus))
{
//如果HASH表中没有的话,此处将获得的文件名放入HASH表中,
{
PHASHDATA lpData= ExAllocatePoolWithTag(NonPagedPool, sizeof(HASHDATA), 'HSAH');
if (lpData)
{
RtlZeroMemory(lpData, sizeof(HASHDATA));
lpData->lpNameControl = lpNameControl;//文件名必须在创建时候并且返回irp成功,得到的才是可靠的,读写都是不可靠,因为以后操作不依赖文件名的,依赖lpFileObject
lpNameControl = NULL;
LockWrite(&g_HashTableLock);
Insert((DWORD)lpFileObject, lpData, g_pHashTable);//文件内核对象作为Key,文件名作为value
UnLockWrite(&g_HashTableLock);
}
}
}
IoCompleteRequest(lpIrp, IO_NO_INCREMENT);
}
_EXIT:
if (bSkipped)
{
IoSkipCurrentIrpStackLocation( lpIrp );
ntStatus = IoCallDriver(((PSFILTER_DEVICE_EXTENSION)lpDevice->DeviceExtension)->NLExtHeader.AttachedToDeviceObject, lpIrp);
}
if (lpNameControl != NULL)
{
NLFreeNameControl(lpNameControl, &gSfNameBufferLookasideList);
}
return ntStatus;
}
写入
NTSTATUS
sfWrite(PDEVICE_OBJECT lpDevice, PIRP lpIrp)
{
PLIST_ENTRY CurrentList = NULL;
USER_RESULT R3UserResult = User_Pass;
PNAME_CONTROL lpNameControl = NULL;
BOOLEAN bSkipped = FALSE;
NTSTATUS Status = STATUS_SUCCESS;
ULONG ulInfomation = 0;
IO_STACK_LOCATION *lpIrpStack = IoGetCurrentIrpStackLocation(lpIrp);
PFILE_OBJECT lpFileObject = lpIrpStack->FileObject;
PTWOWAY pTwoWay = NULL;
UNICODE_STRING ustrRule = {0};
if (IS_MY_CONTROL_DEVICE_OBJECT(lpDevice))
{
lpIrp->IoStatus.Status = Status;
lpIrp->IoStatus.Information = ulInfomation;
IoCompleteRequest(lpIrp, IO_NO_INCREMENT);
return Status;
}
else if (!IS_MY_DEVICE_OBJECT(lpDevice))
{
lpIrp->IoStatus.Status = Status = STATUS_INVALID_PARAMETER;
lpIrp->IoStatus.Information = 0;
IoCompleteRequest(lpIrp, IO_NO_INCREMENT);
return Status;
}
else
{
PSFILTER_DEVICE_EXTENSION lpDevExt = (PSFILTER_DEVICE_EXTENSION)(lpDevice->DeviceExtension);
if (
KeGetCurrentIrql() > APC_LEVEL ||
PsGetCurrentProcessId() == g_hSystemProcID ||
(lpIrp->Flags & IRP_PAGING_IO) ||//虚拟内存缓存机制发下来的
(lpIrp->Flags & IRP_SYNCHRONOUS_PAGING_IO))
{
bSkipped = TRUE;
goto _Exit;
}
//此处需要通过FileObject获得文件名
pTwoWay = Find((DWORD)lpFileObject, g_pHashTable);//lpFileObject:lpIrpStack->FileObject;在irp栈上
if (pTwoWay == NULL)
{
bSkipped = TRUE;
goto _Exit;
}
lpNameControl = pTwoWay->data.lpNameControl;
RtlInitUnicodeString(&ustrRule, L"C:\\WINDOWS\\SYSTEM32\\*\\*.SYS");
if (!IsPatternMatch(&ustrRule, &lpNameControl->Name, TRUE))
{
bSkipped = TRUE;
goto _Exit;
}
R3UserResult = hipsGetResultFromUser(L"写入", lpNameControl->Name.Buffer, NULL, User_DefaultNon);
if (R3UserResult == User_Block)
{
//禁止
lpIrp->IoStatus.Information = 0;
lpIrp->IoStatus.Status = STATUS_ACCESS_DENIED;
IoCompleteRequest(lpIrp, IO_NO_INCREMENT);
Status = STATUS_ACCESS_DENIED;
bSkipped = FALSE;
goto _Exit;
}
//允许
bSkipped = TRUE;
goto _Exit;
}
_Exit:
if (bSkipped)
{
IoSkipCurrentIrpStackLocation( lpIrp );
Status = IoCallDriver(((PSFILTER_DEVICE_EXTENSION)lpDevice->DeviceExtension)->NLExtHeader.AttachedToDeviceObject, lpIrp);
}
return Status;
}
重命名和删除