技术宅的结界

 找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 1658|回复: 3
收起左侧

【转】RING3直接读写磁盘扇区

[复制链接]

1012

主题

2251

帖子

5万

积分

用户组: 管理员

一只技术宅

UID
1
精华
201
威望
271 点
宅币
17112 个
贡献
34134 次
宅之契约
0 份
在线时间
1620 小时
注册时间
2014-1-26
发表于 2015-1-15 19:46:38 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有帐号?立即注册→加入我们

x
FROM: http://www.kernelmode.info/forum/viewtopic.php?f=15&t=3677
Author: EP_X0FF
[C] 纯文本查看 复制代码
#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[8];
    UCHAR CurrentTaskFile[8];
} 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[8] = TEXT("\\\\.\\X:\\");
   WORD    DevId[256] = {0};
   USHORT  AtaFlags;
   UCHAR   AtaCommand;

   drive[4] = FileName[0];
   if ( !GetDiskFreeSpace(&drive[4], &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[6] = 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[0].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[6] = 0xEC;
      DeviceIoControl(f, IOCTL_ATA_PASS_THROUGH_DIRECT, &dio, sizeof(dio), &dioOut, sizeof(dioOut), &iobytes, NULL);

      if ((DevId[83] & 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[0].StartingOffset.QuadPart + (ptrs->Extents[c].Lcn.QuadPart*SectorsPerCluster);
         k = ptrs->Extents[c].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[2] = (lofs.QuadPart >> 24) & 0xff;
            dio.PreviousTaskFile[3] = (lofs.QuadPart >> 32) & 0xff;
            dio.PreviousTaskFile[4] = (lofs.QuadPart >> 40) & 0xff;

            dio.CurrentTaskFile[1] = (UCHAR)SectorsPerCluster;
            dio.CurrentTaskFile[2] = lofs.QuadPart & 0xff;
            dio.CurrentTaskFile[3] = (lofs.QuadPart >> 8) & 0xff;
            dio.CurrentTaskFile[4] = (lofs.QuadPart >> 16) & 0xff;
            
            if (AtaCommand == 0xC8) {
               dio.CurrentTaskFile[5] = 0x40 | ((lofs.QuadPart >> 24) & 0x0f);
            } else {
               dio.CurrentTaskFile[5] = 0x40;
            }
            
            dio.CurrentTaskFile[5] = 0x40;

            dio.CurrentTaskFile[6] = AtaCommand;
            DeviceIoControl(f, IOCTL_ATA_PASS_THROUGH_DIRECT, &dio, sizeof(dio), &dioOut, sizeof(dioOut), &iobytes, NULL);
            p+=(BytesPerSector*SectorsPerCluster);
         }
         lofs.QuadPart = ptrs->Extents[c].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?

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

1012

主题

2251

帖子

5万

积分

用户组: 管理员

一只技术宅

UID
1
精华
201
威望
271 点
宅币
17112 个
贡献
34134 次
宅之契约
0 份
在线时间
1620 小时
注册时间
2014-1-26
 楼主| 发表于 2015-1-21 03:51:31 来自手机 | 显示全部楼层
我觉得……现在“坚持”用XP的人还是很多,恐怕完全淘汰Legacy Boot要很久以后喽

0

主题

25

帖子

52

积分

用户组: 小·技术宅

UID
1741
精华
0
威望
2 点
宅币
23 个
贡献
0 次
宅之契约
0 份
在线时间
4 小时
注册时间
2016-6-3
发表于 2016-6-3 17:15:15 | 显示全部楼层
ring3说明是用户级别的程序?这样也可读写磁盘扇区?

话说谢谢楼主的搬运,不搬运压根不知道有这回事,知道了或许可以自己研究一下~

0

主题

18

帖子

48

积分

用户组: 初·技术宅

UID
2268
精华
0
威望
1 点
宅币
28 个
贡献
0 次
宅之契约
0 份
在线时间
2 小时
注册时间
2017-2-21
发表于 2017-2-22 10:59:47 | 显示全部楼层
谢谢楼主分享,意思就是UEFI的不起作用了吗?

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|技术宅的结界 ( 滇ICP备16008837号|网站地图

GMT+8, 2019-1-19 06:22 , Processed in 0.093918 second(s), 36 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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