Hello all,
I realize this is quite a generic question, mostly about the Windows API, but I recon there are enough people in here that know enough of the Windows API to answer my question. Myself, I know nearly nothing about it.
Just for fun, I have been reversing some malware I found on someone's computer, wondering what it would do. I found out quite a lot already, but I can't figure out this part. I translated it to C++ (well, strictly speaking it's C as well :P). Here's what I found (note that it may not be completely valid; reversing is quite tough, I may have misread an address or something similar. But I've been careful, so I think this should be about right.):
Code:
struct GETVERSIONINPARAMS { /* Size: 0x18 */
UCHAR bVersion; /* Address 0x00 */
UCHAR bRevision; /* Address 0x01 */
UCHAR bReserved; /* Address 0x02 */
UCHAR bIDEDeviceMap; /* Address 0x03 */
ULONG fCapabilities; /* Address 0x04 */
ULONG dwReserved[4]; /* Address 0x08 */
};
struct IDEREGS { /* Size: 0x08 */
UCHAR bFeaturesReg; /* Address 0x00 */
UCHAR bSectorCountReg; /* Address 0x01 */
UCHAR bSectorNumberReg; /* Address 0x02 */
UCHAR bCylLowReg; /* Address 0x03 */
UCHAR bCylHighReg; /* Address 0x04 */
UCHAR bDriveHeadReg; /* Address 0x05 */
UCHAR bCommandReg; /* Address 0x06 */
UCHAR bReserved; /* Address 0x07 */
};
struct SENDCMDINPARAMS { /* Size: 0x24 */
ULONG cBufferSize; /* Address 0x00 */
IDEREGS irDriveRegs; /* Address 0x04 */
UCHAR bDriveNumber; /* Address 0x0C */
UCHAR bReserved[3]; /* Address 0x0D */
ULONG dwReserved[4]; /* Address 0x10 */
UCHAR bBuffer[1]; /* Address 0x20 */
};
struct DriverStatus { /* Size: 0x0C */
UCHAR bDriveError; /* Address 0x00 */
UCHAR bIDEError; /* Address 0x01 */
UCHAR bReserved[2]; /* Address 0x02 */
ULONG dwReserved[2]; /* Address 0x04 */
};
struct SENDCMDOUTPARAMS { /* Size: 0x214 */
ULONG cBufferSize; /* Address 0x00 */
DRIVERSTATUS DriverStatus; /* Address 0x04 */
UCHAR bBuffer[0x204]; /* Address 0x10 */
};
struct LARGE_INTEGER { /* Size: 0x08 */
DWORD LowPart; /* Address 0x00 */
LONG HighPart; /* Address 0x04 */
};
struct DISK_EXTENT { /* Size: 0x18 */
DWORD DiskNumber; /* Address 0x00 */
LARGE_INTEGER StartingOffset; /* Address 0x08 */
LARGE_INTEGER ExtentLength; /* Address 0x10 */
};
struct VOLUME_DISK_EXTENTS { /* Size: 0x20 */
DWORD NumberOfDiskExtents; /* Address 0x00 */
DISK_EXTENT Extents[1]; /* Address 0x08 */
};
bool func(char *data, int *nread)
{
HANDLE hDisk;
DWORD bytesRet;
int ret = 0;
hDisk = CreateFileA("\\\\.\\PhysicalDrive0", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
0, 0);
if(hDisk == -1)
return false;
VOLUME_DISK_EXTENTS diskExtents
memset((void*)&diskExtents, 0, sizeof(diskExtents));
DeviceIoControl(hDisk, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0,
(void*)&diskExtents, sizeof(diskExtents), &bytesRet, 0);
GETVERSIONINPARAMS inParams;
memset((void*)&inParams, 0, sizeof(inParams));
if(!DeviceIoControl(hDisk, SMART_GET_VERSION, NULL, 0,
(void*)&inParams, sizeof(inParams), &bytesRet, 0)) {
CloseHandle(hDisk);
return false;
}
if(inParams.bIDEDeviceMap == 0) {
CloseHandle(hDisk);
return false;
}
SENDCMDINPARAMS cmdInParams;
memset((void*)&cmdInParams, 0, sizeof(cmdInParams));
cmdInParams.cBufferSize = 0x200;
cmdInParams.irDriveRegs.bDriveHeadReg = (diskExtents.Extents[0].DiskNumber & 1) ? 0xB0 : 0xA0;
cmdInParams.irDriveRegs.bSectorCountReg = 1;
cmdInParams.irDriveRegs.bCommandReg = (inParams.bIDEDeviceMap & (0x10 << (diskExtents.Extents[0].DiskNumber & 0xFF))) ? 0xA1 : 0xEC;
cmdInParams.irDriveRegs.bSectorNumberReg = 1;
cmdInParams.bDriveNumber = diskExtents.Extents[0].DiskNumber;
SENDCMDOUTPARAMS cmdOutParams;
memset((void*)&cmdOutParams, 0, sizeof(cmdOutParams));
if(!DeviceIoControl(hDisk, SMART_RCV_DRIVE_DATA,
(void*)&cmdInParams, sizeof(cmdInParams),
(void*)&cmdOutParams, sizeof(cmdOutParams),
&bytesRet, 0)) {
CloseHandle(hDisk);
return false;
}
*nread = 0;
for(int i = 0; i < 20; i++) {
if(cmdOutParams.bBuffer[20 + i] == 0)
break;
data[i] = cmdOutParams.bBuffer[20 + i];
(*nread)++;
}
data[*nread] = 0;
CloseHandle(hDisk);
return true;
}
I've tried searching through MSDN, but the description on the DeviceIoControl aren't too good there.
Thanks in advance