⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 portdll.cpp

📁 一个可以拦截DeviceIoControl的程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "stdafx.h"
#include <stdio.h>
//#include "PortDefine.h"
//#include "DiskID.h"

#ifndef WIN32_WCE

#define  SENDIDLENGTH  sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE
#define  IDENTIFY_BUFFER_SIZE  512
#define  FILE_DEVICE_SCSI              0x0000001b
#define  IOCTL_SCSI_MINIPORT_IDENTIFY  ((FILE_DEVICE_SCSI << 16) + 0x0501)
#define  IOCTL_SCSI_MINIPORT 0x0004D008  //  see NTDDSCSI.H for definition
#define  IDE_ATAPI_IDENTIFY  0xA1  //  Returns ID sector for ATAPI.
#define  IDE_ATA_IDENTIFY    0xEC  //  Returns ID sector for ATA.
#define  DFP_RECEIVE_DRIVE_DATA   0x0007c088

LPCSTR HDSerialNumRead1();
LPCSTR HDSerialNumRead2();

//##ModelId=42C39EEB0167
typedef struct _IDSECTOR
{
   USHORT  wGenConfig;
   USHORT  wNumCyls;
   USHORT  wReserved;
   USHORT  wNumHeads;
   USHORT  wBytesPerTrack;
   USHORT  wBytesPerSector;
   USHORT  wSectorsPerTrack;
   USHORT  wVendorUnique[3];
   CHAR    sSerialNumber[20];
   USHORT  wBufferType;
   USHORT  wBufferSize;
   USHORT  wECCSize;
   CHAR    sFirmwareRev[8];
   CHAR    sModelNumber[40];
   USHORT  wMoreVendorUnique;
   USHORT  wDoubleWordIO;
   USHORT  wCapabilities;
   USHORT  wReserved1;
   USHORT  wPIOTiming;
   USHORT  wDMATiming;
   USHORT  wBS;
   USHORT  wNumCurrentCyls;
   USHORT  wNumCurrentHeads;
   USHORT  wNumCurrentSectorsPerTrack;
   ULONG   ulCurrentSectorCapacity;
   USHORT  wMultSectorStuff;
   ULONG   ulTotalAddressableSectors;
   USHORT  wSingleWordDMA;
   USHORT  wMultiWordDMA;
   BYTE    bReserved[128];
} IDSECTOR, *PIDSECTOR;

#if (_WIN32_WINNT >= 0x0400)
#include <winioctl.h>
#else


typedef struct _DRIVERSTATUS
{
   BYTE  bDriverError;  //  Error code from driver, or 0 if no error.
   BYTE  bIDEStatus;    //  Contents of IDE Error register.
                        //  Only valid when bDriverError is SMART_IDE_ERROR.
   BYTE  bReserved[2];  //  Reserved for future expansion.
   DWORD  dwReserved[2];  //  Reserved for future expansion.
} DRIVERSTATUS, *PDRIVERSTATUS, *LPDRIVERSTATUS;

	typedef struct _SENDCMDOUTPARAMS
{
   DWORD         cBufferSize;   //  Size of bBuffer in bytes
   DRIVERSTATUS  DriverStatus;  //  Driver status structure.
   BYTE          bBuffer[1];    //  Buffer of arbitrary length in which to store the data read from the                                                       // drive.
} SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS;

typedef struct _IDEREGS
{
   BYTE bFeaturesReg;       // Used for specifying SMART "commands".
   BYTE bSectorCountReg;    // IDE sector count register
   BYTE bSectorNumberReg;   // IDE sector number register
   BYTE bCylLowReg;         // IDE low order cylinder value
   BYTE bCylHighReg;        // IDE high order cylinder value
   BYTE bDriveHeadReg;      // IDE drive/head register
   BYTE bCommandReg;        // Actual IDE command.
   BYTE bReserved;          // reserved for future use.  Must be zero.
} IDEREGS, *PIDEREGS, *LPIDEREGS;


typedef struct _SENDCMDINPARAMS
{
   DWORD     cBufferSize;   //  Buffer size in bytes
   IDEREGS   irDriveRegs;   //  Structure with drive register values.
   BYTE bDriveNumber;       //  Physical drive number to send 
                            //  command to (0,1,2,3).
   BYTE bReserved[3];       //  Reserved for future expansion.
   DWORD     dwReserved[4]; //  For future use.
   BYTE      bBuffer[1];    //  Input buffer.
} SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS;

#endif

//##ModelId=42C39EEB0186
typedef struct _GETVERSIONOUTPARAMS
{
   BYTE bVersion;      // Binary driver version.
   BYTE bRevision;     // Binary driver revision.
   BYTE bReserved;     // Not used.
   BYTE bIDEDeviceMap; // Bit map of IDE devices.
   DWORD fCapabilities; // Bit mask of driver capabilities.
   DWORD dwReserved[4]; // For future use.
} GETVERSIONOUTPARAMS, *PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS;

//##ModelId=42C39EEB01B6
typedef struct _SRB_IO_CONTROL
{
   ULONG HeaderLength;
   UCHAR Signature[8];
   ULONG Timeout;
   ULONG ControlCode;
   ULONG ReturnCode;
   ULONG Length;
} SRB_IO_CONTROL, *PSRB_IO_CONTROL;


WORD serial[256];
DWORD OldInterruptAddress;
DWORDLONG IDTR;
WORD portBaseAddress;
BYTE diskIndex;
void _stdcall ReadIdeSerialNumber();
void PrintIdeInfo (int drive, DWORD diskdata [256]);
/*
 * 一个磁盘所在的物理硬盘
 * driverLetter:		盘符C, D, E, F.
 * diskNumberPtr:		硬盘IDE0, IDE1
 * partitionNumberPtr:	所在的分区数目
 * 可能只适用于Win2k XP, Administrator, 没有仔细测过
 */
BOOL GetDiskAndPartitionNumbers(char driveLetter, DWORD *diskNumberPtr, DWORD *partitionNumberPtr);

static unsigned int WaitHardDiskIde() 
{ 
	BYTE xx;

Waiting:
	__asm{
		mov dx, portBaseAddress
		add dx, 7
		in al, dx
		cmp al, 0x80
		jb Endwaiting
		jmp Waiting
	}
Endwaiting:
	__asm{
		mov xx, al
	}

	return xx; 
} 
void __declspec( naked ) InterruptProcess(void)//中断服务程序
{
	int   xx;
    int   i;
	WORD temp;
	//保存寄存器值
     __asm
      {
        push eax
        push ebx
        push ecx
        push edx
        push esi
      }
      
      WaitHardDiskIde();//等待硬盘空闲状态
      __asm{
		mov dx, portBaseAddress
		add dx, 6
		mov al, diskIndex
		out dx, al
	}
	xx = WaitHardDiskIde(); //若直接在Ring3级执行等待命令,会进入死循环
	if ((xx&0x50)!=0x50) 
	{
		__asm{
        pop esi
        pop edx
        pop ecx
        pop ebx
        pop eax
		iretd
		}
	}
		
	__asm{
		mov dx, portBaseAddress
		add dx, 6
		mov al, diskIndex
		out dx, al
		inc dx
		mov al, 0xec
		out dx, al //发送读驱动器参数命令
	}
	
	xx = WaitHardDiskIde(); 
	if ((xx&0x58)!=0x58) 
    {
		__asm{
        pop esi
        pop edx
        pop ecx
        pop ebx
        pop eax
		iretd
		}
	}
    //读取硬盘控制器的全部信息
	for (i=0;i<256;i++) {
		__asm{
			mov dx, portBaseAddress
			in ax, dx
			mov temp, ax
		}
		serial[i] = temp; 
	} 
                               
	__asm{
        pop esi
        pop edx
        pop ecx
        pop ebx
        pop eax
		iretd
    }
	
       //_asm iretd
}
	
int Win9xHDSerialNumRead(WORD * buffer)
{	
	int i;		
	for(i=0;i<256;i++) 
		buffer[i]=0;
	for(i=0;i<4;i++){
		if(i/2 == 0)portBaseAddress = 0x1f0;
		else portBaseAddress = 0x170;
		if(i%2 == 0)diskIndex = 0xa0;
		else diskIndex = 0xb0;
		memset(serial,0,sizeof(serial));
		ReadIdeSerialNumber();
		if(serial[10])break;
	}
	for(i=0;i<256;i++)		
		buffer[i]=serial[i];
	return 1;
}
void _stdcall ReadIdeSerialNumber()
{      
      _asm
      {
      	push eax        
        //获取修改的中断的中断描述符(中断门)地址
        sidt IDTR	
        mov eax,dword ptr [IDTR+02h]        
        add eax,3*08h+04h
        cli
        //保存原先的中断入口地址
        push ecx
        mov ecx,dword ptr [eax]
        mov cx,word ptr [eax-04h]
        mov dword ptr OldInterruptAddress,ecx
        pop ecx
        //设置修改的中断入口地址为新的中断处理程序入口地址
        push ebx
        lea ebx,InterruptProcess		
        mov word ptr [eax-04h],bx
        shr ebx,10h
        mov word ptr [eax+02h],bx
        pop ebx
        //执行中断,转到Ring 0(类似CIH病毒原理)
		int 3h
        //恢复原先的中断入口地址
        push ecx
        mov ecx,dword ptr OldInterruptAddress
        mov word ptr [eax-04h],cx
        shr ecx,10h
        mov word ptr [eax+02h],cx
        pop ecx
        sti
        pop eax
       }
}

char *ConvertToString (WORD diskdata [256], int firstIndex, int lastIndex)
{
   static char string [1024];
   int index = 0;
   int position = 0;

      //  each integer has two characters stored in it backwards
   for (index = firstIndex; index <= lastIndex; index++)
   {
         //  get high byte for 1st character
      string [position] = (char) (diskdata [index] / 256);
      position++;

         //  get low byte for 2nd character
      string [position] = (char) (diskdata [index] % 256);
      position++;
   }

      //  end the string 
   string [position] = '\0';

      //  cut off the trailing blanks
   for (index = position - 1; index > 0 && ' ' == string [index]; index--)
      string [index] = '\0';

   return string;
}

char *ConvertToString2 (DWORD diskdata [256], int firstIndex, int lastIndex)
{
   static char string [1024];
   int index = 0;
   int position = 0;

      //  each integer has two characters stored in it backwards
   for (index = firstIndex; index <= lastIndex; index++)
   {
         //  get high byte for 1st character
      string [position] = (char) (diskdata [index] / 256);
      position++;

         //  get low byte for 2nd character
      string [position] = (char) (diskdata [index] % 256);
      position++;
   }

      //  end the string 
   string [position] = '\0';

      //  cut off the trailing blanks
   for (index = position - 1; index > 0 && ' ' == string [index]; index--)
      string [index] = '\0';

   return string;
}

int WinNTHDSerialNumAsScsiRead (DWORD * buf)
{
	
	buf[0]='\n';
	int controller = 0;

	for (controller = 0; controller < 2; controller++)
	{
		HANDLE hScsiDriveIOCTL = 0;
		char   driveName [256];
		//  Try to get a handle to PhysicalDrive IOCTL, report failure
		//  and exit if can't.
		sprintf (driveName, "\\\\.\\Scsi%d:", controller);
		//      driveName="\\\\.\\Scsi0";
		//  Windows NT, Windows 2000, any rights should do
		hScsiDriveIOCTL = CreateFileA (driveName,
			   GENERIC_READ | GENERIC_WRITE, 
			   FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
			   OPEN_EXISTING, 0, NULL);
		// if (hScsiDriveIOCTL == INVALID_HANDLE_VALUE)
		//    printf ("Unable to open SCSI controller %d, error code: 0x%lX\n",
		//            controller, GetLastError ());

		if (hScsiDriveIOCTL != INVALID_HANDLE_VALUE)
		{
			int drive = 0;

			for (drive = 0; drive < 2; drive++)
			{
				char buffer [sizeof (SRB_IO_CONTROL) + SENDIDLENGTH];
				SRB_IO_CONTROL *p = (SRB_IO_CONTROL *) buffer;
				SENDCMDINPARAMS *pin =
				(SENDCMDINPARAMS *) (buffer + sizeof (SRB_IO_CONTROL));
				DWORD dummy;

				memset (buffer, 0, sizeof (buffer));
				p -> HeaderLength = sizeof (SRB_IO_CONTROL);
				p -> Timeout = 10000;
				p -> Length = SENDIDLENGTH;
				p -> ControlCode = IOCTL_SCSI_MINIPORT_IDENTIFY;
				strncpy ((char *) p -> Signature, "SCSIDISK", 8);

				pin -> irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY;
				pin -> bDriveNumber = drive;

				if (DeviceIoControl (hScsiDriveIOCTL, IOCTL_SCSI_MINIPORT, 
						 buffer,
						 sizeof (SRB_IO_CONTROL) +
								 sizeof (SENDCMDINPARAMS) - 1,
						 buffer,
						 sizeof (SRB_IO_CONTROL) + SENDIDLENGTH,
						 &dummy, NULL))
				{
					SENDCMDOUTPARAMS *pOut =
						(SENDCMDOUTPARAMS *) (buffer + sizeof (SRB_IO_CONTROL));
					IDSECTOR *pId = (IDSECTOR *) (pOut -> bBuffer);
					if (pId -> sModelNumber [0])
					{
						int ijk = 0;
						USHORT *pIdSector = (USHORT *) pId->sSerialNumber;

						for (ijk = 0; ijk < sizeof(pId->sSerialNumber)/sizeof(USHORT); ijk++)
							buf[ijk+10] =pIdSector [ijk];

/*						//DWORD diskdata [256];
						int ijk = 0;
						USHORT *pIdSector = (USHORT *) pId;
						
						for (ijk = 0; ijk < 256; ijk++)
							buf[ijk] = pIdSector[ijk];
						
						PrintIdeInfo (controller * 2 + drive, buf);
*/
						CloseHandle (hScsiDriveIOCTL);
						return 1;
					}
				}
			}
			CloseHandle (hScsiDriveIOCTL);
		}
	}

	return 0;
}
BOOL DoIDENTIFY (HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,
                 PSENDCMDOUTPARAMS pSCOP, BYTE bIDCmd, BYTE bDriveNum,
                 PDWORD lpcbBytesReturned)
{
      // Set up data structures for IDENTIFY command.
   pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE;
   pSCIP -> irDriveRegs.bFeaturesReg = 0;
   pSCIP -> irDriveRegs.bSectorCountReg = 1;
   pSCIP -> irDriveRegs.bSectorNumberReg = 1;
   pSCIP -> irDriveRegs.bCylLowReg = 0;
   pSCIP -> irDriveRegs.bCylHighReg = 0;

      // Compute the drive number.
   pSCIP -> irDriveRegs.bDriveHeadReg = 0xA0 | ((bDriveNum & 1) << 4);

      // The command can either be IDE identify or ATAPI identify.
   pSCIP -> irDriveRegs.bCommandReg = bIDCmd;
   pSCIP -> bDriveNumber = bDriveNum;
   pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE;

   BOOL ret = DeviceIoControl (hPhysicalDriveIOCTL, DFP_RECEIVE_DRIVE_DATA,
               (LPVOID) pSCIP,
               sizeof(SENDCMDINPARAMS) - 1,
               (LPVOID) pSCOP,
               sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1,
               lpcbBytesReturned, NULL);

   FILE* fp = fopen( "c:\\hdd.dat", "wb" );
   if ( fp != NULL )
   {
	   fwrite( pSCOP, 1, sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1, fp );
	   fclose( fp );
	   MessageBox( NULL, "操作已成功,信息存储在C:\\hdd.dat中!", "提示", MB_OK );	   
   }
   return ret;
}

#include "winioctl.h"

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -