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

📄 usbmon.c

📁 usb透明加密驱动程序源代码
💻 C
字号:

#include "usbmon.h"
#include "inlinehook.h"
#include "scsi.h"
#include "aestable.h"					//AES对称加密算法
#include "rc4.h"						//RC4流加密算法

GLOBALS Globals = {0};

#define USB_STOR_DRIVER_NAME	L"\\Driver\\USBSTOR"
#define	USB_EHCI_DRIVER_NAME	L"\\Driver\\USBPORT"
#define USB_HUB_DRIVER_NAME		L"\\Driver\\USBHUB"
#define FAST_FAT_DRIVER_NAME	L"\\FileSystem\\Fastfat"

typedef struct _HOOK_IO_COMPLETION_CONTEXT
{
	PIO_COMPLETION_ROUTINE	OrgRoutine;
	HANDLE					OrgContext;
	PVOID					Buffer;
	ULONG					Length;
}HOOK_IO_COMPLETION_CONTEXT, *PHOOK_IO_COMPLETION_CONTEXT;

BOOLEAN RefreshCryptMdlList(PVOID MmAddress, PVOID NewMmAddress);

NTSTATUS 
DriverEntry( 
	IN PDRIVER_OBJECT  DriverObject, 
	IN PUNICODE_STRING  RegistryPath 
    )
{
	PDRIVER_OBJECT usbRoot;
	UNICODE_STRING usbRootName;
	INT i;
	//初始化密钥
	for (i=0; i<sizeof(Globals.Key); i++)
		Globals.Key[i] = i;

	KdPrint(("Usb mon DriverEntry...\n"));

	
	RtlInitUnicodeString(&usbRootName, USB_HUB_DRIVER_NAME);
	//RtlInitUnicodeString(&usbRootName, L"\\Driver\\usbhub20");
	if (NT_SUCCESS(ObReferenceObjectByName(&usbRootName, OBJ_CASE_INSENSITIVE, NULL, 0, *IoDriverObjectType, 0, 0, &usbRoot)))
	{
		ObDereferenceObject(usbRoot);
		KdPrint(("%wZ:%08x\n", &usbRootName, usbRoot));
		//HOOK IRP_MJ_PNP
		Globals.PnpHookHandle = SetupInlineHook(usbRoot->MajorFunction[IRP_MJ_PNP], HookPnpDevice, NULL);
	}
	
	//
	//HOOK USB_EHCI_DRIVER_NAME
	//直接 Hook usb 总线驱动
	//
	/*
	RtlInitUnicodeString(&usbRootName, USB_EHCI_DRIVER_NAME);
	if (NT_SUCCESS(ObReferenceObjectByName(&usbRootName, OBJ_CASE_INSENSITIVE, NULL, 0, *IoDriverObjectType, 0, 0, &usbRoot)))
	{
		ObDereferenceObject(usbRoot);
		KdPrint(("%wZ:%08x\n", &usbRootName, usbRoot));
		//HOOK IRP_MJ_SCSI
		Globals.ScsiHookHandle = SetupInlineHook(usbRoot->MajorFunction[IRP_MJ_SCSI], HookUsbScsi, NULL);
	}
	*/
	DriverObject->DriverUnload = UsbMonUnload;
	return STATUS_SUCCESS;
}

VOID
UsbMonUnload(
	IN PDRIVER_OBJECT DriverObject
	)
{
	PDRIVER_OBJECT	usbStor;
	UNICODE_STRING	usbStorName;
	
	KdPrint(("Usb mon unload...\n"));

	if (Globals.PnpHookHandle)
	{
		KdPrint(("Remove usbhub pnp handle...\n"));
		ClearInlineHook(Globals.PnpHookHandle);
	}
	if (Globals.fsdReadHookHandle)
	{
		KdPrint(("Remove fsdReadHookHandle...\n"));
		ClearInlineHook(Globals.fsdReadHookHandle);
	}
	if (Globals.fsdWriteHookHandle)
	{
		KdPrint(("Remove fsdWriteHookHandle...\n"));
		ClearInlineHook(Globals.fsdWriteHookHandle);
	}
	//
	//ScsiHookHandle = UsbStor->IRP_MJ_SCSI函数
	//USBSTOR驱动不常驻内存有可能已经卸载
	//
	RtlInitUnicodeString(&usbStorName, USB_STOR_DRIVER_NAME);
	if (NT_SUCCESS(ObReferenceObjectByName(&usbStorName, OBJ_CASE_INSENSITIVE, NULL, 0, *IoDriverObjectType, 0, 0, &usbStor)))
	{
		ObDereferenceObject(usbStor);
		KdPrint(("Remove usbstor scsi handle...\n"));
		if (Globals.ScsiHookHandle) ClearInlineHook(Globals.ScsiHookHandle);
		if (Globals.ScsiReadCompletionHandle) ClearInlineHook(Globals.ScsiReadCompletionHandle);
	}
}

NTSTATUS
HookPnpDevice(
	IN HANDLE OrgFunction,
	IN PDEVICE_OBJECT DeviceObject,
	IN PIRP Irp
	)
{
	PDRIVER_OBJECT		usbStor;
	UNICODE_STRING		usbStorName;
	PIO_STACK_LOCATION	irpStack = IoGetCurrentIrpStackLocation(Irp);

	switch(irpStack->MinorFunction)
	{
	case IRP_MN_START_DEVICE:
		if (KeGetCurrentIrql() == PASSIVE_LEVEL)
		{
			//HOOK USBSTOR IRP_MJ_SCSI
			RtlInitUnicodeString(&usbStorName, USB_STOR_DRIVER_NAME);
			if (NT_SUCCESS(ObReferenceObjectByName(&usbStorName, OBJ_CASE_INSENSITIVE, NULL, 0, *IoDriverObjectType, 0, 0, &usbStor)))
			{
				ObDereferenceObject(usbStor);
				KdPrint(("Usb device %08x %08x started...\n", DeviceObject, usbStor));

				if (Globals.UsbStorDriver
					&& Globals.UsbStorDriver != usbStor)
				{
					ASSERT(Globals.ScsiHookHandle);
					KdPrint(("RE_HOOK USBSTOR SCSI!!!!"));
					ClearInlineHook(Globals.ScsiHookHandle);
					Globals.ScsiHookHandle = NULL;
					Globals.ScsiReadCompletionHandle = NULL;
					Globals.UsbStorDriver = usbStor;
				}
				if (!Globals.ScsiHookHandle)
				{
					KdPrint(("Hook UsbStor ...\n"));
					Globals.ScsiHookHandle = SetupInlineHook(usbStor->MajorFunction[IRP_MJ_SCSI], HookUsbScsi, NULL);
				}
			}
		}
		break;
	case IRP_MN_REMOVE_DEVICE:
		KdPrint(("Usb device %08x removed...\n", DeviceObject));
		break;
	}
	return ((NTSTATUS(*)(PDEVICE_OBJECT,PIRP))OrgFunction)(DeviceObject, Irp);
}

NTSTATUS
FsdReadCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
{
	PHOOK_IO_COMPLETION_CONTEXT hookContext = (PHOOK_IO_COMPLETION_CONTEXT)Context;

	KdPrint(("FsdReadCompletion: %08x\n", Context));

	//解密
	DecryptBuf_128AES(hookContext->Buffer, hookContext->Length);
	ExFreePool(hookContext);

	if (hookContext->OrgRoutine)
	{
		return hookContext->OrgRoutine(DeviceObject, Irp, hookContext->OrgContext);
	}
	return STATUS_SUCCESS;
}
NTSTATUS
HookFsdReadWrite(
	IN HANDLE OrgFunction,
	IN PDEVICE_OBJECT DeviceObject,
	IN PIRP Irp
)
{
	PFILE_OBJECT		fileObj = Irp->Tail.Overlay.OriginalFileObject;
	NTSTATUS status;

	//KdPrint(("Irp:%08x HookFsdRead:%08x Mdl:%08x\n", Irp, Irp->Tail.Overlay.OriginalFileObject,  Irp->MdlAddress));

	if (Irp->MdlAddress &&
		fileObj &&
		(fileObj->DeviceObject->DeviceType == FILE_DEVICE_DISK) &&
		(fileObj->DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) &&
		fileObj->FileName.Buffer &&
		wcschr(fileObj->FileName.Buffer, L'@'))
	{
		//
		//测试该Mdl数据是否需要进行加解密处理
		//
		PVOID mmAddr = MmGetSystemAddressForMdl(Irp->MdlAddress);
		
		KdPrint(("Usb Device:%08x Irp:%08x ", fileObj->DeviceObject, Irp));
		KdPrint(("MmAddress: %08x %wZ\n", mmAddr, &Irp->Tail.Overlay.OriginalFileObject->FileName));
		//
		//首先记录Mdl地址,调用原始函数-【fastfat同步等待】
		//
		RefreshCryptMdlList(NULL, mmAddr);
		//__asm int 3;
		status = ((NTSTATUS(*)(PDEVICE_OBJECT,PIRP))OrgFunction)(DeviceObject, Irp);
		//__asm int 3;
		RefreshCryptMdlList(mmAddr, NULL);
		return status;
	}
	
	return ((NTSTATUS(*)(PDEVICE_OBJECT,PIRP))OrgFunction)(DeviceObject, Irp);
}

NTSTATUS
HookUsbScsi(
	IN HANDLE OrgFunction,
	IN PDEVICE_OBJECT DeviceObject,
	IN PIRP Irp
	)
{
	PHOOK_IO_COMPLETION_CONTEXT conext = NULL;
	PIO_STACK_LOCATION	irpStack;
	PIO_STACK_LOCATION  irpNextStack;
	PSCSI_REQUEST_BLOCK	srb = NULL;
	PCDB				cdb = NULL;
	PMDL				mdl = NULL;
	PVOID				mmAddress = NULL;
	UNICODE_STRING		fastFatName;
	NTSTATUS			status;

	irpStack = IoGetCurrentIrpStackLocation(Irp);
	irpNextStack = IoGetNextIrpStackLocation(Irp);
	srb = irpStack->Parameters.Scsi.Srb;
	mdl = Irp->MdlAddress;

	if (IRP_MJ_INTERNAL_DEVICE_CONTROL == irpStack->MajorFunction && mdl && srb)
	{
		//SCSI接口命令-参考scsi手册以及机器狗代码
		cdb = (PCDB)srb->Cdb;
		mmAddress = MmGetSystemAddressForMdl(mdl);
		
		KdPrint(("Irp:%08x irpStack:%08x irpNextStack:%08x\n", Irp, irpStack, irpNextStack));
		//IOCTL_INTERNAL_USB_SUBMIT_URB
		switch (cdb->CDB10.OperationCode)
		{
		case SCSIOP_WRITE:
		case SCSIOP_WRITE_VERIFY:
			//KdPrint(("UsbScsi_Write FileObject:%08x MmAddress:%08x\n", Irp->Tail.Overlay.OriginalFileObject, mmAddress));
			if (RefreshCryptMdlList(mmAddress, mmAddress))
			{
				//获取原始文件对象
				KdPrint(("UsbScsi_Write CompletionRoutine:%08x File:%wZ  %04x Bytes\n", irpStack->CompletionRoutine, &Irp->Tail.Overlay.OriginalFileObject->FileName, srb->DataTransferLength));
				//对数据进行加密
				//__asm int 3;
				//EncryptBuf_128AES(mmAddress, srb->DataTransferLength);

				EncryptBuf_128RC4(mmAddress, srb->DataTransferLength);

				//Hook写完成,进行解密【维护Windows缓冲数据为明码】
				conext = SetupIoCompletionRoutineHook(Irp, irpStack, HookIoCompletionRoutine);
				if (conext) 
				{
					KdPrint(("UsbScsi_Write EncryptBuf_128RC4 %08x %08x...\n", conext->Buffer, conext->Length));
				}
				else
				{
					KdPrint(("USB Encrypt Fail to SetupIoCompletionRoutineHook...\n"));
				}
			}
			break;
		case SCSIOP_READ:
			//KdPrint(("UsbScsi_Read MmAddress: %08x CompletionRoutine %08x conext %08x... \n", mmAddress, irpStack->CompletionRoutine, irpStack->Context));
			//HOOK IO完成函数 等待读完成...
			status = ((NTSTATUS(*)(PDEVICE_OBJECT,PIRP))OrgFunction)(DeviceObject, Irp);
			ASSERT(status == STATUS_PENDING);
			//注意:可能Hook位置有错误
			/*
			if (irpNextStack->CompletionRoutine && !Globals.ScsiReadCompletionHandle)
			{
			KdPrint(("Inline Hook ScsiReadCompletionHandle %08x\n", irpNextStack->CompletionRoutine));
			Globals.ScsiReadCompletionHandle = SetupInlineHook(irpNextStack->CompletionRoutine, InlineHookIoCompletionRoutine, NULL);
			}
			*/
			//Hook Fsd
			if (!Globals.FastFatDriver)
			{
				RtlInitUnicodeString(&fastFatName, FAST_FAT_DRIVER_NAME);
				if (NT_SUCCESS(ObReferenceObjectByName(&fastFatName, OBJ_CASE_INSENSITIVE, NULL, 0, *IoDriverObjectType, 0, 0, &Globals.FastFatDriver)))
				{
					ObDereferenceObject(Globals.FastFatDriver);
					KdPrint(("Hook %wZ...\n", &fastFatName));
					Globals.fsdReadHookHandle = SetupInlineHook(Globals.FastFatDriver->MajorFunction[IRP_MJ_READ], HookFsdReadWrite, NULL);
					Globals.fsdWriteHookHandle = SetupInlineHook(Globals.FastFatDriver->MajorFunction[IRP_MJ_WRITE], HookFsdReadWrite, NULL);
				}
			}
			
			if (RefreshCryptMdlList(mmAddress, mmAddress))
			{
				KdPrint(("UsbScsi_Read MmAddress: %08x CompletionRoutine %08x %08x... \n", mmAddress, irpStack->CompletionRoutine, irpNextStack->CompletionRoutine));
				//hook pnpclass.sys 读完成函数
				conext = SetupIoCompletionRoutineHook(Irp, irpStack, HookIoCompletionRoutine);
				if (conext)
				{
					//conext->Length -》Cdb长度
					conext->Length = srb->DataTransferLength;
					KdPrint(("UsbScsi_Read %08x %08x %08x...\n", Irp, conext->Buffer, conext->Length));
				}
				else
				{
					KdPrint(("HOOK IO_COMPLETION FAILED! %08x %08x\n", Irp, irpNextStack));
				}
			}
			
			return status;
			break;
		case SCSIOP_MODE_SENSE:
			KdPrint(("Usb SCSIOP_MODE_SENSE...\n"));
			break;
		}
	}

	return ((NTSTATUS(*)(PDEVICE_OBJECT,PIRP))OrgFunction)(DeviceObject, Irp);
}

PVOID
SetupIoCompletionRoutineHook(
	IN PIRP Irp,
	IN PIO_STACK_LOCATION irsp,
	IN PIO_COMPLETION_ROUTINE HookHandle
	)
{
	PHOOK_IO_COMPLETION_CONTEXT conext = NULL;
	
	if (!irsp || !HookHandle) return NULL;
	
	conext = ExAllocatePool(NonPagedPool, sizeof(HOOK_IO_COMPLETION_CONTEXT));

	KdPrint(("Hook IO_STACK_LOCATION:%08x %08x\n", irsp, irsp->CompletionRoutine));

	if (conext)
	{
		//用户数据缓冲区
		conext->OrgRoutine = irsp->CompletionRoutine;
		conext->OrgContext = irsp->Context;
		conext->Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
		conext->Length = MmGetMdlByteCount(Irp->MdlAddress);	//获取数据长度
			
		irsp->CompletionRoutine = HookHandle;
		irsp->Context = conext;
		
		return conext;
	}
	else
	{
		KdPrint(("Hook IO_STACK_LOCATION FAILD\n"));
	}

	return NULL;
}

NTSTATUS
InlineHookIoCompletionRoutine(
	IN HANDLE OrgFunction,
	IN PDEVICE_OBJECT DeviceObject,
	IN PIRP Irp,
	IN PVOID Context
	)
{
	NTSTATUS status;
	PVOID mmAddress = NULL;
	
	status = ((NTSTATUS(*)(PDEVICE_OBJECT,PIRP,PVOID))OrgFunction)(DeviceObject, Irp, Context);

	if (Irp->MdlAddress)  
	{
		mmAddress = MmGetSystemAddressForMdl(Irp->MdlAddress);
		if (RefreshCryptMdlList(mmAddress, mmAddress))
		{
			//
			//[!!!]mmAddress在windbg调试模式下有数据,但是不开调试器就无数据:-<by boywhp 08/09/19
			//STATUS_MORE_PROCESSING_REQUIRED - Hook 位置错误!!

			KdPrint(("InlineHookIoCompletionRoutine %08x [%08x] %08x %d Bytes\n",  mmAddress, *(PULONG)mmAddress, status, MmGetMdlByteCount(Irp->MdlAddress)));
			__asm int 3;
			DecryptBuf_128AES(mmAddress, MmGetMdlByteCount(Irp->MdlAddress));
			//__asm int 3;
		}
	}

	//status = ((NTSTATUS(*)(PDEVICE_OBJECT,PIRP,PVOID))OrgFunction)(DeviceObject, Irp, Context);
	return status;
}

NTSTATUS
HookIoCompletionRoutine(
	IN PDEVICE_OBJECT DeviceObject,
	IN PIRP Irp,
	IN PVOID Context)
{
	NTSTATUS status = STATUS_SUCCESS;
	PHOOK_IO_COMPLETION_CONTEXT hookContext = (PHOOK_IO_COMPLETION_CONTEXT)Context;
	
	ASSERT(hookContext);

	KdPrint(("Hook IoCompletionRoutine %08x %08x ", hookContext->OrgRoutine, hookContext->OrgContext));
	//首先调用原始的完成函数

	//修改Irp数据
	KdPrint(("%08x [%08x] %d Bytes\n", hookContext->Buffer, *(PULONG)hookContext->Buffer, hookContext->Length));
	//__asm int 3;
	//DecryptBuf_128AES(hookContext->Buffer, hookContext->Length);
	DecryptBuf_128RC4(hookContext->Buffer, hookContext->Length);
	//__asm int 3;
	if (!RefreshCryptMdlList(hookContext->Buffer, NULL))
	{
		KdPrint(("HookIoCompletionRoutine Free CryptMdlList Fail!\n"));
	}
	if (hookContext->OrgRoutine)
	{
		KdPrint(("Call OrgRoutine IoCompletionRoutine:%08x\n", hookContext->OrgRoutine));
		status = hookContext->OrgRoutine(DeviceObject, Irp, hookContext->OrgContext);
	}
	ExFreePool(hookContext);
	return status;
}

BOOLEAN
RefreshCryptMdlList(PVOID MmAddress, PVOID NewMmAddress)
/*
 *	在CryptMdlList中搜索MmAddress,并写入NewMmAddress
 */
{
	INT i;
	for (i=0; i<MAX_MDL_LIST; i++)
	{
		if (MmAddress == Globals.CryptMdlList[i])
		{
			Globals.CryptMdlList[i] = NewMmAddress;
			return TRUE;
		}
	}
	return FALSE;
}

⌨️ 快捷键说明

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