关闭

hd spoofer from ring0

标签: descriptoroutputaccessqueryextensionfile
861人阅读 评论(0) 收藏 举报
分类:
 /*
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
;

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:3651653次
    • 积分:59840
    • 等级:
    • 排名:第40名
    • 原创:1549篇
    • 转载:1252篇
    • 译文:0篇
    • 评论:459条
    最新评论