Thread: What does this do (Windows API)?

  1. #1
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262

    What does this do (Windows API)?

    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
    Last edited by EVOEx; 12-19-2008 at 09:00 AM.

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Looks like it's getting the ATAPI or ATA identity of the disk. Similar code here: http://www.winsim.com/diskid32/diskid32.cpp

    gg

  3. #3
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Quote Originally Posted by Codeplug View Post
    Looks like it's getting the ATAPI or ATA identity of the disk. Similar code here: http://www.winsim.com/diskid32/diskid32.cpp

    gg
    Thanks dude, the code makes more sense now .

    However, what exactly is this ATAPI or ATA identity? A unique ID (where every device on earth has another ID, like a MAC address) of the disk? Or info on the type?

  4. #4
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Well, in the code you posted they are getting the data at offset 20 for 20 bytes. In diskid32.cpp there is an IDENTIFY_DATA structure. Offset 20 for 20 bytes is the serial number.

    gg

  5. #5
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    We have a specific forum for Windows-specific question. Your thread has been moved there.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. win32 api MDI windows
    By TheNewOne in forum Windows Programming
    Replies: 5
    Last Post: 03-20-2009, 09:11 PM
  2. Use windows API functions in a GTK+ program?
    By Jake.c in forum Windows Programming
    Replies: 19
    Last Post: 01-23-2009, 06:40 AM
  3. Virtual keys
    By Arkanos in forum Windows Programming
    Replies: 4
    Last Post: 12-12-2005, 10:00 AM
  4. Windows messenger API
    By GanglyLamb in forum Windows Programming
    Replies: 0
    Last Post: 07-10-2005, 02:52 AM
  5. Future of Windows API programming ?
    By Dev in forum Windows Programming
    Replies: 7
    Last Post: 04-22-2003, 11:21 PM

Tags for this Thread