想截获WindowsXP的“获取硬盘物理序列号”的API,使该API返回的“硬盘物理序列号的值”为本人指定的值。
   不知有没有可能实现?
   肯请各位帮助!谢了!!!

解决方案 »

  1.   

    系统中没有哪个API可以直接取到硬盘序列号的,那些取序列号的函数都是程序员自己定义的,而且这些函数是用多个API组合的,比如CreateFile、DeviceIoControl等,所以你的想法是没法实现的
      

  2.   

    那你只有HOOK一些关键函数,但是很容易引起误判
      

  3.   

    好像没有一个api可以独立获取硬盘序列号
      

  4.   

    读取硬件ID 
    如硬盘ID function GetIdeSerialNumber: pchar; 
    const IDENTIFY_BUFFER_SIZE = 512; 
    type 
      TIDERegs = packed record 
        bFeaturesReg: BYTE; // Used for specifying SMART "commands". 
        bSectorCountReg: BYTE; // IDE sector count register 
        bSectorNumberReg: BYTE; // IDE sector number register 
        bCylLowReg: BYTE; // IDE low order cylinder value 
        bCylHighReg: BYTE; // IDE high order cylinder value 
        bDriveHeadReg: BYTE; // IDE drive/head register 
        bCommandReg: BYTE; // Actual IDE command. 
        bReserved: BYTE; // reserved for future use. Must be zero. 
      end; 
      TSendCmdInParams = packed record 
        // Buffer size in bytes 
        cBufferSize: DWORD; 
        // Structure with drive register values. 
        irDriveRegs: TIDERegs; 
        // Physical drive number to send command to (0,1,2,3). 
        bDriveNumber: BYTE; 
        bReserved: array[0..2] of Byte; 
        dwReserved: array[0..3] of DWORD; 
        bBuffer: array[0..0] of Byte; // Input buffer. 
      end; 
      TIdSector = packed record 
        wGenConfig: Word; 
        wNumCyls: Word; 
        wReserved: Word; 
        wNumHeads: Word; 
        wBytesPerTrack: Word; 
        wBytesPerSector: Word; 
        wSectorsPerTrack: Word; 
        wVendorUnique: array[0..2] of Word; 
        sSerialNumber: array[0..19] of CHAR; 
        wBufferType: Word; 
        wBufferSize: Word; 
        wECCSize: Word; 
        sFirmwareRev: array[0..7] of Char; 
        sModelNumber: array[0..39] of Char; 
        wMoreVendorUnique: Word; 
        wDoubleWordIO: Word; 
        wCapabilities: Word; 
        wReserved1: Word; 
        wPIOTiming: Word; 
        wDMATiming: Word; 
        wBS: Word; 
        wNumCurrentCyls: Word; 
        wNumCurrentHeads: Word; 
        wNumCurrentSectorsPerTrack: Word; 
        ulCurrentSectorCapacity: DWORD; 
        wMultSectorStuff: Word; 
        ulTotalAddressableSectors: DWORD; 
        wSingleWordDMA: Word; 
        wMultiWordDMA: Word; 
        bReserved: array[0..127] of BYTE; 
      end; 
      PIdSector = ^TIdSector; 
      TDriverStatus = packed record 
        // 驱动器返回的错误代码,无错则返回0 
        bDriverError: Byte; 
        // IDE出错寄存器的内容,只有当bDriverError 为 SMART_IDE_ERROR 时有效 
        bIDEStatus: Byte; 
        bReserved: array[0..1] of Byte; 
        dwReserved: array[0..1] of DWORD; 
      end; 
      TSendCmdOutParams = packed record 
        // bBuffer的大小 
        cBufferSize: DWORD; 
        // 驱动器状态 
        DriverStatus: TDriverStatus; 
        // 用于保存从驱动器读出的数据的缓冲区,实际长度由cBufferSize决定 
        bBuffer: array[0..0] of BYTE; 
      end; 
    var 
      hDevice: Thandle; 
      cbBytesReturned: DWORD; 
      SCIP: TSendCmdInParams; 
      aIdOutCmd: array[0..(SizeOf(TSendCmdOutParams) + IDENTIFY_BUFFER_SIZE - 1) - 1] of Byte; 
      IdOutCmd: TSendCmdOutParams absolute aIdOutCmd; 
    procedure ChangeByteOrder(var Data; Size: Integer); 
    var 
      ptr: Pchar; 
      i: Integer; 
      c: Char; 
    begin 
      ptr := @Data; 
      for I := 0 to (Size shr 1) - 1 do begin 
        c := ptr^; 
        ptr^ := (ptr + 1)^; 
        (ptr + 1)^ := c; 
        Inc(ptr, 2); 
      end; 
    end; 
    begin 
    Result := ''; // 如果出错则返回空串 
    if SysUtils.Win32Platform = VER_PLATFORM_WIN32_NT then begin // Windows NT, Windows 2000 
    // 提示! 改变名称可适用于其它驱动器,如第二个驱动器: '\\.\PhysicalDrive1\' 
    hDevice := CreateFile('\\.\PhysicalDrive0', GENERIC_READ or GENERIC_WRITE, 
    FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0); 
    end else // Version Windows 95 OSR2, Windows 98 
    hDevice := CreateFile('\\.\SMARTVSD', 0, 0, nil, CREATE_NEW, 0, 0); 
    if hDevice = INVALID_HANDLE_VALUE then Exit; 
    try 
    FillChar(SCIP, SizeOf(TSendCmdInParams) - 1, #0); 
    FillChar(aIdOutCmd, SizeOf(aIdOutCmd), #0); 
    cbBytesReturned := 0; 
    // Set up data structures for IDENTIFY command. 
    with SCIP do begin 
    cBufferSize := IDENTIFY_BUFFER_SIZE; 
    // bDriveNumber := 0; 
    with irDriveRegs do begin 
    bSectorCountReg := 1; 
    bSectorNumberReg := 1; 
    // if Win32Platform=VER_PLATFORM_WIN32_NT then bDriveHeadReg := $A0 
    // else bDriveHeadReg := $A0 or ((bDriveNum and 1) shl 4); 
    bDriveHeadReg := $A0; 
    bCommandReg := $EC; 
    end; 
    end; 
    if not DeviceIoControl(hDevice, $0007C088, @SCIP, SizeOf(TSendCmdInParams) - 1, 
    @aIdOutCmd, SizeOf(aIdOutCmd), cbBytesReturned, nil) then Exit; 
    finally 
    CloseHandle(hDevice); 
    end; 
    with PIdSector(@IdOutCmd.bBuffer)^ do begin 
    ChangeByteOrder(sSerialNumber, SizeOf(sSerialNumber)); 
    (Pchar(@sSerialNumber) + SizeOf(sSerialNumber))^ := #0; 
    Result := Pchar(@sSerialNumber); 
    end; 
    end; 
      

  5.   

    这100分给我了~,以下的程序100符合你的要求。(含源代码)
    http://blogimg.chinaunix.net/blog/upfile2/090518234832.rar通过HOOK  DeviceIoControl函数,来任意修改获取硬盘物理序列号!
    下载后打开:GUI\Debug目录,运行GUI.exe
    然后在托盘按setting,设置新的硬盘物理序列号,再读到的的硬盘物理序列号,就是你刚刚设置的了。
      

  6.   

    在硬盘加密或者装有还原卡的状况下,createfile访问磁盘(\\.\PhysicalDrive0)会失败。
    更稳妥的办法是,直接申请IO端口操作,直接读取硬盘数据。从这样的状况看,截获API是徒劳的....