精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>C/C++>>硬件、外设相关>>前几天有人问CPU序列号问题,现在找到了

主题:前几天有人问CPU序列号问题,现在找到了
发信人: wenbobo(灌了拂衣去)
整理人: wenbobo(2002-12-06 23:29:45), 站内信件
Cracking Open The Pentium III

How do I read the new Pentium III serial number?

Why are so many people upset about having a serial number within the processor? I think it’s a fine place for a centralized number for security, identification, software protection or licensing. For software protection and licensing, unique numbers are not hard to generate -- especially if the machine has a network card (that will provide 48 totally unique bits for starters). Add to this the variety of other random information that you can grab from a user’s machine (such as the vendor ID of the video card, the version of Windows and the serial number of the motherboard) and you’ll get a unique number! Internet games could make use of a persistent, unique number, for instance for online identification. I think it makes perfect sense for a computer to have a unique ID, and the processor is an ideal place to put it. Anyway, other machines have had unique IDs for years. Let’s see how to read it.

To detect the presence of the serial number, you issue the CPUID instruction with EAX=1 to read the feature flags, and check the SN bit (bit 18) in EDX. If the bit is clear, the machine has no serial number or it has been disabled. And once disabled, it cannot be re-enabled without resetting the processor. The serial number, if present, is read with the CPUID instruction when EAX =3. The lower 64 bits of the 96-bit serial number are returned in EDX:ECX, and the top 32 bits comes from the processor signature (ECX = bits 0 to 31, EDX = bits 32 to 63). The function below detects the presence of the serial number: 

bool DetectSerialNumber()
{


bool found_sn;
_asm
{


pushfd
pop eax // get EFLAGS into eax
mov ebx,eax // keep a copy
xor eax,0x200000 // toggle CPUID bit
push eax
popfd // set new EFLAGS
pushfd
pop eax // EFLAGS back into eax


// have we changed the ID bit?
xor eax,ebx 

je NO_SERIAL_NUM

// we could toggle the bit so CPUID
// is present
mov eax,1

cpuid // get processor features

// check the serial number bit
test edx,1<<18

jz NO_SERIAL_NUM
mov found_sn,1
jmp DONE
NO_SERIAL_NUM:
mov found_sn,0
DONE:



}

return found_sn;

}

The next function below actually reads the serial number, but make sure you have verified that the serial number is present before you use this function. An illegal instruction will result if the serial number is not present or disabled due to the illegal operation (EAX=3) with CPUID. The source files DETECT.CPP and DETECT.H contain code that will read the serial number.

void ReadSerialNumber(DWORD* serial)
{

DWORD t,m,b;
_asm
{


mov eax,1
cpuid

// top 32 bits are the processor
// signature bits
mov t,eax

// A new CPUID code for the
// Pentium III
mov eax,3


cpuid
mov m,edx
mov b,ecx

}

// copy the locals into the pointer variables passed in
serial[0] = b;
serial[1] = m;
serial[2] = t;

}

Intel recommends displaying the serial number to the user as six groups of four hexidecimal digits, (i.e., xxxx-xxxx-xxxx-xxxx-xxxx-xxxx.).

If you have a multi-processor machine, then you also have multiple serial numbers. What’s worse is that the serial number may be disabled on just one of the processors, which could introduce some really hard-to-find bugs. For example, the function to detect the serial number could indicate that there is a serial number on one processor, but due to context switching, the function to read the serial number might actually run on the other processor, whose number has been disabled. This will cause an exception that is really difficult to track down. I recommend detecting the features of each processor individually by running the detection functions from a thread that has its affinity set to a single processor. This guarantees reliability by forcing all code to run on the same physical processor. (See the DETECTEXAMPLE.CPP source file for an example of this technique.)

How do I disable the Pentium III serial number?

The easiest way to disable the serial number is to get the serial number utility tool from Intel’s web page, and run this application. This utility causes all traces of the serial number to disappear. If you run this tool from within Windows, it may be too late to prevent the number from being read, as a driver could read it during your machine’s boot up. To completely disable the serial number, it must be run from the BIOS during initial boot up, and at the time of writing only a few BIOSes provided this feature. If you have either an Intel SE440BX or an SE440BX-2 motherboard, you should ensure that the BIOS version is either 4S4EB0X1.86A.0031.P11 or 4S4EB2X0.86A.0017.P10, respectively (these numbers are displayed on the initial boot screen). These lastest BIOSes support the Pentium III and feature the ability to disable the serial number at boot up. They also support the latest clock speeds (550Mhz in the case of the SE440BX-2). BIOS updates for any Intel motherboard are available from the Intel web page at http://www.intel.com/design/motherbd/genbios.htm.

To write code to disable the serial number, you simply set bit 21 of Model Specific Register (MSR) 119h, but as with all system registers, you have to be at ring zero to accomplish this. Additionally, remember to disable the serial number for every processor in the system, if you are running a machine with more than one processor. It is very unlikely that a game or other application will ever want to disable the serial number, however.




----
█◣◢█
◢█◤
◢█◤
█◤◥█  

[关闭][返回]