【转】RING3直接读写磁盘扇区
FROM: http://www.kernelmode.info/forum/viewtopic.php?f=15&t=3677Author: 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?
翻译过来就是:现在的硬件+最新的Windows在EFI模式下,所有的BIOS bootkit将不再有效你造吗?几年后,你只能在废料厂找到有BIOS的电脑。(他说的BIOS指的是Legacy方式引导的电脑。) 我觉得……现在“坚持”用XP的人还是很多,恐怕完全淘汰Legacy Boot要很久以后喽 ring3说明是用户级别的程序?这样也可读写磁盘扇区?
话说谢谢楼主的搬运,不搬运压根不知道有这回事,知道了或许可以自己研究一下~ 谢谢楼主分享,意思就是UEFI的不起作用了吗?
页:
[1]