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