Access via ASPI

Accessing the Drive via SCSI Miniport

The SCSI miniport driver allows the system to abstract from the details of the physical interfaces for specific equipment. In the interest of brevity, let us simply call it the minidriver, although this is actually only partially true. After all, along with the minidrivers for SCSI ports, there are also drivers for video and network miniports. However, since neither of these relates to the context of our discussion in any way, there won t be any misunderstanding.

Hierarchically, the miniport driver resides between the physical (virtual) devices connected to specific interface buses of the computer (IDE/PCI/SCSI) and the SCSI port driver. The miniport driver is a system-independent driver, which, at the same time, depends on specific features of the HBA (Host Bus Adapter), i.e., the physical/ virtual equipment that it serves. The miniport driver exports a range of functions of the ScsiPortXXX family, which are intended for use by higher-level drivers. Usually, it is implemented as a Dynamic Link Library (DLL), which, quite naturally, executes in ring 0 of the kernel level.

It is this driver that translates SCSI requests into commands for the device connected to it, creates virtual SCSI ports with names such as \Device\ScsiPortx , and ensures support for storage media having interfaces different from SCSI. For example, drivers such as ATAPI.SYS, serving CD-ROM drives with the ATAPI interface, and DISK.SYS, serving hard disks, are implemented in the form of miniport drivers.

Control of the miniport is carried out using special IOCTL code passed to the DeviceIoControl function and defined as IOCTL_SCSI_MINIPORT in the NTDDSCSI.H file. If you don t have a copy of NT DDK, here is its direct value: 0x40008 . Naturally, before calling on the DeviceIoControl function, you must first open an appropriate SCSI port using the CreateFile function. The code that carries out this task might appear as shown in the listing below. Pay special attention to the fact that the port name must appear as SCSIx: , rather than ScsiPortx ; the name must be terminated with a colon . Otherwise, the attempt will fail.

Listing 4.17: Opening the SCSI port for controlling the miniport driver
image from book
 h = CreateFile ("\\. \SCSI1: ", GENERIC_READ  GENERIC_WRITE, FILE_SHARE_READ   FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); 
image from book
 

Here, you open the first (numbered from zero) SCSI port that, as you already know, corresponds to the first IDE channel, or, to put it in other words, to the secondary IDE controller (on the author s computer, the CD-ROM drive is connected to that particular controller). To detect the drive location on an unknown computer, you can use the IOCTL_SCSI_GET_INQUIRY_DATA IOCTL code, which makes the miniport driver list all the equipment at its disposal, after which it only remains to correctly determine its type (for more details, see NTDDK\SRC\STORAGE\CLASS\SPTI).

However, miniport control is carried out in a different way from that used to control the SCSI port! At this level, there are no standard commands, and you have to take into account the specific features of the implementation of specific hardware. Instead of SRB requests, the minidriver accepts the SRB_IO_CONTROL structure defined as follows :

Listing 4.18: The purpose of the SRB_IO_CONTROL structure fields
image from book
 typedef struct _SRB_IO_CONTROL  {  ULONG HeaderLength;   // sizeof (SRB_IO_CONTROL)  UCHAR Signature [8];  // Minidriver signature  ULONG Timeout;        // Max. waiting time for the request                        // to be completed (in seconds)  ULONG ControlCode;    // Command code  ULONG ReturnCode;     // Here we will get the return code.  ULONG Length;         // The length of entire transmitted buffer  } SRB_IO_CONTROL, *PSRB_IO_CONTROL; 
image from book
 

Well, you understand the meaning of the HeaderLength field, but what is the signature? The point is that the controlling codes of miniport drivers aren t standardized. On the contrary, they are defined by the drivers developers. Therefore, the control codes of one driver are unlikely to fit those of another. In order to avoid conflicts, each miniport driver contains a unique signature, which it compares carefully to the one passed on by an application in the signature field of the SRB_IO_CONTROL structure. If these signatures do not match, the driver responds with the following message: SRB_STATUS_INVALID_REQUEST . Unfortunately, the interfaces of the standard minidrivers ”ATAPI.SYS and DISK.SYS ”are not documented. As a result, it s a difficulty for those who are unable to disassemble. With regard to the disassembler, it immediately shows that the signatures of both drivers appear as SCSIDISK. The signature of the Alcohol 120% minidriver appears as Alcoholx (the latter doesn t present any special interest to us because it doesn t correspond to standards).

It is somewhat more difficult to understand program codes. Although the specialists constantly reading MSDN and therefore, having a sound knowledge in it, might recall that this specification describes the API for an application to issue SMART commands to an IDE drive under Microsoft Windows 95 and Windows NT. Under Windows 95, the API is implemented in a Vendor Specific Driver (VSD), Smartvsd.vxd. SMART functionality is implemented as a ˜pass-through mechanism, whereby the application sets up the IDE registers in a structure and passes them to the driver through the DeviceIoControl API.

Well, one of the drivers facilitates the manipulation of the registers of the IDE controller as needed, which means that it provides low-level access to the disk ” very well. The interface with the SMART driver is well documented (see MSDN Specifications a Platforms SMART IOCTL API Specification ). But the silence in relation to Windows NT appears to be somewhat irritating . Clearly, there are no VxDs in Windows NT. However, it is clearly stated in this document that SMART API is implemented there. If you use a few gray cells and a little bit of intuition work, you might be able to guess that SMART support in NT is through standard means! The only question that remains is as follows: How and by what means? Neither SDK nor DDK contain any information on this topic. However, careful study of the header files included with NT DDK can help. Look at what you can find in the image from book  scsi.h file.

Listing 4.19: The SMART control commands in Windows NT, which can be passed to the miniport driver via the ControlCode field of the
image from book
  SRB_IO_CONTROL structure  //  // SMART support in atapi  //  #define IOCTL_SCSI_MINIPORT_SMART_VERSION           ((FILE_DEVICE_SCSI<<16) + 0x0500)  #define IOCTL_SCSI_MINIPORT_IDENTIFY                ((FILE_DEVICE_SCSI<<16) + 0x0501)  #define IOCTL_SCSI_MINIPORT_READ_SMART_ATTRIBS      ((FILE_DEVICE_SCSI<<16) + 0x0502)  #define IOCTL_SCSI_MINIPORT_READ_SMART_THRESHOLDS   ((FILE_DEVICE_SCSI<<16) + 0x0503)  #define IOCTL SCSI MINIPORT ENABLE SMART            ((FILE DEVICE SCSI<<16) + 0x0504)  #define IOCTL_SCSI_MINIPORT_DISABLE_SMART           ((FILE_DEVICE_SCSI<<16) + 0x0505)  #define IOCTL_SCSI_MINIPORT_RETURN_STATUS           ((FILE_DEVICE_SCSI<<16) + 0x0506)  #define IOCTL_SCSI_MINIPORT_ENABLE_DISABLE_AUTOSAVE ((FILE_DEVICE_SCSI<<16) + 0x0507)  #define IOCTL_SCSI_MINIPORT_SAVE_ATTRIBUTE_VALUES   ((FILE_DEVICE_SCSI<<16) + 0x0508)  #define IOCTL_SCSI_MINIPORT_EXECUTE_OFFLINE_DIAGS   ((FILE_DEVICE_SCSI<<16) + 0x0509)  #define IOCTL_SCSI_MINIPORT_ENABLE_DISABLE_AUTO_OFFLINE (FILE_DEVICE_SCSI<<16)+0x050a 
image from book
 

You might suspect that, in Windows, NT SMART isn t implemented in the miniport driver, and disassembling of ATAPI.SYS actually confirms this. So why include IOCTL commands in the header file without documenting them? would be a fair question for Microsoft s technical writers. And, according to the license agreement, disassembling any OS components is prohibited . Instead of complaining, let s read the SMART IOCTL API Specification once again. In this document, you discover that in order to control the miniport driver under Windows NT, it is necessary to pass the code of one of the above-listed commands to the ControlCode field of the SRB_IO_CONTROL structure. For example, IOCTL_SCSI_MINIPORT_IDENTIFY .

Immediately following the end of the SRB_IO_CONTROL structure, there must be SENDCMDINPARAMS , defined as shown in Listing 4.20.

Listing 4.20: The SENDCMDINPARAMS structure providing direct access to IDE registers
image from book
 typedef struct _SENDCMDINPARAMS  {  DWORD    cBufferSize;           // Buffer size in bytes or zero  IDEREGS  irDriveRegs;           // The structure containing                                  // the values of IDE registers  BYTE     bDriveNumber;          // Physical disk number,                                  // starting from zero  BYTE     bReserved[3];          // Reserved  DWORD    dwReserved[4];         // Reserved  BYTE     bBuffer[1];            // The starting point of the input buffer  } SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS; 
image from book
 

This means that the input buffer of the DeviceIoControl function must look as follows:

image from book
Fig. 4.6: Structure of the input buffer of the DeviceIoControl function for controlling the miniport driver under Windows 9x/NT

The first structural element, cBufferSize , containing the bBufferSize , is obvious and, therefore, of little interest. As for the IDREGS structure, it represents a virtual goldmine of information. Just look for yourself:

Listing 4.21: The IDEREGS structure providing low-level access to IDE registers
image from book
 typedef struct _IDEREGS  {  BYTE bFeaturesReg;       // IDE Features register  BYTE bSectorCountReg;    // IDE SectorCount register  BYTE bSectorNumberReg;   // IDE SectorNumber register  BYTE bCylLowReg;         // IDE CylLowReg register  BYTE bCylHighReg;        // IDE CylHighReg register  BYTE bDriveHeadReg;      // IDE DriveHead register  BYTE bCommandReg;        // Command register  BYTE bReserved;          // Reserved  } IDEREGS, *PIDEREGS, *LPIDEREGS; 
image from book
 

Anyone who has ever read the ATA/ATAPI specification and programmed devices with the IDE interface should immediately recognize the well-known registers ” Command, Drive/Head, Cylinder High, Cylinder Low, Sector Number, Sector Count , and Features . That they are listed in reverse order in the IDEREGS structure is only a minor implementation detail. The main fact is that using this structure, it is possible to do whatever you like with the drive, implementing all of the tricks of which it is capable. It is hard to believe that the security subsystem contains such a security loophole. This is aggravated further by the fact that administrative privileges are not required for controlling the miniport. Jumping with joy, let s fill in the remaining fields of the SENDCMDINPARAMS structure, namely: bDriveNumber ”the physical number of the drive, numbering from zero, and the buffer for passing the data.

Important  

This is a buffer itself, rather than a pointer to a buffer.

However, for the moment, you are not going to write any data to the disc, are we? Well, then let s leave this field blank.

Alas! An attempt to feed the drive with a command other than those from the SMART family, will fail. After all, the miniport driver isn t as stupid as you supposed. It checks the contents of the IDEREGS structure before passing it to the IDE drive. The only exception has been made for the drive identification command ” 0xEC , about which Microsoft has openly informed us: There are three IDE commands supported in this driver, ID (0xEC), ATAPI ID (0xA1) , and SMART (0xB0) . The ˜subcommands of the SMART commands (featuring register values) are limited to the currently defined values ( 0xDO through 0xD6, 0xD8 through 0xEF ). SMART subcommand 0XD7 , write threshold value, is not allowed. Any other command or SMART subcommand will result in an error being returned from the driver. Any SMART command that is not currently implemented on the target drive will result in an ABORT error from the IDE interface .

At first glance, it seems that you have failed altogether. However, this is not so the case! After all, this check can be disabled. Let us disassemble the ATAPI.SYS driver and see what can be done. The following fragment is responsible for checking IDE commands passed to the drive in order to determine whether they belong to the allowed list.

Listing 4.22: A fragment of the disassembled listing of the ATAPI.SYS driver
image from book
 .text:00013714 aScsidisk   db  'SCSIDISK'  ,0   ; DATA XREF: SCSI_MINIPORT + CC   o  ; here is our signature        ^^^^^^^^  ;  .text:000137DF  .text:000137DF    loc_137DF:                  ; CODE XREF: SCSI_MINIPORT+B5   j  .text:000137DF    mov    [edi], ebx  .text:000137E1    mov    eax, [ebx+18h]  .text:000137E4    push   8                    ; The length of the string                                                ; to be compared  .text:000137E6    add    eax, 4  .text:000137E9    push   offset aScsidisk     ; Pattern signature  .text:000137EE    push   eax                  ; The signature passed                                                ; by an application  .text:000137EF    call   ds:RtlCompareMemory  ; Do signatures match?  .text:000137F5    cmp    eax, 8   .text:000137F8    jnz    oc_13898             ; No match, exiting  .text:000137F8  .text:000137FE    mov    esi, [ebx+18h]  .text:00013801    mov    eax, [esi+10h]       ; Getting Control code  .text:00013804    cmp    eax, 1B0500h         ;  IOCTL_SCSI_MINIPORT_SM  .text:00013809    jz     loc_1389F            ;  Processing   SMART_VERSION  .text:0001380F    mov    ecx, 1B0501h         ;  IOCTL_SCSI_MINIPORT_IDENTIFY  .text:00013814    cmp    eax, ecx             ;  .text:00013816    jz     short loc_1382D      ;    Processing   IDENTIFY  .text:00013818    jbe    short loc_13898      ; IF ControlCode < IDENTIFY THEN go to exit  .text:0001381A    cmp    eax, 1B050Ah         ; IOCTL_SCS I_MINI PORT_ENABLE_DISABLE   .text:0001381F    ja     short loc 13898      ; IF ControlCode > ENABLE_DISAB   go to exit  .text:00013821    push   ebx                  ;  .text:00013822    push   edi                  ;  .text:00013823    call   sub_12412            ; processing other SMART commands  .text:00013828    jmp    loc_1393E  .text:0001382D    ; ----------------------------------------------------------- .text:00012412    sub_12412 proc near         ; CODE XREF: SCSI_MINIPORT+106   p   .text:00012433    cmp   [ebp+var 1E] , 0B0h   ; SMART-command  .text:00012437    jnz   loc_12633             ; If this isnt SMART, go to exit  .text:00012437                                ; Checks start from here  .text:0001243D    movzx  eax, [ebp+var_1C]  .text:00012441    mov    eax, [ebx+eax*4+0B0h]; Loading Drive/Head register into EAX  .text:00012448    test   al, 1                ; Comparing the least significant bit                                                ; of AL to one  .text:0001244A    jz     loc_1262F            ; If the least significant bit                                                ;is equal to zero, then exit  .text:00012450    test   al, 2                ; Comparing the next bit of AL to one  .text:00012452    jnz    loc_1262F            ; If it isnt equal to zero, exit  .text:00012458    mov    al, [ebp+var_24]     ; Loading the Feature register to AL  .text:0001245B    cmp    al, 0D0h             ; Is this SMART READ DATA?  .text:0001245D    mov    [ebx+0CCh], al  .text:00012463    jz     loc_12523            ; If yes, start processing  .text:00012469    cmp    al, 0D1h             ; Is it obsolete?  .text:0001246B    jz     loc_12523            ; If yes, start its processesing  .text:00012471    cmp    al, 0D8h             ; Is this SMART ENABLE OPERATIONS?  .text:00012473    jz     short loc_12491      ; If yes, start its processing  .text:00012475    cmp    al, 0D9h             ; Is this SMART DISABLE OPERATIONS?  .text:00012477    jz     short loc_12491      ; If yes, start its processing  .text:00012479    cmp    al, 0DA              ; Is this SMART RETURN STATUS?  .text:0001247B    jz     short loc_12491      ; If yes, start its processing  .text:0001247D    cmp    al, 0D2h             ; Is this SMART ENBL/DSBL ATTRIBUTE AUTOSAVE?  .text:0001247D    cmp    al, 0D2h             ; It this really the case?!  .text:0001247F    jz     short loc_12491      ; If yes, start its processing  .text:00012481    cmp    al, 0D4h             ; Is this SMART EXECUTE OFF-LINE IMMEDIATE?  .text:00012483    jz     short loc_12491      ; If yes, start its processing  .text:00012485    cmp    al, 0D3h             ; Is this SMART SAVE ATTRIBUTE VALUES?  .text:00012487    jz     short loc_12491      ; If yes, start its processing  .text:00012489    cmp    al, 0DBh             ; Is this SMART ENABLE OPERATIONS?  .text:0001248B    jnz    loc_12633            ; If no, then exit  .text:00012491  .text:00012491    loc_12491:                  ; CODE XREF: sub_12412+61   j  .text:00012491           ; Command processing starts from here  .text:00012491                                ;  .text:00012491    push   1  .text:00012493    pop    eax  .text:00012494    cmp    ds:0FFDF02C0h, eax  .text:0001249A    jnz    short loc_124A5  .text:0001249C    cmp    dword ptr [ebx+4], 640h  .text:000124A3    jz     short loc_124A7  .text:000124A5  .text:000124A5    loc_124A5:                  ; CODE XREF: sub_12412+88   j  .text:000124A5    xor    eax, eax  .text:000124A7  .text:000124A7    loc 124A7:                  ; CODE XREF: sub 12412+91   j  .text:000124A7                                ; Writing to the port starts from here!  .text:000124A7                                ;  .text:000124A7    mov    esi, ds  :WRITE_PORT_UCHAR  .text:000124AD    test   al, al  .text:000124AF    jz     short loc 124C0  .text:000124B1    mov    al, [ebp+var_1C]  .text:000124B4    shr    al, 1  .text:000124B6    and    al, 1  .text:000124B8    push   eax  .text:000124B9    push   432h  .text:000124BE    call   esi                  ;  WRITE_PORT_UCHAR  
image from book
 

Thus, in order to allow the driver to send any commands to the IDE drive, you must change the conditional jump located by the address 0x12437 (in the listing, it is highlighted and surrounded by a rectangle) for the unconditional jump passing the control to the write command by the address 0x12491 . After modifying the driver, don t forget to correct its checksum, which can be carried out, for example, using the EDITBIN.EXE utility supplied with Microsoft Visual Studio. Otherwise, Windows NT will refuse to load the hacked driver.

Naturally, I recommend that you carry out such an operation only with your own driver, because others are unlikely to be pleased by the newly-created security hole. Moreover, distribution of the modified version of ATAPI.SYS violates the licensing agreement and Microsoft s copyright. Draw your own conclusions. Nevertheless, your application can patch ATAPI.SYS on your own computer and on the computers of your users (naturally, you must inform them of the things that you are going to do, ask their permission or, at least, mention this aspect in companion documentation).

This method of interacting with the drive mustn t be neglected altogether, since it significantly complicates the cracking of protection mechanisms based on it. After all, not every hacker is well acquainted with specific features related to controlling the miniport. Therefore, with good probability, the vast majority will make fools of themselves .

The example program provided below demonstrates the passing of ATA commands to the IDE drive via the miniport driver.

Listing 4.23: [/etc/SCSI.mini-port.c] A sample program demonstrating the technique of interacting with the SCSI miniport
image from book
 int ATAPI_MINIPORT_DEMO(void)  {           int a;           HANDLE h;           Char*buf ;           Int LU=0;           DWORD returned;           Int controller;           CharScsiPort [16];           Charbuffer [sizeof (SRB_IO_CONTROL) + SENDIDLENGTH] ;           SRB_IO_CONTROL *p = (SRB_IO_CONTROL *) buffer;           SENDCMDINPARAMS *pin = (SENDCMDINPARAMS *) (buffer + sizeof  (SRB_IO_CONTROL)) ;  // Testing both IDE controllers in a loop  for (controller = 0; controller < 2; controller++)           {  // Forming ScsiPort for each controller  sprintf (ScsiPort, "\\.\Scsi%d:", controller);  // Opening the required ScsiPort  h = CreateFile (ScsiPort, GENERIC_READ  GENERIC_WRITE,                               FILE_SHARE_READ  FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);               if (h == INVALID_HANDLE_VALUE) {  // EXIT IF ERROR  printf("-ERR: Unable to open ScsiPort%d\n", controller);                       return -1;               }  // Testing both devices on each of the IDE controllers  for  (LU = 0; LU < 2; LU++)  {  // Initializing the input buffer  memset (buffer, 0, sizeof (buffer));  // PREPARING THE SRB IO CONTROL STRUCTURE,  // intended for the miniport driver                       p > Timeout = 10000;  // Wait  p > Length = SENDIDLENGTH;  // Max. length  p > HeaderLength = sizeof (SRB_IO_CONTROL);  // Header size  p > ControlCode = IOCTL_SCSI_MINIPORT_IDENTIFY;  // ^^^ code of the command sent to the driver   // Signature for ATAPI.SYS - "SCSIDISK"  strncpy ((char *) p > Signature, "SCSIDISK", 8);  // PREPARING THE SENDCMDINPARAMS STRUCTURE,   // containing ATA commands passed to the IDE drive  pin > bDriveNumber = LU;                       pin > irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY;  // SENDING THE REQUEST TO THE MINIPORT DRIVER  if (DeviceIoControl (h, IOCTL_SCSI_MINIPORT, buffer,                       sizeof (SRB_IO_CONTROL) + sizeof (SENDCMDINPARAMS) - 1,                               buffer, sizeof (SRB_IO_CONTROL) + SENDIDLENGTH,                               &returned, 0))                               if (buffer[98]!=0)  {// In response, get the string with   // the identifier of   // the IDE- drive, which we display on   // the screen.  for (a=98; a < 136; a+=2)                                       printf("%c%c", buffer[a+1], buffer[a]);                                       printf("\n");                                       }               }               CloseHandle (h);  // Close the descriptor of the given SCSI miniport.  }          return 0;  } 
image from book
 


CD Cracking Uncovered. Protection against Unsanctioned CD Copying
CD Cracking Uncovered: Protection Against Unsanctioned CD Copying (Uncovered series)
ISBN: 1931769338
EAN: 2147483647
Year: 2003
Pages: 60

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net