如题!
http://expert.csdn.net/Expert/topic/1575/1575103.xml?temp=.2643091

解决方案 »

  1.   

    很多年以前(^_^),我在dos下分析过format和fdisk程序,当时做数据恢复。没记错的话,软盘和硬盘的序列号是format程序生成的,软盘在第一个扇区的bpb表中,硬盘在系统分区的第一个扇区中,位置记不太清楚。你把一个软盘的序列号手动算成16进制,好像高位在前,低位在后,与软盘第一个扇区的数据比较一下,应该很简单可以看出来。
      

  2.   

    网上找到的一个qb(够老吧)代码,不知道win下能不能用? 
    最后一段是原理。'=================================================
    ==========================
    ' Subject: CHANGE DISK SERIAL NUMBER Date: 09/93 (00:00) 
    ' Author: Andy Thomas Code: QB, PDS 
    ' Keys: CHANGE,DISK,SERIAL,NUMBER Packet: DISK.ABC
    '=================================================
    ==========================
    DEFINT A-Z
    ' Purpose: To change the serial number on any DOS disk.
    ' WARNING THE FOLLOWING PROGRAM USES DIRECT DISK WRITES!
    ' by Andy Thomas 9/93
    ' Author not responsible for misuse or errors of any kind.
    ' Use of this program could, but should not, damage your disk
    ' or render data unusable.
    '$INCLUDE: 'QB.BI'
    ' QB must be started with the /L switch!
    DIM inreg AS RegTypeX, outreg AS RegTypeX
    CLS
    TYPE DiskPacketType
    Sector AS LONG ' DWORD - starting sector number
    CountWrite AS INTEGER ' WORD - Number of sectors affected
    TransAddres AS STRING * 4 ' DWORD - Location of data transfer
    ' Address
    END TYPE
    ' Note: Sector is a LONG while TransAddres is a string
    ' because we know Sector is going to be zero for this program.
    ' In other uses Sector would need to be made a string to avoid
    ' QuickBasic OVERFLOW errors.DIM DiskPacket AS DiskPacketType ' Disk Write Packet
    DIM DataStorage AS STRING * 512 ' string to read/write sectorPRINT "Place disk in drive." ' get drive to change
    PRINT "Enter drive letter:";
    DO
    Drive$ = UCASE$(INKEY$)
    LOOP UNTIL Drive$ <> ""
    PRINT Drive$
    PRINTDriveNumb = ASC(Drive$) - 65 ' drive number: A:=0, B:=1....
    inreg.cx = &HFFFF ' Read/Write Absolute Sector
    inreg.ax = DriveNumb ' Drive id
    DiskPacket.Sector = 0 ' start at sector 0
    DiskPacket.CountWrite = 1 ' load one sector'DWORD -- Seg:Off of DataStorage
    DiskPacket.TransAddres = CHR$(VARPTR(DataStorage) AND &HFF) +_
    CHR$(((VARPTR(DataStorage) AND &HFF00) \ 256) AND &HFF) +_
    CHR$((VARSEG(DataStorage) AND &HFF)) +_
    CHR$(((VARSEG(DataStorage) AND &HFF00) \ 256) AND &HFF)inreg.ds = VARSEG(DiskPacket) ' DS:BX = Disk write packet
    inreg.bx = VARPTR(DiskPacket)CALL INTERRUPTX(&H25, inreg, outreg) ' read disk sector' Get serial number from boot sector
    FOR I = &H2B TO &H28 STEP -1
    OldSerial$ = OldSerial$ + HEX$(ASC(MID$(DataStorage, I, 1)))
    IF LEN(OldSerial$) = 4 THEN OldSerial$ = OldSerial$ + "-"
    NEXT IPRINT " Old serial number:"; OldSerial$
    LOCATE 5, 1
    PRINT "Enter new serial Number:"' get user input for new serial number
    ' making sure only a valid serial number is entered
    Ptr = 0
    DashAdj = 0
    DO
    DO
    A$ = UCASE$(INKEY$)
    LOOP UNTIL (INSTR("0123456789ABCDEF" + CHR$(8), A$) > 0) AND_
    A$ <> ""
    IF A$ = CHR$(8) THEN ' backspace for corrections
    IF Ptr > 0 THEN
    Ptr = Ptr - 1
    NewSerial$ = LEFT$(NewSerial$, Ptr)
    ELSE
    NewSerial$ = ""
    END IF
    ELSE
    Ptr = Ptr + 1
    NewSerial$ = NewSerial$ + A$
    END IF
    LOCATE 5, 25
    PRINT " "LOCATE 5, 25
    PRINT LEFT$(NewSerial$, 4)
    IF Ptr > 4 THEN
    LOCATE 5, 29
    PRINT "-" + MID$(NewSerial$, 5, 8)
    END IF
    LOOP UNTIL Ptr = 8
    Ptr = 0' Convert NewSerial$ into numerical ASCII codes
    ' and save within DataStorage
    FOR I = &H2B TO &H28 STEP -1
    Sbyte = 0
    FOR J = 1 TO 2
    A$ = MID$(NewSerial$, J + Ptr, 1)
    IF ASC(A$) > 64 AND ASC(A$) < 71 THEN Adj = 55 ELSE Adj= 48
    Sbyte = (Sbyte * 16) + (ASC(A$) - Adj)
    NEXT J
    DEF SEG = VARSEG(DataStorage)
    POKE VARPTR(DataStorage) + I - 1, Sbyte
    Ptr = Ptr + 2
    NEXT I' Check to make sure new serial number was placed in
    ' correct location (this is a redundant check for safety)
    FOR I = &H2B TO &H28 STEP -1
    ChkSerial$ = ChkSerial$ + HEX$(ASC(MID$(DataStorage, I, 1)))
    IF LEN(ChkSerial$) = 4 THEN ChkSerial$ = ChkSerial$ + "-"
    NEXT I' confirm change
    PRINT
    PRINT " disk:"; Drive$
    PRINT " from serial number:"; OldSerial$
    PRINT "to new serial number:"; ChkSerial$
    PRINT "Confirm change: (Y/N)"
    DO
    A$ = UCASE$(INKEY$)
    LOOP UNTIL A$ = "Y" OR A$ = "N"
    IF A$ = "Y" THEN ' make the change
    DiskPacket.TransAddres = CHR$(VARPTR(DataStorage) AND &HFF) +_
    CHR$(((VARPTR(DataStorage) AND &HFF00) \ 256) AND &HFF) +_
    CHR$((VARSEG(DataStorage) AND &HFF)) +_
    CHR$(((VARSEG(DataStorage) AND &HFF00) \ 256) AND &HFF)inreg.ds = VARSEG(DiskPacket) ' DS:BX = Disk write packet
    inreg.bx = VARPTR(DiskPacket)CALL INTERRUPTX(&H26, inreg, outreg) ' write disk sector
    ELSE
    PRINT "Change Aborted."
    END IFEND' Methodology: The disk serial number is stored as a Double
    ' Word in the boot sector (sector zero) of every disk at
    ' location 27h. This program reads sector zero into a string,
    ' changes the dword value at offset 27h and writes the changed
    ' data back to sector zero. While this program should work, and
    ' has been tested on both hard drives and floppy disks, I
    ' suggest it only be used on floppy drives, as a error
    ' occurring while writing to sector zero on the hard drive
    ' could be disastrous.