Read hard disk serial number

Source: Internet
Author: User
 
Function getidediskserialnumber (scsiid: integer): string; // disk ID type tsrbiocontrol = packed record headerlength: ulong; Signature: array [0 .. 7] of char; Timeout: ulong; controlcode: ulong; returncode: ulong; Length: ulong; end; srb_io_control = tsrbiocontrol; psrbiocontrol = ^ tsrbiocontrol; tideregs = packed record Bytes: byte; // used for specifying smart "commands ". bsectorcounregulatory: 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; ideregs = tideregs; pideregs = ^ tideregs; tsendcmdinpa Rams = packed record cbuffersize: DWORD; // buffer size in bytes irdriveregs: tideregs; // structure with drive register values. bdrivenumber: byte; // physical drive number to send command to (0, 1, 2, 3 ). breserved: array [0 .. 2] of byte; // reserved for future expansion. dwreserved: array [0 .. 3] of DWORD; // for future use. bbuffer: array [0 .. 0] of byte; // input buffer. end; sendcmdinparams = tsendcm Dinparams; outputs = ^ tsendcmdinparams; tidsector = packed record wgenconfig: word; wnumcyls: word; wreserved: word; wnumheads: word; wbytespertrack: word; keywords: 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; character: word; wdoublewordio: word; wcapabilities: word; wreserved1: word; wpiotiming: word; wdmatiming: word; WBS: word; wnumcurrentcyls: word; wnumcurrentheads: word; wnumcurrentsectorspertrack: word; ulcurrentsectorcapacity: ulong; wmultsectorstuff: word; Future: ulong; wsingleworddma: word; wmultiworddma: word; breserved: array [0 .. 127] of byte; end; pidse Ctor = ^ tidsector; const ide_id_function = $ EC; identify_buffer_size = 512; cost = $0007c088; cost = $0004d008; cost = $001b0501; datasize = sizeof (tsendcmdinparams) -1 + identify_buffer_size; buffersize = sizeof (srb_io_control) + datasize; w9xbuffersize = identify_buffer_size + 16; var hdevice: thandle; cbbytesreturned: DWORD; pindata: PS Cmdinparams; poutdata: pointer; // psendcmdinparams; Buffer: array [0 .. buffersize-1] of byte; srbcontrol: tsrbiocontrol absolute buffer; 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; begin result: = ''; fillchar (buffer, Buffers Ize, #0); If win32platform = ver_platform_win32_nt then begin // Windows NT, Windows 2000 // get SCSI port handle hdevice: = createfile (pchar ('//. /SCSI '+ inttostr (scsiid) +': '), generic_read or generic_write, file_1__read or file_1__write, nil, open_existing, 0, 0); If hdevice = invalid_handle_value then exit; try srbcontrol. headerlength: = sizeof (srb_io_control); system. move ('scsidisk', srbco Ntrol. signature, 8); srbcontrol. timeout: = 2; srbcontrol. length: = datasize; srbcontrol. controlcode: = callback; pindata: = psendcmdinparams (pchar (@ buffer) + sizeof (srb_io_control); poutdata: = pindata; with pindata ^ do begin cbuffersize: = identify_buffer_size; bdrivenumber: = 0; with irdriveregs do begin bfeaturesreg: = 0; bsectorcounregulatory: = 1; bsectornumberreg: = 1; bcyllow Reg: = 0; bcylhighreg: = 0; bdriveheadreg: = $ A0; bcommandreg: = ide_id_function; end; if not deviceiocontrol (hdevice, ioctl_scsi_miniport, @ buffer, buffersize, @ buffer, buffersize, cbbytesreturned, nil) Then exit; finally closehandle (hdevice); end else begin // Windows 95 osr2, Windows 98 hdevice: = createfile ('//. /smartvsd', 0, 0, nil, create_new, 0, 0); If hdevice = invalid_handle_val UE then exit; try pindata: = psendcmdinparams (@ buffer); poutdata: = pchar (@ pindata ^. bbuffer); with pindata ^ do begin cbuffersize: = bytes; bdrivenumber: = 0; with irdriveregs do begin bfeaturesreg: = 0; bsectorcounreg: = 1; Response: = 1; bcyllowreg: = 0; bcylhighreg: = 0; bdriveheadreg: = $ A0; bcommandreg: = ide_id_function; end; if not deviceiocontrol (hdevice, dfp_re Outputs, pindata, sizeof (tsendcmdinparams)-1, poutdata, w9xbuffersize, blocks, nil) Then exit; finally closehandle (hdevice); end; with pidsector (pchar (poutdata) + 16) ^ do begin changebyteorder (sserialnumber, sizeof (sserialnumber); setstring (result, sserialnumber, sizeof (sserialnumber); end; Result: = trim (result); end; getidediskserialnumber (0) during use; assume that the hard disk is connected to the 0 # IDE.
Top
 
  Reply:Imageonline (no rent)() Credit: 100 2003-004 12: 56: 41z Score: 0
 
 
?
I. What is the serial number of the hard disk? The serial number of the hard disk is set by the manufacturer during production and exists in the control chip of the hard disk. It does not change with the partitioning or formatting status of the hard disk, like the number of physical cylinders and sectors of a hard disk, it is an operating system-independent feature. The serial number can only be read using the I/O command of the hard disk controller, and cannot be modified using the conventional method. ---- It should be noted that the serial number of the hard disk exists physically, which is fundamentally different from the serial number automatically generated in the Partition Boot Sector after the hard disk is formatted as fat or FAT32. The serial number generated by formatting is a logical number. The serial number generated by each formatting is different and can be manually modified. 2. Why should I read the serial number of the hard disk? The only reason I can think of is the anti-copy protection of the software. This is determined by the uniqueness and read-only nature of the hard disk serial number. The general practice is to read the serial number when the software is installed on the hard disk, save it after some appropriate changes, the software installed on the hard disk can be compared according to the current hard disk serial number and the serial number stored during installation. If the two are found to be inconsistent, it indicates that the software is illegally copied to the actual hard disk for running. ---- Because the manufacturer has ensured the uniqueness of the serial number and the user cannot modify it, This method basically guarantees the legal benefits of the software, many DOS software in China have adopted this method. By the way, these software often uses the BIOS of the motherboard With the serial number of the hard disk for protection. The reason is that, on the one hand, it is to increase the encryption strength, on the other hand, that is, the disadvantage of this method, that is, some hard disks, such as some models of Sankey, do not have serial numbers. 3. How to read the serial number of the hard disk-the serial number of the hard disk can only be read through direct operations on the hard disk controller, that is, the hard disk controller can only be operated using the cpu I/O command, the read method is as follows in the C language program: static int waitide () {int al; while (Al = Indium (0x1f7)> = 0x80); return Al ;} static void readide () {int al; int I; Word PW [256]; waitide (); outp (0x1f6, 0xa0); Al = waitide (); if (Al & 0x50 )! = 0x50) return; outp (0x1f6, 0xa0); outp (0x1f7, 0xec); Al = waitide (); If (Al & 0x58 )! = 0x58) return; for (I = 0; I <256; I ++) PW [I] = inpw (0x1f0 );} ---- the above program actually reads all the information stored in the hard disk controller, and the serial number is only part of it, which is located in the 10 to 20 elements of the PW [] array mentioned above, that is, within the 10 words starting from & PW [10], each word occupies two bytes, occupying 20 bytes in total. Because the high and low bytes of each word are not intel-ordered when the serial number is stored, that is, its high bytes are in the front and the low bytes are in the back, so you need to reverse the high and low bytes during use to obtain the complete serial number. 4. Why can't I use the read method mentioned above in Windows 95? In the DOS era, I used this method to read the serial number of the hard disk and use it for anti-copy protection, even in Windows 3. X is no problem, but with the popularization of Windows 95 (and Windows 98, Windows 9x), the limitations of this method are also revealed, because in Windows 9x, this method does not read any information at all. ---- In Windows 9x, the I/O commands used in the above Code are restricted as privileged commands. So what are privileged commands? ---- First of all, let's briefly review the protection mechanism of Intel 80386 and above CPUs. After 80386, the CPU is divided into four privileged levels (namely, ring 0-3) for the operating system to use, the highest level of Ring 0 and the lowest level of Ring 3. The allowed CPU instruction sets are reduced from 0 to 3. The commands used only at ring 0 are special commands. Executing privileged commands at other levels may cause CPU exceptions. ---- Now back to Windows 9x, Windows 95/98 only uses two CPU-level privileges, namely, ring 0 and ring 3. In these two levels, Windows Virtual Machine management, various drivers (VxD) run on Ring 0, other applications, even the three main modules, kernel, GDI, and user, run on the Ring Level 3. Programs at this level obtain the required services from the ring 0 module through CPU exceptions. Windows9x provides its own exception handling program, so it can provide corresponding services. ---- On the Ring 3 level, the I/O commands for operating the hard disk controller are not available, so the Code listed in section 3 is executed to waitide () the cause is that the exception handler of Windows 9x always causes in 0x1f7 to return 0xff (in fact, even if you skip this wait ). 5. How should I read the serial number in Windows 9x? How can I bypass this layer of protection in Windows 9x to operate the hard disk controller to read the serial number? The easy solution is to write a virtual device driver, VxD, because VxD runs on the highest privilege level of the Ring 0 on the CPU. At this level, all commands are available. This method can be directly read. In fact, I have already written such a VxD, and the effect is the same as that in DOS. ---- However, this method has three problems (or disadvantages): ---- first, writing VxD is much more complicated than writing a common Windows 9x program, more operating system knowledge is required. Programmers need to be familiar with DDK and related kernel technologies of Windows 9X. Today, many programmers of VB and Delphi are almost unfamiliar with Windows 9x sdks, not to mention programming with DDK. From this perspective, it is difficult to use the VxD writing method. (Interested readers can refer to tutorial for "VxD getting started tutorial") ---- second, because VxD runs at ring 0 of the CPU, it actually runs at the core level of the Windows 9x operating system, therefore, any small negligence is enough to cause Windows 9x to crash. Without a doubt, this will increase system instability, especially the VxD written by inexperienced programmers, which is more prone to problems. ---- Third, the main purpose of reading the hard disk serial number is to protect the software, that is, to prevent illegal copying. If a VxD is attached, it will obviously prompt others how to crack it. ---- In fact, we can use VxD Technology in common applications to perform operations. This will involve how to execute RING 0 code at the application level (Ring 3. 6. How to execute code with a privilege level 0 from an application-the only technical difficulty with this method is to directly switch from ring 3 to ring 0 using a CPU exception. If this problem is solved, the rest of the work will be very simple. It is worth mentioning that because the technology switches the CPU to the ring 0 level for running, the operation that can be done is not just as easy as reading the hard disk serial number. ---- To solve this problem, we need to look back at the CPU protection mode and interrupt processing method. ---- In real mode, the interrupt vector table is located at 0: 0 of the memory address. When the interrupt occurs, the CPU searches for the interrupt entry position from the table whether it is a hard interrupt or a soft interrupt, and execute the corresponding interrupt processing program. ---- In the protection mode (including the v86 mode), the interrupt vector table does not have to be placed at in the physical memory. In fact, the representation like "" has also undergone a fundamental change, in the original sense, the segment address no longer exists, instead of the segment selector. Correspondingly, the interrupt vector table is replaced by the Interrupt Descriptor Table (IDT), which means that when an interrupt or exception occurs (the exception only exists in the protection mode, you can simply treat it as an interruption), the CPU looks for IDT, and then runs the corresponding processing program based on the retrieved entry address. ---- For details about this part, refer to the Technical Manual of CPU 80386 (and above. ---- As we can see from the above, although the content and method of the query have changed, the principle has not changed. If you want to modify the interrupt entry, the only thing you need to modify is the IDT. Even better, the interrupt (or exception) handler runs on the highest privilege RING 0 of the CPU. This is not enough. We also need to have write permission on the IDT, fortunately, in Windows 95/98, IDT is located in the shared area above 0c0000000 of the memory, and this area is visible to all processes, the IDT is writable to all processes, which makes it possible to execute the Ring 0-level code from ring 3. 7. How to Use the Ring 0 code to read the serial number of the hard disk ---- according to the above analysis, the specific method can be summarized as follows: ---- first, the system IDT needs to be obtained, which can be used with the sidt command in one step, this command is not restricted by Level 3 of privilege; ---- then, select an interrupt (exception) and modify its entry in IDT (for the modification method, see IDT format ), point it to our own processing program. Although all items in the IDT table can be used, I suggest using interrupt 3, which is used by the debugger and is usually useless. ---- At last, an exception occurs when the interrupt is executed. The method is to directly execute code INT 3. Of course, executing this command on ring3 will inevitably lead to CPU exceptions. Therefore, our processing program can be easily controlled. ---- Once the CPU has the highest privilege level of control, the interrupt handler can perform any operations that normally cannot be performed on ring3, including reading the hard disk serial number. ---- To be more specific, put the program code listed in section 3 above in this article into the interrupt handler. ---- This method is used to read the complete C Language Program of the hard disk serial number, which is not listed in this article due to space limitations. 8. Conclusion ---- In fact, the purpose of this article is not entirely to read the serial number of the hard disk (after all, this stuff is not very useful, and some hard disks, such as Samsung's 32543a, do not have a serial number at all ), the main purpose is to try to obtain the Ring 0 privilege from ring3. ---- It should be noted that this method cannot be used in Windows NT. The reason is that the IDT cannot be modified under WindowsNT. Reply to: Cobi (small New International) (9:47:39) 0 point post: Doctor Network (http://www.helpwork.net) Q & A area -- Delphi Moderator: kongfang (bnnay) Source: 210.28.70.67 title: how to obtain the serial number of the hard disk-program list statement: it cannot be used for ntunit unit1; interfaceuseswindows, messages, sysutils, classes, graphics, controls, forms, dialogs, stdctrls; typetform1 = Class (tform) button1: tbutton; label0: tlabel; label1: tlabel; label2: tlabel; label3: tlabel; label4: tlabel; Procedure button1click (Sender: tobject ); private {private Declarations} public {public declarations} end; consthookexceptionno = 5; errno: integer = 0; varpw: array [0 .. 255] of word; // PW [256]; idtr_1: array [0 .. 5] of byte; // Save the Interrupt Descriptor Table register oldexceptionhook: DWORD; // Save the original interrupt entry address idebase: word; selectdisk: integer; varform1: tform1; Implementation
Top
 
  Reply:Sysu (dead tree)() Credit: 198 2003-03-04 13: 00: 26z Score: 0
 
 
?
function GetHardDiskSerieNumber: string;var  sysinfo:tsysteminfo;  lpRootPathName           : PChar; // address of root directory of the file system  lpVolumeNameBuffer       : PChar; // address of name of the volume  nVolumeNameSize          : DWORD; // length of lpVolumeNameBuffer  lpVolumeSerialNumber     : DWORD; // address of volume serial number  lpMaximumComponentLength : DWORD; // address of system's maximum filename length  lpFileSystemFlags        : DWORD; // address of file system flags  lpFileSystemNameBuffer   : PChar; // address of name of file system  nFileSystemNameSize      : DWORD; // length of lpFileSystemNameBufferbegin  lpRootPathName:=pchar('c:/');  windows.GetSystemInfo(sysinfo);  GetMem( lpVolumeNameBuffer, MAX_PATH + 1 );  GetMem( lpFileSystemNameBuffer, MAX_PATH + 1 );  nVolumeNameSize     := MAX_PATH + 1;  nFileSystemNameSize := MAX_PATH + 1;  Windows.GetVolumeInformation(  lpRootPathName,                                 lpVolumeNameBuffer,                                 nVolumeNameSize,                                 @lpVolumeSerialNumber,                                 lpMaximumComponentLength,                                 lpFileSystemFlags,                                 lpFileSystemNameBuffer,                                 nFileSystemNameSize );  Result := Copy( IntToHex( lpVolumeSerialNumber, 0 ), 1, 4 ) + '-' +            Copy( IntToHex( lpVolumeSerialNumber, 0 ), 5, 4 );end;
Top
 
  Reply:Imageonline (no rent)() Credit: 100 2003-004 13: 02: 43z Score: 0
 
 
?
procedure TForm1.Button1Click(Sender: TObject);varSerialNum: DWord;A, B: DWord;VolumeSerialNumber: string ;Key: string ;beginKey:='';if GetVolumeInformation(PChar('C:/'),Nil, 0, @SerialNum, A, B, Nil, 0) thenVolumeSerialNumber := IntToHex(HiWord(SerialNum), 4) +IntToHex(LoWord(SerialNum), 4);Key := VolumeSerialNumber ;Label1.Caption := Key ;end;

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.