找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
楼主: 乔丹二世

一份磁盘级过滤的代码

  [复制链接]

280

主题

203

回帖

0

精华

版主

积分
1808
发表于 2013-10-29 15:58:09 | 显示全部楼层 |阅读模式
本帖最后由 乔丹二世 于 2013-10-29 16:01 编辑

听说TA在烦如何过滤SCSI请求块(SRB),于是本大牛乔二再次发出找骂神功,翻出了一份处理SRB的代码:
  1. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. // BkFilter project
  3. //        
  4. // module: bkfilter.c
  5. // $$$$Revision: 67 $$$$
  6. // $$$$Date: 2012-05-29 22:20:56 +0400 (Вт, 29 май 2012) $$$$
  7. // description:
  8. //        Disk filter driver.
  9. //        Protects BK initial loader and VFS area (if any) from unauthorized reading and writing.


  10. #include <ntddk.h>
  11. #include <ntdddisk.h>
  12. #include <ntddscsi.h>
  13. #include <srb.h>
  14. #include <scsi.h>

  15. #include "version.h"
  16. #include "ntddkex.h"
  17. #include "kdbg.h"
  18. #include "..\bkdrv\bkdrv.h"
  19. #include "..\bkdrv\khook.h"

  20. #include "bklib.h"
  21. #include "bkfilter.h"


  22. PDEVICE_OBJECT IoGetLowerDeviceObject(
  23.   __in  PDEVICE_OBJECT DeviceObject
  24. );


  25. #define                wczBootDevice                L"\\Device\\Harddisk0\\DR0"
  26. #define                wczHarddisk0                L"\\Device\\Harddisk0"
  27. #define                wczHarddiskVolume1        L"\\Device\\HarddiskVolume1"

  28. #define                NTFS_LOADER_SIZE        16        // sectors


  29. BK_FS_AREA                g_FsArea;
  30. PDEVICE_OBJECT        g_ClassDevice = NULL;
  31. ULONG                        g_MySrbMark = 0;


  32. NTSTATUS my_DispatchScsi(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
  33. HOOK_FUNCTION hook_DispatchScsi = {NULL, NULL, &my_DispatchScsi, NULL, NULL};
  34. static HOOK ClassDispatchScsi = DEFINE_HOOK(&hook_DispatchScsi, HOOK_TYPE_POINTER);


  35. // ---- Predefinitions ----------------------------------------------------------------------------------------------------

  36. PUNICODE_STRING        AllocUniString(VOID);
  37. VOID FreeUniString(PUNICODE_STRING        pUs);
  38. LONG volatile        g_WorkerEntryCount;


  39. // ---- Debug support routines --------------------------------------------------------------------------------------------


  40. #if DBG
  41. VOID
  42.         DbgPrintCdb(
  43.                  IN PCDB Cdb,
  44.                  IN ULONG Length
  45.                  )
  46. {
  47.         DbgPrint("\tCdb:\n\t\tOpCode: %02X\n",
  48.                 Cdb->CDB6GENERIC.OperationCode);
  49. }

  50. PSTR g_SrbFlags[]={
  51.         "0x00000001",
  52.         "SRB_FLAGS_QUEUE_ACTION_ENABLE",
  53.         "SRB_FLAGS_DISABLE_DISCONNECT",
  54.         "SRB_FLAGS_DISABLE_SYNCH_TRANSFER",

  55.         "SRB_FLAGS_BYPASS_FROZEN_QUEUE",
  56.         "SRB_FLAGS_DISABLE_AUTOSENSE",
  57.         "SRB_FLAGS_DATA_IN",
  58.         "SRB_FLAGS_DATA_OUT",

  59.         "SRB_FLAGS_NO_QUEUE_FREEZE",
  60.         "SRB_FLAGS_ADAPTER_CACHE_ENABLE",
  61.         "SRB_FLAGS_FREE_SENSE_BUFFER",
  62.         "0x00000800",

  63.         "0x00001000",
  64.         "0x00002000",
  65.         "0x00004000",
  66.         "0x00008000",

  67.         "SRB_FLAGS_IS_ACTIVE",
  68.         "SRB_FLAGS_ALLOCATED_FROM_ZONE",
  69.         "SRB_FLAGS_SGLIST_FROM_POOL",
  70.         "SRB_FLAGS_BYPASS_LOCKED_QUEUE",

  71.         "SRB_FLAGS_NO_KEEP_AWAKE",
  72.         "SRB_FLAGS_PORT_DRIVER_ALLOCSENSE",
  73.         "SRB_FLAGS_PORT_DRIVER_SENSEHASPORT",
  74.         "SRB_FLAGS_DONT_START_NEXT_PACKET",

  75.         "PORT 0x01000000",
  76.         "PORT 0x02000000",
  77.         "PORT 0x04000000",
  78.         "PORT 0x08000000",

  79.         "CLASS 0x10000000",
  80.         "CLASS 0x20000000",
  81.         "CLASS 0x40000000",
  82.         "CLASS 0x80000000"
  83. };

  84. VOID
  85.         DbgPrintSrbFlags(
  86.                 IN ULONG SrbFlags
  87.                 )
  88. {
  89.         ULONG i;
  90.         DbgPrint("\tSrbFlags: ");

  91.         if(!SrbFlags)
  92.                 DbgPrint("SRB_FLAGS_NO_DATA_TRANSFER");
  93.         else
  94.         {
  95.                 for(i=0;SrbFlags;++i,SrbFlags>>=1)
  96.                 {
  97.                         if(SrbFlags&1)
  98.                         {
  99.                                 DbgPrint("%s",g_SrbFlags[i]);
  100.                                 if(SrbFlags&0xFFFFFFFE)
  101.                                         DbgPrint("|\n\t\t");
  102.                         }
  103.                 }
  104.         }
  105.         DbgPrint("\n");
  106. }

  107. PSTR g_SrbFuncs[]={
  108.         "SRB_FUNCTION_EXECUTE_SCSI",
  109.         "SRB_FUNCTION_CLAIM_DEVICE",
  110.         "SRB_FUNCTION_IO_CONTROL",
  111.         "SRB_FUNCTION_RECEIVE_EVENT",
  112.         "SRB_FUNCTION_RELEASE_QUEUE",
  113.         "SRB_FUNCTION_ATTACH_DEVICE",
  114.         "SRB_FUNCTION_RELEASE_DEVICE",
  115.         "SRB_FUNCTION_SHUTDOWN",
  116.         "SRB_FUNCTION_FLUSH",
  117.         "SRB_FUNCTION_ABORT_COMMAND",
  118.         "SRB_FUNCTION_RELEASE_RECOVERY",
  119.         "SRB_FUNCTION_RESET_BUS",
  120.         "SRB_FUNCTION_RESET_DEVICE",
  121.         "SRB_FUNCTION_TERMINATE_IO",
  122.         "SRB_FUNCTION_FLUSH_QUEUE",
  123.         "SRB_FUNCTION_REMOVE_DEVICE",
  124.         "SRB_FUNCTION_WMI",
  125.         "SRB_FUNCTION_LOCK_QUEUE",
  126.         "SRB_FUNCTION_UNLOCK_QUEUE",
  127.         "SRB_FUNCTION_RESET_LOGICAL_UNIT"
  128. };

  129. VOID
  130.         DbgPrintSrb(
  131.                 IN PSCSI_REQUEST_BLOCK Srb
  132.                 )

  133. {
  134.         DbgPrint("SRB:\n\tLength: %d\n\tFunction: %s\n\tPathId: %d\n\tTargetId: %d\n\tLun: %d\n",
  135.                 Srb->Length,Srb->Function>SRB_FUNCTION_RESET_LOGICAL_UNIT?"Invalid function"
  136.                 :g_SrbFuncs[Srb->Function], Srb->PathId,Srb->TargetId,Srb->Lun);
  137.         DbgPrint("\tCdbLength: %d\n\tSenseInfoBufferLength: %d\n", Srb->CdbLength,Srb->SenseInfoBufferLength);
  138.         DbgPrintSrbFlags(Srb->SrbFlags);
  139.         DbgPrint("\tDataTransferLength: %d\n\tTimeOutValue: %d\n", Srb->DataTransferLength,Srb->TimeOutValue);
  140.         DbgPrintCdb((PCDB)Srb->Cdb,Srb->CdbLength);
  141. }

  142. #endif


  143. //
  144. //        Returns a pointer to the next-lower-level device object on the driver stack if any.
  145. //        Reurns STATUS_NOT_FOUND if the next-lower-level driver is not loaded or
  146. //         the specified device is the lowest device object in the driver stack
  147. //
  148. NTSTATUS GetLowerDeviceObjectByName(
  149.         IN        PUNICODE_STRING uDeviceName,        // name of a device
  150.         OUT        PDEVICE_OBJECT* pDeviceObj                // receives a pointer to the next-lower-level device object
  151.         )
  152. {
  153.         HANDLE                hFile;
  154.         NTSTATUS        ntStatus;
  155.         PFILE_OBJECT        FileObj;
  156.         PDEVICE_OBJECT        DeviceObj = NULL;
  157.         OBJECT_ATTRIBUTES        oa;
  158.         IO_STATUS_BLOCK                IoStatus;

  159.         InitializeObjectAttributes(&oa, uDeviceName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);

  160.         ntStatus = ZwOpenFile(&hFile, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &oa, &IoStatus,
  161.                 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);

  162.         if (NT_SUCCESS(ntStatus))
  163.         {
  164.                 ntStatus = ObReferenceObjectByHandle(hFile, GENERIC_READ, *IoFileObjectType, KernelMode, &FileObj, NULL);
  165.                 if (NT_SUCCESS(ntStatus))
  166.                 {                        
  167.                         if (DeviceObj = IoGetLowerDeviceObject(FileObj->DeviceObject))
  168.                                 *pDeviceObj = DeviceObj;
  169.                         else
  170.                                 ntStatus = STATUS_NOT_FOUND;
  171.                         ObDereferenceObject(FileObj);
  172.                 }
  173.                 ZwClose(hFile);
  174.         }        // if (NT_SUCCESS(ntStatus))

  175.         return(ntStatus);
  176. }        


  177. NTSTATUS        FltAttachClassDeviceDriver(PUNICODE_STRING        uDeviceName)
  178. {
  179.         NTSTATUS                ntStatus;
  180.         PDRIVER_OBJECT        DriverObj;
  181.         LARGE_INTEGER        TickCount;

  182.         if (NT_SUCCESS(ntStatus = GetLowerDeviceObjectByName(uDeviceName, &g_ClassDevice)))
  183.         {
  184.                 DriverObj = g_ClassDevice->DriverObject;

  185.                 // Initializing BK internal request mark value
  186.                 KeQueryTickCount(&TickCount);
  187.                 g_MySrbMark = TickCount.LowPart;

  188.                 // Setting hooks
  189.                 if (DriverObj->MajorFunction[IRP_MJ_SCSI])
  190.                         SetHook(&ClassDispatchScsi, &DriverObj->MajorFunction[IRP_MJ_SCSI], DriverObj->DriverStart);
  191.         }

  192.         return(ntStatus);
  193. }


  194. VOID        FltReplaceRead(
  195.         ULONGLONG        StartBlock,
  196.         ULONG                NumberBlocks,
  197.         PCHAR                DataBuffer,
  198.         ULONG                Length
  199.         )
  200. {
  201.         ULONG        Skipped;
  202.         PCHAR        FillBuffer;
  203.         ULONG        FillLength = 0;

  204.         if ((StartBlock + NumberBlocks) > g_FsArea.StartSector && StartBlock < (g_FsArea.StartSector + g_FsArea.NumberOfSectors))
  205.         {
  206.                 FillBuffer = DataBuffer;
  207.                 FillLength = Length;

  208.                 if (StartBlock < g_FsArea.StartSector)
  209.                 {
  210.                         Skipped = ((ULONG)(g_FsArea.StartSector - StartBlock)) * g_FsArea.BytesPerSector;
  211.                         ASSERT(FillLength > Skipped);
  212.                         FillBuffer += Skipped;
  213.                         FillLength -= Skipped;
  214.                 }

  215.                 if ((StartBlock + NumberBlocks) > (g_FsArea.StartSector + g_FsArea.NumberOfSectors))
  216.                 {
  217.                         Skipped = (ULONG)((StartBlock + NumberBlocks) - (g_FsArea.StartSector + g_FsArea.NumberOfSectors));
  218.                         Skipped *= g_FsArea.BytesPerSector;
  219.                         ASSERT(FillLength > Skipped);
  220.                         FillLength -= Skipped;
  221.                 }

  222.                 if (FillLength)
  223.                 {
  224.                         RtlZeroMemory(FillBuffer, FillLength);
  225.                         KdPrint(("BKFLT: Replace %u bytes read starting from sector %u.\n", FillLength, (ULONG)StartBlock + (ULONG)(FillBuffer - DataBuffer) / g_FsArea.BytesPerSector));
  226.                 }
  227.         }

  228.         if (((StartBlock + NumberBlocks) > g_FsArea.BootSector && StartBlock < (g_FsArea.BootSector + 16)))
  229.         {
  230.                 FillBuffer = DataBuffer;
  231.                 FillLength = Length;

  232.                 if (StartBlock < g_FsArea.BootSector)
  233.                 {
  234.                         Skipped = ((ULONG)(g_FsArea.BootSector - StartBlock)) *  g_FsArea.BytesPerSector;
  235.                         ASSERT(FillLength > Skipped);
  236.                         FillBuffer += Skipped;
  237.                         FillLength -= Skipped;
  238.                 }

  239.                 if ((StartBlock + NumberBlocks) > (g_FsArea.BootSector + 16))
  240.                 {
  241.                         Skipped = (ULONG)((StartBlock + NumberBlocks) - (g_FsArea.BootSector + 16));
  242.                         Skipped *= g_FsArea.BytesPerSector;
  243.                         ASSERT(FillLength > Skipped);
  244.                         FillLength -= Skipped;
  245.                 }

  246.                 KdPrint(("BKFLT: Replace %u bytes read starting from sector %u.\n", FillLength, (ULONG)StartBlock + (ULONG)(FillBuffer - DataBuffer) / g_FsArea.BytesPerSector));
  247.         }        // if ((StartBlock + NumberBlocks) > g_FsArea.StartSector && StartBlock < (g_FsArea.StartSector + g_FsArea.NumberOfSectors))               
  248. }


  249. BOOL        FltIsWithinBkArea(
  250.         ULONGLONG        StartBlock,
  251.         ULONG                NumberBlocks
  252.         )
  253. {
  254.         BOOL Ret = FALSE;

  255.         if (((StartBlock + NumberBlocks) > g_FsArea.StartSector &&         StartBlock < (g_FsArea.StartSector + g_FsArea.NumberOfSectors)) ||
  256.                 ((StartBlock + NumberBlocks) > g_FsArea.BootSector && StartBlock < (g_FsArea.BootSector + 16)))
  257.                 Ret = TRUE;

  258.         return(Ret);
  259. }

  260. //
  261. //        Parses specified SRB extracting starting block address, number of blocks, buffer and it's length.
  262. //
  263. UCHAR FltParseSrb(
  264.         IN        PIRP                Irp,
  265.         OUT        PULONGLONG        pStartBlock,
  266.         OUT        PULONG                pNumberBlocks,
  267.         OUT        PCHAR*                pDataBuffer,
  268.         OUT        PULONG                pLength
  269.         )
  270. {               
  271.         PIO_STACK_LOCATION        IrpStack = IoGetCurrentIrpStackLocation(Irp);
  272.         PSCSI_REQUEST_BLOCK        Srb = IrpStack->Parameters.Scsi.Srb;
  273.         PCDB        pCdb = (PCDB)Srb->Cdb;
  274.         UCHAR        CdbOpCode = ((PCDB)Srb->Cdb)->CDB6GENERIC.OperationCode;

  275.         LARGE_INTEGER        LogicalBlockAddr;
  276.         ULONG        NumberBlocks = 0;
  277.         PCHAR        UserBuffer;


  278.         if (CdbOpCode == SCSIOP_READ || CdbOpCode == SCSIOP_WRITE ||
  279.                 CdbOpCode == SCSIOP_READ_DATA_BUFF || CdbOpCode == SCSIOP_WRITE_DATA_BUFF)
  280.         {
  281.                 // Checking if current SRB is not marked as BK internal request
  282.                 if (Srb->QueueSortKey != g_MySrbMark)
  283.                 {
  284.                         if ((Irp->MdlAddress) && (UserBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, LowPagePriority)))
  285.                         {
  286.                                 //        DataBuffer contains the same as MmGetMdlVirtualAddress(Irp->Mdl) + offset (where offset is non-zero if
  287.                                 //                SRB is a result of breaking a big request to smaller chunks) or NULL.
  288.                                 if (Srb->DataBuffer)
  289.                                         UserBuffer = Srb->DataBuffer;

  290.                                 if ( Srb->CdbLength == 16 )
  291.                                 {
  292.                                         REVERSE_BYTES_QUAD(&LogicalBlockAddr, pCdb->CDB16.LogicalBlock);
  293.                                         REVERSE_BYTES(&NumberBlocks, pCdb->CDB16.TransferLength);
  294.                                 }
  295.                                 else if ( Srb->CdbLength == 10 )
  296.                                 {
  297.                                         LogicalBlockAddr.HighPart = 0;
  298.                                         ((PFOUR_BYTE)&LogicalBlockAddr.LowPart)->Byte0=pCdb->CDB10.LogicalBlockByte3;
  299.                                         ((PFOUR_BYTE)&LogicalBlockAddr.LowPart)->Byte1=pCdb->CDB10.LogicalBlockByte2;
  300.                                         ((PFOUR_BYTE)&LogicalBlockAddr.LowPart)->Byte2=pCdb->CDB10.LogicalBlockByte1;
  301.                                         ((PFOUR_BYTE)&LogicalBlockAddr.LowPart)->Byte3=pCdb->CDB10.LogicalBlockByte0;
  302.                                         ((PFOUR_BYTE)&NumberBlocks)->Byte0=pCdb->CDB10.TransferBlocksLsb;
  303.                                         ((PFOUR_BYTE)&NumberBlocks)->Byte1=pCdb->CDB10.TransferBlocksMsb;
  304.                                 }
  305.                                 else
  306.                                 {
  307.                                         ASSERT(FALSE);
  308.                                 }

  309.                                 *pStartBlock        = (ULONGLONG)LogicalBlockAddr.QuadPart;
  310.                                 *pNumberBlocks        = NumberBlocks;
  311.                                 *pLength = Srb->DataTransferLength;
  312.                                 *pDataBuffer = UserBuffer;
  313.                         }        // if ((Irp->MdlAddress) && (UserBuffer = MmGetSystemAddressForMdlSafe(MdlAddress, LowPagePriority)))
  314.                         else
  315.                                 // No User buffer specified, skipping
  316.                                 CdbOpCode = SCSIOP_TEST_UNIT_READY;
  317.                 }        // if (Srb->QueueSortKey != g_MySrbMark)
  318.                 else
  319.                 {
  320.                         // Restoring Srb->QueueSortKey value
  321.                         ((PFOUR_BYTE)&Srb->QueueSortKey)->Byte0 = pCdb->CDB10.LogicalBlockByte3;
  322.                         ((PFOUR_BYTE)&Srb->QueueSortKey)->Byte1 = pCdb->CDB10.LogicalBlockByte2;
  323.                         ((PFOUR_BYTE)&Srb->QueueSortKey)->Byte2 = pCdb->CDB10.LogicalBlockByte1;
  324.                         ((PFOUR_BYTE)&Srb->QueueSortKey)->Byte3 = pCdb->CDB10.LogicalBlockByte0;

  325.                         // Skipping current SRB
  326.                         CdbOpCode = SCSIOP_TEST_UNIT_READY;
  327.                 }
  328.         }        // if (CdbOpCode == SCSIOP_READ || CdbOpCode == SCSIOP_WRITE ||

  329.         return(CdbOpCode);
  330. }



  331. NTSTATUS FltIrpCompletionRoutine(
  332.     IN PDEVICE_OBJECT DeviceObject,
  333.     IN PIRP Irp,
  334.     IN PVOID Context
  335.     )
  336. {
  337.         NTSTATUS        ntStatus1, ntStatus = STATUS_MORE_PROCESSING_REQUIRED;
  338.         PFLT_COMPLETION_CONTEXT FltCtx = (PFLT_COMPLETION_CONTEXT)Context;
  339.         PIO_STACK_LOCATION                IrpStack = IoGetCurrentIrpStackLocation(Irp);

  340.         // restore saved completion routine, context and control flags
  341.         IrpStack->CompletionRoutine = FltCtx->CompletionRoutine;
  342.         IrpStack->Context = FltCtx->CompletionContext;
  343.         IrpStack->Control = FltCtx->Control;

  344.         ntStatus1 = Irp->IoStatus.Status;

  345.         if (NT_SUCCESS(ntStatus1))
  346.         {
  347.                 PCHAR UserBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, LowPagePriority);
  348.                 FltReplaceRead(FltCtx->StartBlock, FltCtx->NumberBlocks, UserBuffer, FltCtx->Length);
  349.         }               

  350.         if (IrpStack->CompletionRoutine)
  351.         {
  352.                 if ((NT_SUCCESS(ntStatus1) && (IrpStack->Control | SL_INVOKE_ON_SUCCESS)) ||
  353.                         (ntStatus1 == STATUS_CANCELLED && (IrpStack->Control | SL_INVOKE_ON_CANCEL)) ||
  354.                         (!NT_SUCCESS(ntStatus1) && ntStatus1 != STATUS_CANCELLED && (IrpStack->Control | SL_INVOKE_ON_ERROR))
  355.                         )
  356.                 {
  357.                         // Calling original IO completion routine
  358.                         ntStatus = (IrpStack->CompletionRoutine)(DeviceObject, Irp, IrpStack->Context);
  359.                 }
  360.         }        // if (IrpStack->CompletionRoutine)

  361.         MyFreePool(FltCtx);

  362.     return(ntStatus);
  363. }


  364. NTSTATUS FltForwardScsiIrpAsync(
  365.     IN PDEVICE_OBJECT DeviceObject,
  366.     IN PIRP                        Irp,
  367.         IN ULONGLONG        StartBlock,
  368.         ULONG                        NumberBlocks,
  369.         PCHAR                        DataBuffer,
  370.         ULONG                        Length
  371.     )
  372. {
  373.         NTSTATUS        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
  374.         PFLT_COMPLETION_CONTEXT        FltCtx;
  375.         PIO_STACK_LOCATION                IrpStack = IoGetCurrentIrpStackLocation(Irp);


  376.         if (FltCtx = MyAllocatePool(NonPagedPool, sizeof(FLT_COMPLETION_CONTEXT)))
  377.         {
  378.                 FltCtx->StartBlock = StartBlock;
  379.                 FltCtx->NumberBlocks = NumberBlocks;
  380.                 FltCtx->DataBuffer = DataBuffer;
  381.                 FltCtx->Length        = Length;

  382.                 // save previouse completion routine, context and control flags
  383.                 FltCtx->CompletionRoutine = IrpStack->CompletionRoutine;
  384.                 FltCtx->CompletionContext = IrpStack->Context;
  385.                 FltCtx->Control = IrpStack->Control;

  386.                 // set a completion routine, context and control flags
  387.                 IrpStack->CompletionRoutine = &FltIrpCompletionRoutine;
  388.                 IrpStack->Context = FltCtx;
  389.                 IrpStack->Control = SL_INVOKE_ON_CANCEL | SL_INVOKE_ON_SUCCESS | SL_INVOKE_ON_ERROR;

  390.                 // call the next lower device
  391.                 ntStatus = ((PDRIVER_DISPATCH)hook_DispatchScsi.Original)(DeviceObject, Irp);
  392.         }
  393.     return(ntStatus);

  394. }        // FltProcessScsiIrpSynchronous



  395. // ---- Filter API functions -------------------------------------------------------------------------------------------------

  396. NTSTATUS FltIoCompleteCallback(
  397.     IN PDEVICE_OBJECT DeviceObject,
  398.     IN PIRP Irp,
  399.     IN PVOID Context
  400.     )
  401. {
  402.     Irp->UserIosb->Status = Irp->IoStatus.Status;
  403.     Irp->UserIosb->Information = Irp->IoStatus.Information;
  404.         KeSetEvent(Irp->UserEvent, IO_NO_INCREMENT, FALSE);

  405.         UNREFERENCED_PARAMETER(DeviceObject);
  406.         UNREFERENCED_PARAMETER(Context);

  407.     return STATUS_MORE_PROCESSING_REQUIRED;
  408. }


  409. NTSTATUS FltReadWriteSectors(
  410.     IN ULONG MajorFunction,
  411.     IN PVOID Buffer,
  412.     IN ULONG SectorOffset,
  413.     IN ULONG SectorCount
  414.     )
  415. {
  416.     PCDB        Cdb;
  417.     ULONG        Length;
  418.         PMDL    Mdl;
  419.     KEVENT        Event;
  420.     PIRP        Irp;
  421.         NTSTATUS        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
  422.         PSCSI_REQUEST_BLOCK Srb;
  423.     IO_STATUS_BLOCK     IoStatus;
  424.     PIO_STACK_LOCATION  IrpSp;
  425.         PSENSE_DATA         SenseData;


  426.         if (g_ClassDevice)
  427.         {
  428.                 Length = SectorCount * g_FsArea.BytesPerSector;

  429.                 if (Srb = MyAllocatePool(NonPagedPool, sizeof(SCSI_REQUEST_BLOCK) + sizeof(SENSE_DATA)))
  430.                 {
  431.                         RtlZeroMemory(Srb, sizeof(SCSI_REQUEST_BLOCK) + sizeof(SENSE_DATA));
  432.                         SenseData = (PSENSE_DATA)(Srb + 1);

  433.                         if (Irp = IoAllocateIrp(g_ClassDevice->StackSize, FALSE))
  434.                         {
  435.                                  if (Mdl = IoAllocateMdl(Buffer, Length, FALSE, FALSE, Irp))
  436.                                  {
  437.                                          MmProbeAndLockPages(Mdl, KernelMode, MajorFunction == IRP_MJ_WRITE ? IoReadAccess : IoWriteAccess);
  438.                                  
  439.                                          // Initializing the SRB
  440.                                          Srb->Length = sizeof(SCSI_REQUEST_BLOCK);
  441.                                          Srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
  442.                                          Srb->OriginalRequest = Irp;
  443.                                          Srb->DataBuffer = Buffer;
  444.                                                                           
  445.                                          Srb->DataTransferLength = Length;
  446.                                          Srb->QueueAction = SRB_SIMPLE_TAG_REQUEST;
  447.                                          Srb->SrbStatus = SRB_STATUS_PENDING;
  448.                                          Srb->ScsiStatus = STATUS_SUCCESS;
  449.                                          Srb->SenseInfoBuffer = SenseData;
  450.                                          Srb->SenseInfoBufferLength = sizeof(SENSE_DATA);

  451.                                          if (MajorFunction == IRP_MJ_READ)
  452.                                                  Srb->SrbFlags = SRB_FLAGS_DATA_IN;
  453.                                          else
  454.                                                  Srb->SrbFlags = SRB_FLAGS_DATA_OUT;
  455.                                          
  456.                                          Srb->SrbFlags = Srb->SrbFlags | 0x40000100;
  457.                                          if (MajorFunction == IRP_MJ_READ)
  458.                                                  Srb->SrbFlags |= SRB_FLAGS_ADAPTER_CACHE_ENABLE;
  459.                                          else
  460.                                                  Srb->SrbFlags |= SRB_FLAGS_DISABLE_AUTOSENSE;
  461.                                          
  462.                                          Srb->TimeOutValue = (Length / 1024) + 1;
  463.                                          Srb->CdbLength = 10;

  464.                                          // Marking SRB as BK internal request to transfer it to underlying driver without any processing
  465.                                          Srb->QueueSortKey = g_MySrbMark;
  466.                                          
  467.                                          // Initializing the CDB
  468.                                          Cdb = (PCDB)Srb->Cdb;
  469.                                          Cdb->CDB10.OperationCode = (UCHAR)((MajorFunction - IRP_MJ_READ) + (MajorFunction - IRP_MJ_READ) + SCSIOP_READ);
  470.                                          Cdb->CDB10.LogicalUnitNumber = 4;

  471.                                          Cdb->CDB10.LogicalBlockByte0 = (UCHAR)(SectorOffset >> 24);
  472.                                          Cdb->CDB10.LogicalBlockByte1 = (UCHAR)(SectorOffset >> 16);
  473.                                          Cdb->CDB10.LogicalBlockByte2 = (UCHAR)(SectorOffset >> 8);
  474.                                          Cdb->CDB10.LogicalBlockByte3 = (UCHAR)SectorOffset;
  475.                                          
  476.                                          Cdb->CDB10.TransferBlocksMsb = (UCHAR)(SectorCount >> 8);
  477.                                          Cdb->CDB10.TransferBlocksLsb = (UCHAR)SectorCount;

  478.                                          // Initializing the IRP
  479.                                          ASSERT(Irp->MdlAddress == Mdl);
  480.                                          Irp->UserIosb = &IoStatus;
  481.                                          Irp->UserEvent = &Event;
  482.                                          Irp->IoStatus.Status = STATUS_SUCCESS;
  483.                                          Irp->IoStatus.Information = 0;
  484.                                          Irp->Flags = IRP_SYNCHRONOUS_API | IRP_NOCACHE;
  485.                                          Irp->AssociatedIrp.SystemBuffer = NULL;
  486.                                          Irp->Cancel = FALSE;
  487.                                          Irp->RequestorMode = KernelMode;
  488.                                          Irp->CancelRoutine = NULL;
  489.                                          Irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
  490.                                          
  491.                                          IrpSp = IoGetNextIrpStackLocation(Irp);
  492.                                          IrpSp->DeviceObject = g_ClassDevice;
  493.                                          IrpSp->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
  494.                                          IrpSp->Parameters.Scsi.Srb = Srb;
  495.                                          
  496.                                            KeInitializeEvent(&Event, NotificationEvent, FALSE);
  497.                                          IoSetCompletionRoutine(Irp, FltIoCompleteCallback, Srb, TRUE, TRUE, TRUE);
  498.                                          
  499.                                           // Calling the target class device
  500.                                          ntStatus = IoCallDriver(g_ClassDevice, Irp);
  501.                                        
  502.                                          if (ntStatus == STATUS_PENDING)
  503.                                          {
  504.                                                  KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
  505.                                                  ntStatus = IoStatus.Status;
  506.                                          }
  507.                                          
  508.                                          if (Srb->SenseInfoBuffer != SenseData)
  509.                                          {
  510.                                                  if (Srb->SenseInfoBuffer)                                         
  511.                                                          MyFreePool(Srb->SenseInfoBuffer);
  512.                                          }

  513.                                          MmUnlockPages(Mdl);
  514.                                          IoFreeMdl(Mdl);
  515.                                  }        // if (Mdl = IoAllocateMdl(Buffer, Length, FALSE, FALSE, Irp))
  516.                                  IoFreeIrp(Irp);
  517.                         }        // if (Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE))
  518.                         MyFreePool(Srb);
  519.                 }        // if (Srb = MyAllocatePool(NonPagedPool, sizeof(SCSI_REQUEST_BLOCK) + sizeof(SENSE_DATA)))
  520.         }        // if (g_ClassDevice)

  521.     return (ntStatus);
  522. }

  523. // ---- Filter hook functions ------------------------------------------------------------------------------------------------

  524. //
  525. //        Standard IRP_MJ_SCSI dispatch routine hook
  526. //
  527. NTSTATUS my_DispatchScsi(
  528.     IN PDEVICE_OBJECT DeviceObject,
  529.     IN PIRP Irp
  530.     )
  531. {
  532.         NTSTATUS        ntStatus = STATUS_REQUEST_NOT_ACCEPTED;
  533.         ULONGLONG        StartBlock;
  534.         ULONG        NumberBlocks, Length;
  535.         UCHAR        CdbOpCode;
  536.         PCHAR        DataBuffer;
  537.         
  538.         ENTER_HOOK();

  539.         if (DeviceObject == g_ClassDevice)
  540.         {
  541.                 //DbgPrintSrb(Srb);

  542.                 CdbOpCode = FltParseSrb(Irp, &StartBlock, &NumberBlocks, &DataBuffer, &Length);

  543.                 if (CdbOpCode == SCSIOP_WRITE || CdbOpCode == SCSIOP_WRITE_DATA_BUFF)
  544.                 {
  545.                         if (FltIsWithinBkArea(StartBlock, NumberBlocks))
  546.                         {
  547.                                 ntStatus = STATUS_ACCESS_DENIED;
  548.                                 Irp->IoStatus.Status = ntStatus;
  549.                                 IoCompleteRequest(Irp, IO_NO_INCREMENT);
  550.                                 KdPrint(("BKFLT: Write from %u for %u sectors - blocked.\n", (ULONG)StartBlock, NumberBlocks));
  551.                         }
  552.                 }        // if (CdbOpCode == SCSIOP_WRITE || CdbOpCode == SCSIOP_WRITE_DATA_BUFF)
  553.                 else if (CdbOpCode == SCSIOP_READ || CdbOpCode == SCSIOP_READ_DATA_BUFF)
  554.                 {
  555.                         if (FltIsWithinBkArea(StartBlock, NumberBlocks))
  556.                                 ntStatus = FltForwardScsiIrpAsync(DeviceObject, Irp, StartBlock, NumberBlocks, DataBuffer, Length);

  557.                 }        // else if (CdbOpCode == SCSIOP_READ || CdbOpCode == SCSIOP_READ_DATA_BUFF)
  558.         }        // if (DeviceObject == g_ClassDevice)

  559.         if (ntStatus == STATUS_REQUEST_NOT_ACCEPTED)
  560.                 ntStatus = ((PDRIVER_DISPATCH)hook_DispatchScsi.Original)(DeviceObject, Irp);

  561.         LEAVE_HOOK();

  562.         return(ntStatus);
  563. }        // my_DispatchScsi


  564. // ---- Filter startup/cleanup -----------------------------------------------------------------------------------------------

  565. NTSTATUS        FltStartup(IN PBK_FS_AREA FsArea)
  566. {
  567.         NTSTATUS        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
  568.         UNICODE_STRING        uDeviceName = RTL_CONSTANT_STRING(wczBootDevice);

  569.         KdPrint(("BKFLT: BK filter driver started.\n"));

  570.         HookInit();

  571.         RtlMoveMemory(&g_FsArea, FsArea, sizeof(BK_FS_AREA));

  572.         ntStatus = FltAttachClassDeviceDriver(&uDeviceName);

  573.         KdPrint(("BKFLT: Driver entry finished with status %x\n", ntStatus));

  574.         return(ntStatus);
  575. }


  576. VOID FltCleanup(VOID)
  577. {
  578.         RemoveAllHooks(NULL);
  579.         WaitForHooks();

  580.         KdPrint(("BKFLT: BK filter driver unloaded.\n"));
  581. }
复制代码
其实源代码也是偷来的,不过不是我乔大牛偷来的:
游客,如果您要查看本帖隐藏内容请回复

2

主题

38

回帖

1

精华

铂金会员

积分
1395
发表于 2013-10-29 17:57:06 | 显示全部楼层
老代码了!

857

主题

2632

回帖

2

精华

管理员

此生无悔入华夏,  长居日耳曼尼亚。  

积分
36130
发表于 2013-10-29 22:25:34 | 显示全部楼层
听说TA在烦如何过滤SCSI请求块(SRB),于是本大牛乔二再次发出找骂神功,翻出了一份处理SRB的代码:

“找骂神功”。。。

0

主题

11

回帖

0

精华

铜牌会员

积分
184
发表于 2013-10-30 21:03:50 | 显示全部楼层
乔帮主功力深厚,围观一下降龙十八掌。。

280

主题

203

回帖

0

精华

版主

积分
1808
 楼主| 发表于 2013-11-3 08:14:05 | 显示全部楼层
Tesla.Angela 发表于 2013-10-29 22:25
“找骂神功”。。。

是他妈的“找码”神功!代码的码!

280

主题

203

回帖

0

精华

版主

积分
1808
 楼主| 发表于 2013-11-3 08:14:25 | 显示全部楼层
bboyiori 发表于 2013-10-29 17:57
老代码了!

比你年轻!!!!

0

主题

3

回帖

0

精华

初来乍到

积分
13
发表于 2014-2-26 15:39:00 | 显示全部楼层
磁盘级过滤

1

主题

77

回帖

0

精华

金牌会员

积分
1137
发表于 2014-2-27 09:46:11 | 显示全部楼层
哪里偷的,哈哈

1

主题

77

回帖

0

精华

铂金会员

积分
1972
发表于 2014-11-4 00:10:33 | 显示全部楼层
学习了

0

主题

44

回帖

0

精华

铜牌会员

积分
130
发表于 2015-8-14 02:21:23 | 显示全部楼层
谢谢分享
头像被屏蔽

1

主题

30

回帖

0

精华

贵宾会员

积分
115
发表于 2016-5-25 23:32:28 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

1

主题

118

回帖

0

精华

金牌会员

积分
856
发表于 2016-8-12 09:13:24 | 显示全部楼层
随便看看.               

0

主题

67

回帖

0

精华

铂金会员

积分
2141
发表于 2016-8-12 23:40:55 | 显示全部楼层
其实源代码也是偷来的!!!当真?

9

主题

53

回帖

0

精华

贵宾会员

积分
16
发表于 2016-12-8 10:26:01 | 显示全部楼层
大神你好

1

主题

80

回帖

1

精华

铂金会员

积分
1818
发表于 2016-12-31 12:16:14 | 显示全部楼层
看看..谢谢.

0

主题

68

回帖

0

精华

论坛元老

积分
432738
发表于 2017-1-14 14:28:11 | 显示全部楼层
谢谢分享

0

主题

103

回帖

0

精华

初来乍到

积分
3
发表于 2018-1-9 18:57:20 | 显示全部楼层
谢谢分享!

0

主题

32

回帖

0

精华

铜牌会员

积分
112
发表于 2018-1-12 12:25:14 | 显示全部楼层
那是谁偷来的

0

主题

87

回帖

0

精华

金牌会员

积分
1046
发表于 2018-6-22 03:51:51 | 显示全部楼层
正要找相关驱动代码

0

主题

15

回帖

0

精华

初来乍到

积分
8
发表于 2021-12-7 05:51:15 | 显示全部楼层
围观一下降龙十八掌
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

快速回复 返回顶部 返回列表