A forum for reverse engineering, OS internals and malware analysis 

Forum for discussion about user-mode development.
 #10208  by Tigzy
 Wed Dec 07, 2011 1:20 pm
Hello
Not to flood this thread: http://www.kernelmode.info/forum/viewto ... ?f=14&t=29

----

Here's my code:

When using the READ10, all working fine.
When using READ6 / READ12, returns STATUS_INVALID_DEVICE_REQUEST.
I can't see any big mistake explaining this. The structures are slighty the sames...
Code: Select all
#define CDB10GENERIC_LENGTH        10
#define CDB12GENERIC_LENGTH        12
#define SCSIOP_READ10              0x28
#define SCSIOP_READ12              0xA8

...

bool GetSPTIMBR(byte* outBuff, int sizeBuff, int phyDrive)
{   
	DWORD outBytes;
	SCSI_PASS_THROUGH_WITH_BUFFERS sptwb;
        SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER sptdwb;
	ULONG length = 0;
	NTSTATUS ntStatus = STATUS_SUCCESS;
	UNICODE_STRING szPath = {0};
	OBJECT_ATTRIBUTES Attr = {0};
	IO_STATUS_BLOCK IoStatusBlock = {0};
	HANDLE hDevice = 0;

	// Init drive name
	wstring fileName = L"\\??\\PhysicalDrive";
	WCHAR nDrive[3];
	_stprintf_s(nDrive, L"%d", phyDrive);
	fileName.append(nDrive);	

	// Init UNICODE Path & attributes
	RtlInitUnicodeString(&szPath, fileName.c_str());

	// Init OBJECT_ATTRIBUTE
	Attr.Length = sizeof(OBJECT_ATTRIBUTES);	
	Attr.RootDirectory = NULL;
	Attr.ObjectName = &szPath;
	Attr.Attributes = 0;
	Attr.SecurityDescriptor = NULL;
	Attr.SecurityQualityOfService = NULL;

	// Open Device
	ntStatus = NtCreateFile(&hDevice, GENERIC_WRITE | GENERIC_READ, &Attr, &IoStatusBlock, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, 0, NULL, 0);
	if (ntStatus != STATUS_SUCCESS)
	{
		printf ("Error : 0x%x\n" , ntStatus);
		return (FALSE);
	}
	
	// Init input / output buffs
	ZeroMemory(&sptdwb, sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER));
       ZeroMemory(outBuff,sizeBuff);

	// Init struct
	sptdwb.sptd.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
	//sptdwb.sptd.ScsiStatus = 0; // Must be 0 --> filled by the function
        sptdwb.sptd.PathId = 0; // Id of the SCSI bus adapter , often 0
        sptdwb.sptd.TargetId = 1; // Scsi Id number of the device
        sptdwb.sptd.Lun = phyDrive; // Logical unit number of the device
        sptdwb.sptd.CdbLength = CDB12GENERIC_LENGTH; // Size of the CDB struct
        sptdwb.sptd.DataIn = SCSI_IOCTL_DATA_IN; // Size of the data
        sptdwb.sptd.SenseInfoLength = SPT_SENSE_LENGTH; // Length of the SenseInfo buff
        sptdwb.sptd.DataTransferLength = sizeBuff; // Sector size
        sptdwb.sptd.TimeOutValue = 2; // Timeout (secs)
        sptdwb.sptd.DataBuffer = outBuff; // Pointer to dataBuff
        sptdwb.sptd.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER,ucSenseBuf);

	// ----- Read 12 ----
        sptdwb.sptd.Cdb[0] = SCSIOP_READ12; //SCSIOP_READ_DATA_BUFF;
        sptdwb.sptd.Cdb[1] = 0x08; //  LUN = 000b, DPO = 0, FUA = 1, RFU1 = 0, RFU1 = 0, RelAdr = 0      (LSbit)
	sptdwb.sptd.Cdb[2] = 0x00; //    Cdb[2-->5] = 0;   //  Logical block addresss  (MSByte)
	sptdwb.sptd.Cdb[3] = 0x00;
	sptdwb.sptd.Cdb[4] = 0x00;
	sptdwb.sptd.Cdb[5] = 0x00;

	byte size[4];
	convertIntTo4bytes (sizeBuff, size);	
	
	sptdwb.sptd.Cdb[6] = size[3]; //(UCHAR)(sizeBuff >> 24);  // Parameter List length
	sptdwb.sptd.Cdb[7] = size[2]; //(UCHAR)(sizeBuff >> 16);  // Parameter List length
        sptdwb.sptd.Cdb[8] = size[1]; //(UCHAR)(sizeBuff >> 8);  // Parameter List length
        sptdwb.sptd.Cdb[9] = size[0]; //0;	
	sptdwb.sptd.Cdb[10] = 0x00;
	// -------------------

	length = sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER);

	ntStatus = NtDeviceIoControlFile( hDevice, NULL, NULL, NULL, &IoStatusBlock,  IOCTL_SCSI_PASS_THROUGH_DIRECT,  &sptdwb, length, &sptdwb, length);
	if (ntStatus != STATUS_SUCCESS)
	{
		printf ("Error : 0x%x\n" , ntStatus);
		return (FALSE);
	}	

	CloseHandle(hDevice);
	return true;
}
 #10230  by Tigzy
 Thu Dec 08, 2011 8:33 am
Have tested INQUIRY, MODE SENSE, all working fine...
I'm really confused about those READ commands :cry:

Nobody's got an idea?

EDIT: There was a mistake in the CDB, but not the origin of that error:
Code: Select all
// ----- Read 6 ----
	sptdwb.sptd.CdbLength = CDB6GENERIC_LENGTH;
	sptdwb.sptd.Cdb[0] = SCSIOP_READ6;
    sptdwb.sptd.Cdb[1] = 0x00; //  LUN = 000b, LSB = 00000      (LSbit)
	sptdwb.sptd.Cdb[2] = 0x00; //    Cdb[2-->5] = 0;   //  Logical block addresss  (MSByte)
	sptdwb.sptd.Cdb[3] = 0x00;
    sptdwb.sptd.Cdb[4] = 0x01;
	sptdwb.sptd.Cdb[5] = 0x00;
	// ------------------