inline hook IofCallDriver 调用ntfs时保护文件访问

#include <ntddk.h>
#include <stdio.h>

NTSTATUS DriverUnload(IN PDRIVER_OBJECT DriverObject);
int IsNeedProtect(DEVICE_OBJECT *DeviceObject, PIRP Irp);
ULONG GetFunctionAddr(IN PCWSTR FunctionName);
VOID InlineHook();

NTKERNELAPI UCHAR *PsGetProcessImageFileName(__in PEPROCESS Process);

typedef NTSTATUS(FASTCALL *pIofCallDriver)(
	IN PDEVICE_OBJECT DeviceObject,
	IN OUT PIRP Irp);
pIofCallDriver OldAddress;


NTSTATUS FASTCALL MyIofCallDriver(IN PDEVICE_OBJECT DeviceObject,
	IN OUT PIRP Irp)
{
	NTSTATUS stat;
	//先保存所有寄存器的原来状态,到时好恢复现场环境,跟加壳软件开始的指令也是一样
	__asm
	{
		pushad
			pushfd
	}

	if (IsNeedProtect(DeviceObject, Irp))
	{
		//返回删除失败的提示
		__asm
		{
				popfd
				popad
				mov eax, 0xC000000D
				mov stat, eax
		}
		return stat;
	}

	//先恢复现场环境,跳转回原地址
	__asm
	{
		popfd
			popad
			mov ecx, DeviceObject
			mov edx, Irp
			call OldAddress;
		mov stat, eax
	}
	return stat;

}





int IsNeedProtect(DEVICE_OBJECT *DeviceObject, PIRP Irp)
{
	NTSTATUS status;
	int nResult = FALSE;
	DRIVER_OBJECT *DriverObject = DeviceObject->DriverObject;
	WCHAR *pwsz = NULL;
	IO_STACK_LOCATION *sp;
	FILE_OBJECT *FileObject = NULL;

	status = STATUS_INVALID_PARAMETER;
	sp = IoGetNextIrpStackLocation(Irp);;


	switch (sp->MajorFunction)
	{
	case IRP_MJ_SET_INFORMATION:
	case IRP_MJ_WRITE:
	case IRP_MJ_CREATE:
	case IRP_MJ_READ:
		goto Continue11;

	default:
		goto Exit00;
	}

Continue11:
	FileObject = sp->FileObject;
	_try
	{
		pwsz = wcsrchr(DriverObject->DriverName.Buffer, L'\\');
		pwsz++;

		//判断Irp是不是发往ntfs和fastfat驱动的,不是则跳出
		if (_wcsnicmp(pwsz, L"ntfs", 4) && _wcsnicmp(pwsz, L"fastfat", 7))
		{
			goto Exit00;
		}

		//DbgPrint("IofCallDriver:Delete File:%ws\n", FileObject->FileName.Buffer);

		pwsz = wcsrchr(FileObject->FileName.Buffer, L'\\');
		if (pwsz != NULL)
		{
			pwsz++;
		}


		if (!_wcsnicmp(pwsz, L"456789.sys", 20))  //保护的文件名xxxxx
		{
			do 
			{
				UCHAR * szProcessName = PsGetProcessImageFileName(PsGetCurrentProcess());
				if (szProcessName)
				{
					if (_stricmp(szProcessName, "explorer.exe") == 0)
					{
						KdPrint(("桌面进程过滤掉\n"));
						break;
					}

					if (_stricmp(szProcessName, "notepad.exe") == 0)
					{
						KdPrint(("notepad进程过滤掉\n"));
						break;
					}

					KdPrint(("当前进程%s 访问文件\n", szProcessName));
					Irp->IoStatus.Information = 0;
					Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
					IoCompleteRequest(Irp, IO_NO_INCREMENT);
					nResult = TRUE;
					goto Exit00;
				}
			} while (FALSE);


		}

	}

		except(1)
	{
		goto Exit00;
	}

Exit00:
	return nResult;
}



ULONG GetFunctionAddr(IN PCWSTR FunctionName)
{
	UNICODE_STRING HookFunctionName;
	RtlInitUnicodeString(&HookFunctionName, FunctionName);
	return (ULONG)MmGetSystemRoutineAddress(&HookFunctionName);
}



//inlineHook IofCallDriver函数
VOID InlineHook()
{
	KIRQL oldIrql;
	ULONG Address;

	Address = (ULONG)GetFunctionAddr(L"IofCallDriver");
	__asm
	{
		mov eax, Address
			mov esi, [eax + 2]
			mov eax, [esi]
			mov OldAddress, eax
	}

	//提升中断层次
	oldIrql = KeRaiseIrqlToDpcLevel();
	__asm
	{
		cli
			mov eax, cr0
			and eax, not 10000h
			mov cr0, eax
	}
	//进行地址替换  
	_asm
	{
		mov eax, Address
			mov esi, [eax + 2]
			mov dword ptr[esi], offset MyIofCallDriver
	}
	_asm
	{
		mov eax, cr0
			or eax, 10000h
			mov cr0, eax
			sti
	}

	//恢复中断层次
	KeLowerIrql(oldIrql);
	return;
}



VOID UninlineHook()
{
	KIRQL oldIrql;
	ULONG Address;

	Address = (ULONG)GetFunctionAddr(L"IofCallDriver");
	//提升中断层次
	oldIrql = KeRaiseIrqlToDpcLevel();
	__asm
	{
		cli
			mov eax, cr0
			and eax, not 10000h
			mov cr0, eax
	}
	//进行地址替换  
	_asm
	{
		mov eax, Address
			mov esi, [eax + 2]
			mov eax, OldAddress
			mov dword ptr[esi], eax
	}

	_asm
	{
		mov eax, cr0
			or eax, 10000h
			mov cr0, eax
			sti
	}

	//恢复中断层次
	KeLowerIrql(oldIrql);
	return;
}




NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject,
	IN PUNICODE_STRING theRegistryPath)
{

	DbgPrint("Hook Called!\n");
	//DbgBreakPoint();
	theDriverObject->DriverUnload = DriverUnload;
	InlineHook();
	return STATUS_SUCCESS;
}


NTSTATUS DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
	NTSTATUS status = STATUS_SUCCESS;
	DbgPrint("OnUnload called!\n");
	UninlineHook();
	return status;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值