Tesla.Angela 发表于 2015-1-15 10:30:06

[转]RING3直接读写磁盘扇区

FROM: http://www.kernelmode.info/forum/viewtopic.php?f=15&t=3677
Author: EP_X0FF
#include <windows.h>
#include "prtl.h"

#define IOCTL_SCSI_BASE               FILE_DEVICE_CONTROLLER
#define FILE_DEVICE_CONTROLLER          0x00000004
#define IOCTL_ATA_PASS_THROUGH_DIRECT   CTL_CODE(IOCTL_SCSI_BASE, 0x040c, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)

#define ATA_FLAGS_DRDY_REQUIRED         (1 << 0)
#define ATA_FLAGS_DATA_IN               (1 << 1)
#define ATA_FLAGS_DATA_OUT            (1 << 2)
#define ATA_FLAGS_48BIT_COMMAND         (1 << 3)
#define ATA_FLAGS_USE_DMA               (1 << 4)
#define ATA_FLAGS_NO_MULTIPLE         (1 << 5)

typedef struct _ATA_PASS_THROUGH_DIRECT {
    USHORT Length;
    USHORT AtaFlags;
    UCHAR PathId;
    UCHAR TargetId;
    UCHAR Lun;
    UCHAR ReservedAsUchar;
    ULONG DataTransferLength;
    ULONG TimeOutValue;
    ULONG ReservedAsUlong;
    PVOID DataBuffer;
    UCHAR PreviousTaskFile;
    UCHAR CurrentTaskFile;
} ATA_PASS_THROUGH_DIRECT, *PATA_PASS_THROUGH_DIRECT;

#define INBUFFER_SIZE 1024*1024

int IsFileInfested(LPCTSTR FileName, LPVOID RawData, DWORD BufferSize)
{
   ATA_PASS_THROUGH_DIRECT      dio, dioOut;
   STARTING_VCN_INPUT_BUFFER   base;
   RETRIEVAL_POINTERS_BUFFER   *ptrs;
   VOLUME_DISK_EXTENTS         ext;
   LARGE_INTEGER            ofs, lofs;
   __int64                  i, k;

   HANDLE   f = INVALID_HANDLE_VALUE;
   DWORD   iobytes, SectorsPerCluster = 0, BytesPerSector = 0, c, p = 0;
   TCHAR   drive = TEXT("\\\\.\\X:\\");
   WORD    DevId = {0};
   USHORTAtaFlags;
   UCHAR   AtaCommand;

   drive = FileName;
   if ( !GetDiskFreeSpace(&drive, &SectorsPerCluster, &BytesPerSector, NULL, NULL) )
      return -1;

   ptrs = (RETRIEVAL_POINTERS_BUFFER *)VirtualAlloc(NULL, INBUFFER_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
   while ( ptrs != NULL ) {
      f = CreateFile(FileName, GENERIC_READ | SYNCHRONIZE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL);
      if ( f == INVALID_HANDLE_VALUE )
         break;
      base.StartingVcn.QuadPart = 0;
      if ( !DeviceIoControl(f, FSCTL_GET_RETRIEVAL_POINTERS, &base, sizeof(base), ptrs, INBUFFER_SIZE, &iobytes, NULL) )
         break;
      CloseHandle(f);

      drive = 0;
      f = CreateFile(drive, GENERIC_READ | SYNCHRONIZE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL);
      if ( f == INVALID_HANDLE_VALUE )
         break;
      if ( !DeviceIoControl(f, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0, &ext, sizeof(ext), &iobytes, NULL) )
         break;
      CloseHandle(f);

      f = CreateFile(TEXT("\\\\.\\PHYSICALDRIVE0"), GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
      if ( f == INVALID_HANDLE_VALUE )
         break;

      ext.Extents.StartingOffset.QuadPart /= BytesPerSector;
      lofs.QuadPart = 0;

      memset(&DevId, 0, sizeof(DevId));
      memset(&dio, 0, sizeof(dio));
      dio.Length = sizeof(dio);
      dio.AtaFlags = ATA_FLAGS_DRDY_REQUIRED | ATA_FLAGS_DATA_IN;
      dio.DataTransferLength = 512;
      dio.TimeOutValue = 1;
      dio.DataBuffer = &DevId;
      dio.CurrentTaskFile = 0xEC;
      DeviceIoControl(f, IOCTL_ATA_PASS_THROUGH_DIRECT, &dio, sizeof(dio), &dioOut, sizeof(dioOut), &iobytes, NULL);

      if ((DevId & 0x400) != 0) {
         AtaCommand = 0x25;
         AtaFlags = ATA_FLAGS_DRDY_REQUIRED | ATA_FLAGS_USE_DMA | ATA_FLAGS_DATA_IN | ATA_FLAGS_48BIT_COMMAND;
      } else {
         AtaCommand = 0xC8;
         AtaFlags = ATA_FLAGS_DRDY_REQUIRED | ATA_FLAGS_USE_DMA | ATA_FLAGS_DATA_IN;
      }


      for (c=0; c<ptrs->ExtentCount; c+=1) {
         ofs.QuadPart = ext.Extents.StartingOffset.QuadPart + (ptrs->Extents.Lcn.QuadPart*SectorsPerCluster);
         k = ptrs->Extents.NextVcn.QuadPart - lofs.QuadPart;

         if ( p+(BytesPerSector*SectorsPerCluster) > BufferSize )
            break;

         for (i=0; i<k; i+=1) {
            if ( p+(BytesPerSector*SectorsPerCluster) > BufferSize )
               break;
            lofs.QuadPart = ofs.QuadPart + i*SectorsPerCluster;

            memset(&dio, 0, sizeof(dio));
            dio.Length = sizeof(dio);
            dio.AtaFlags = AtaFlags;
            dio.DataTransferLength = BytesPerSector*SectorsPerCluster;
            dio.TimeOutValue = 1;
            dio.DataBuffer = ((LPBYTE)RawData)+p;

            dio.PreviousTaskFile = (lofs.QuadPart >> 24) & 0xff;
            dio.PreviousTaskFile = (lofs.QuadPart >> 32) & 0xff;
            dio.PreviousTaskFile = (lofs.QuadPart >> 40) & 0xff;

            dio.CurrentTaskFile = (UCHAR)SectorsPerCluster;
            dio.CurrentTaskFile = lofs.QuadPart & 0xff;
            dio.CurrentTaskFile = (lofs.QuadPart >> 8) & 0xff;
            dio.CurrentTaskFile = (lofs.QuadPart >> 16) & 0xff;
            
            if (AtaCommand == 0xC8) {
               dio.CurrentTaskFile = 0x40 | ((lofs.QuadPart >> 24) & 0x0f);
            } else {
               dio.CurrentTaskFile = 0x40;
            }
            
            dio.CurrentTaskFile = 0x40;

            dio.CurrentTaskFile = AtaCommand;
            DeviceIoControl(f, IOCTL_ATA_PASS_THROUGH_DIRECT, &dio, sizeof(dio), &dioOut, sizeof(dioOut), &iobytes, NULL);
            p+=(BytesPerSector*SectorsPerCluster);
         }
         lofs.QuadPart = ptrs->Extents.NextVcn.QuadPart;
      }
      CloseHandle(f);

      VirtualFree(ptrs, 0, MEM_RELEASE);
      return 0;
   }

   if ( f != INVALID_HANDLE_VALUE )
      CloseHandle(f);
   if ( ptrs != NULL )
      VirtualFree(ptrs, 0, MEM_RELEASE);
   return -1;
}

#define sFileName TEXT("C:\\WINDOWS\\system32\\drivers\\fltmgr.sys")

void main()
{
   LPVOID buffer;
   HANDLE   f;
   DWORD   iobytes, fsize = 0;

   

   f = CreateFile(sFileName, GENERIC_READ | SYNCHRONIZE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
   if ( f != INVALID_HANDLE_VALUE ) {
      fsize = GetFileSize(f, NULL);
      CloseHandle(f);
   }

   buffer = VirtualAlloc(NULL, fsize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
   memset(buffer, 0xcc, fsize);

   IsFileInfested(sFileName, buffer, fsize);
   f = CreateFile(TEXT("Z:\\TEMP\\4321.dmp"), GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);
   if (f != INVALID_HANDLE_VALUE) {
      WriteFile(f, buffer, fsize, &iobytes, NULL);
      CloseHandle(f);
   }
   Sleep(0);
}
但EP_X0FF表示:Do you understrand with current hardware + newest Windows installed in EFI mode all legacy BIOS bootkits are no longer work? And after few years computers with BIOS you can only see in the scrapyard?

andylau004 发表于 2015-1-15 12:10:04

顶。

0xAA55 发表于 2015-1-15 19:49:05

翻译过来就是:现在的硬件+最新的Windows在EFI模式下,所有的BIOS bootkit将不再有效你造吗?几年后,你只能在废料厂找到有BIOS的电脑。(他说的BIOS指的是Legacy方式引导的电脑。)

但事实上还是有无数国人在“坚持”使用XP。
页: [1]
查看完整版本: [转]RING3直接读写磁盘扇区