hd spoofer from ring0

本文介绍了一种篡改硬盘信息的方法,通过钩住系统调用ZwDeviceIoControlFile来修改硬盘的型号、序列号等信息。此方法适用于Windows内核环境。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  /*
simple ring0 hd serial spoofer by Orkblutt aka s@t@nic@
credits:
Taurine for his sample on NtDeviceIoControlFile
jiurl for port hidder method
Bruce Allen & smartmontools devs
*/

#include <ntddk.h>

#define IOCTL_STORAGE_BASE 0x0000002d
#define IOCTL_DISK_BASE 0x00000007

#define IOCTL_STORAGE_QUERY_PROPERTY /
CTL_CODE(IOCTL_STORAGE_BASE0x0500,METHOD_BUFFEREDFILE_ANY_ACCESS
)

#define SMART_RCV_DRIVE_DATA /
CTL_CODE(IOCTL_DISK_BASE0x0022METHOD_BUFFEREDFILE_READ_ACCESS FILE_WRITE_ACCESS
)

#define ATA_IDENTIFY_DEVICE 0xec

#pragma pack(1)

typedef struct ServiceDescriptorEntry 
{
    
unsigned int *ServiceTableBase
;
    
unsigned int *ServiceCounterTableBase
//Used only in checked build
    
unsigned int NumberOfServices
;
    
unsigned char *ParamTableBase
;
ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t
;

struct ata_identify_device 
{
  
unsigned short words000_009[10
];
  
unsigned char  serial_no[20
];
  
unsigned short words020_022[3
];
  
unsigned char  fw_rev[8
];
  
unsigned char  model[40
];
  
unsigned short words047_079[33
];
  
unsigned short major_rev_num
;
  
unsigned short minor_rev_num
;
  
unsigned short command_set_1
;
  
unsigned short command_set_2
;
  
unsigned short command_set_extension
;
  
unsigned short cfs_enable_1
;
  
unsigned short word086
;
  
unsigned short csf_default
;
  
unsigned short words088_255[168
];
};

typedef enum _STORAGE_BUS_TYPE 
{
    
BusTypeUnknown 0x00
,
    
BusTypeScsi
,
    
BusTypeAtapi
,
    
BusTypeAta
,
    
BusType1394
,
    
BusTypeSsa
,
    
BusTypeFibre
,
    
BusTypeUsb
,
    
BusTypeRAID
,
    
BusTypeMaxReserved 
0x7F
STORAGE_BUS_TYPE, *PSTORAGE_BUS_TYPE
;

// retrieve the storage device descriptor data for a device. 
typedef struct _STORAGE_DEVICE_DESCRIPTOR 
{
  
ULONG  Version
;
  
ULONG  Size
;
  
UCHAR  DeviceType
;
  
UCHAR  DeviceTypeModifier
;
  
BOOLEAN  RemovableMedia
;
  
BOOLEAN  CommandQueueing
;
  
ULONG  VendorIdOffset
;
  
ULONG  ProductIdOffset
;
  
ULONG  ProductRevisionOffset
;
  
ULONG  SerialNumberOffset
;
  
STORAGE_BUS_TYPE  BusType
;
  
ULONG  RawPropertiesLength
;
  
UCHAR  RawDeviceProperties[1
];

STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR
;


#pragma pack()

#pragma pack(1)

typedef struct _GETVERSIONOUTPARAMS 
{
    
UCHAR  bVersion
;
    
UCHAR  bRevision
;
    
UCHAR  bReserved
;
    
UCHAR  bIDEDeviceMap
;
    
ULONG  fCapabilities
;
    
ULONG  dwReserved[4
];
GETVERSIONOUTPARAMS, *PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS
;


typedef struct _IDEREGS 
{
    
UCHAR  bFeaturesReg
;
    
UCHAR  bSectorCountReg
;
    
UCHAR  bSectorNumberReg
;
    
UCHAR  bCylLowReg
;
    
UCHAR  bCylHighReg
;
    
UCHAR  bDriveHeadReg
;
    
UCHAR  bCommandReg
;
    
UCHAR  bReserved
;
IDEREGS, *PIDEREGS, *LPIDEREGS
;

typedef struct _SENDCMDINPARAMS 
{
    
ULONG  cBufferSize
;
    
IDEREGS  irDriveRegs
;
    
UCHAR  bDriveNumber
;
    
UCHAR  bReserved[3
];
    
ULONG  dwReserved[4
];
    
UCHAR  bBuffer[1
];
SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS
;


typedef struct _DRIVERSTATUS 
{
    
UCHAR  bDriverError
;
    
UCHAR  bIDEError
;
    
UCHAR  bReserved[2
];
    
ULONG  dwReserved[2
];
DRIVERSTATUS, *PDRIVERSTATUS, *LPDRIVERSTATUS
;

typedef struct _SENDCMDOUTPARAMS 
{
    
ULONG  cBufferSize
;
    
DRIVERSTATUS  DriverStatus
;
    
UCHAR  bBuffer[1
];
SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS
;


#pragma pack()


__declspec(dllimport
ServiceDescriptorTableEntry_t
KeServiceDescriptorTable
;


// smartmontools code to deal with non big endian system

// Copies n bytes (or n-1 if n is odd) from in to out, but swaps adjacents
// bytes.
void swapbytes(char *out, const char *insize_t n
)
{
  
size_t i
;

  for (
0n+= 2
) {
    
out[i]   = in[i+1
];
    
out[i+1] = in[i
];
  }
}

// Copies in to out, but removes leading and trailing whitespace.
void trim(char *out, const char *in
)
{
  
int ifirstlast
;

  
// Find the first non-space character (maybe none).
  
first = -1
;
  for (
0in[i]; i
++)
    if (!
isspace((int)in[i
])) {
      
first i
;
      break;
    }

  if (
first == -1
) {
    
// There are no non-space characters.
    
out[0] = '/0'
;
    return;
  }

  
// Find the last non-space character.
  
for (strlen(in)-1>= first && isspace((int)in[i]); i
--)
    ;
  
last i
;

  
strncpy(outin+firstlast-first+1
);
  
out[last-first+1] = '/0'
;
}

// Convenience function for formatting strings from ata_identify_device
void formatdriveidstring(char *out, const char *inint n
)
{
  
char tmp[65
];
  
64 64 n
;
  
swapbytes(tmpinn
);
  
tmp[n] = '/0'
;
  
trim(outtmp
);
}



NTSYSAPI
NTSTATUS
NTAPI ZwDeviceIoControlFile
(
    
IN HANDLE FileHandle
,
    
IN HANDLE Event OPTIONAL
,
    
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL
,
    
IN PVOID ApcContext OPTIONAL
,
    
OUT PIO_STATUS_BLOCK IoStatusBlock
,
    
IN ULONG IoControlCode
,
    
IN PVOID InputBuffer OPTIONAL
,
    
IN ULONG InputBufferLength
,
    
OUT PVOID OutputBuffer OPTIONAL
,
    
IN ULONG OutputBufferLength
);


typedef NTSTATUS (*ZWDEVICEIOCONTROLFILE
)(
    
IN HANDLE FileHandle
,
    
IN HANDLE Event OPTIONAL
,
    
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL
,
    
IN PVOID ApcContext OPTIONAL
,
    
OUT PIO_STATUS_BLOCK IoStatusBlock
,
    
IN ULONG IoControlCode
,
    
IN PVOID InputBuffer OPTIONAL
,
    
IN ULONG InputBufferLength
,
    
OUT PVOID OutputBuffer OPTIONAL
,
    
IN ULONG OutputBufferLength
);


ZWDEVICEIOCONTROLFILE OldZwDeviceIoControlFile
;

NTSTATUS NewZwDeviceIoControlFile
(
    
IN HANDLE FileHandle
,
    
IN HANDLE Event OPTIONAL
,
    
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL
,
    
IN PVOID ApcContext OPTIONAL
,
    
OUT PIO_STATUS_BLOCK IoStatusBlock
,
    
IN ULONG IoControlCode
,
    
IN PVOID InputBuffer OPTIONAL
,
    
IN ULONG InputBufferLength
,
    
OUT PVOID OutputBuffer OPTIONAL
,
    
IN ULONG OutputBufferLength
)
{

    
PSTORAGE_DEVICE_DESCRIPTOR output
;
    
PSENDCMDINPARAMS  cmdinput
;
    
PSENDCMDOUTPARAMS cmdoutput
;
    
struct ata_identify_device *hdid
;

    
NTSTATUS rc
;
    
rc = ((ZWDEVICEIOCONTROLFILE)(OldZwDeviceIoControlFile
)) (
             
FileHandle
,
             
Event
,
             
ApcRoutine
,
             
ApcContext
,
             
IoStatusBlock
,
             
IoControlCode
,
             
InputBuffer
,
             
InputBufferLength
,
             
OutputBuffer
,
             
OutputBufferLength
         
);



    if(
IoControlCode != IOCTL_STORAGE_QUERY_PROPERTY && IoControlCode != SMART_RCV_DRIVE_DATA
)
        return(
rc
);

    if(
NT_SUCCESS(rc
))
    {
        switch( 
IoControlCode 
)
        {
        case 
IOCTL_STORAGE_QUERY_PROPERTY
:

            
output = (PSTORAGE_DEVICE_DESCRIPTOROutputBuffer
;
            if( 
output->SerialNumberOffset 

            {
                
charserialnum = (char*)output output->SerialNumberOffset
;
                
formatdriveidstring(serialnum"FAKE SERIAL"40
);
            }

            if( 
output->ProductIdOffset 

            {
                
charproductid = (char*)output output->ProductIdOffset
;
                
strncpyproductid"STUPID PB"strlen(productid
) );
            }

            if( 
output->VendorIdOffset 

            {
                
charvendorid = (char*)output output->VendorIdOffset
;
                
strncpyvendorid"asdfghjkl"strlen(vendorid
) );
            }

            break;

        case 
SMART_RCV_DRIVE_DATA
:

            
cmdinput  = (PSENDCMDINPARAMS)  InputBuffer
;
            
cmdoutput = (PSENDCMDOUTPARAMSOutputBuffer
;

            if (
cmdinput->irDriveRegs.bCommandReg == ATA_IDENTIFY_DEVICE

            {
                
hdid = (struct ata_identify_device*) (cmdoutput->bBuffer
);
                
formatdriveidstring(hdid->model"spoofed model!"40 
);
                
formatdriveidstringhdid->serial_no"serial goes here"20 
);
            }
            break;
        }
    }

    return(
rc
);

}


NTSTATUS DriverDispatch
(
    
IN PDEVICE_OBJECT DeviceObject
,
    
IN PIRP Irp
)
{

    
Irp->IoStatus.Status STATUS_SUCCESS
;

    
IoCompleteRequest (Irp,IO_NO_INCREMENT
);

    return 
Irp->IoStatus.Status
;
}



void DriverUnload(IN PDRIVER_OBJECT DriverObject
)
{

    
_asm
    
{
        
CLI 
//dissable interrupt
        
MOV EAXCR0 
//move CR0 register into EAX
        
AND EAXNOT 10000H 
//disable WP bit
        
MOV CR0EAX 
//write register back
    
}

    (
KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)ZwDeviceIoControlFile+1
)])
    = (
ULONG)OldZwDeviceIoControlFile
;

    
_asm

    
{
        
MOV EAXCR0 
//move CR0 register into EAX
        
OR EAX10000H 
//enable WP bit
        
MOV CR0EAX 
//write register back
        
STI 
//enable interrupt
    
}
}


NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObjectIN PUNICODE_STRING RegistryPath
)
{

    
DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverObject->MajorFunction[IRP_MJ_CLOSE] = DriverDispatch
;

    
DriverObject->DriverUnload DriverUnload
;

    
// save old system call locations

    
OldZwDeviceIoControlFile = (ZWDEVICEIOCONTROLFILE)(KeServiceDescriptorTable.ServiceTableBase
[
                                   *(
PULONG)((PUCHAR)ZwDeviceIoControlFile+1
)]);

    
_asm
    
{
        
CLI 
//dissable interrupt
        
MOV EAXCR0 
//move CR0 register into EAX
        
AND EAXNOT 10000H 
//disable WP bit
        
MOV CR0EAX 
//write register back
    
}

    (
KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)ZwDeviceIoControlFile+1
)])
    = (
ULONG)NewZwDeviceIoControlFile
;

    
_asm
    
{
        
MOV EAXCR0 
//move CR0 register into EAX
        
OR EAX10000H 
//enable WP bit
        
MOV CR0EAX 
//write register back
        
STI 
//enable interrupt
    
}

    return 
STATUS_SUCCESS
;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值