I've tried to get the bios serial number using this code:

mov edx,0FEC71h
mov ebx,edx
invoke wsprintf,ADDR BiosNumber,ADDR strFormat, ebx
invoke SetWindowText,hEditName,ADDR BiosNumber

But this work only under Win98. Under Win2000 I get GPF (and program crashes). But I would like to use my program under Win2000 and I don't know how to solve this problem.

Thanks for any kind of help,
Posted on 2002-01-25 13:23:33 by stealthFIGHTER
Is BiosNumber big enough? You have to preserve ebx.
Posted on 2002-01-25 13:32:05 by rdaneel
NT (or Windows 2000 in this case) defaults to send a GPF when you are reading from an area protected by the OS. In the Case on Windows 9x you get no error when trying to read. (But of course you will get the GPF when trying to write to such an area).
Posted on 2002-01-25 17:54:31 by dxantos
Is there anwhere that has a list of memory addresses such as this
Posted on 2002-01-25 18:08:12 by Quantum
Posted on 2002-01-25 22:30:40 by rdaneel
The reason you can do this is that 9x maps the first meg of memory
as the first meg of memory in every win32 app. Which is a pretty
silly thing to do, really, and thus NT based windows doesn't do it.
Posted on 2002-01-26 03:36:55 by f0dder
Thank you all.

I've created little program in Delphi to get the Bios SN.
The code is:

BiosSerialNo := String(Pchar(Ptr($FEC71)));

And this work both in Win98 and Win2000.

But still I don't know how to do this to work in Win2000 :(. Please, can you help me? (if it is possible).

Again thanks very much,
Posted on 2002-01-26 04:23:50 by stealthFIGHTER
I'm totally confused about that stuff. why does

mov edx,0FEC71h
mov ebx,edx

read stuff from a memory location? AFAIK the first instruction just moves the number 0FEC71h to edx, and nothing else..

Posted on 2002-01-26 05:26:51 by NOP-erator
I guess he meant

mov edx,0FEC71h
mov ebx,[edx]

Otherwise he'd end up with edx/ebx both holding the number 0FEC71h...
Posted on 2002-01-26 06:08:38 by Qweerdy
I depends on his strFormat and the format of the serial number. I assume it's a string in memory (and %s is used in strFormat), so you have to pass the address of that string to wsprintf.
It could have been this as well:

invoke wsprintf,ADDR BiosNumber,ADDR strFormat, 0FEC71h

Posted on 2002-01-26 06:16:42 by Thomas
Here you can download BIOS AGENT http://www.unicore.com/biosagent/ba.exe

This useful prog can get the BIOS Sn, the Date, the version, ...
But I don't know if it's legal to disassemble it, but only to see what are the address.
If it's legal, don't do it...

(I downloaded it in order to upgrade my BIOS to see what version I had)
Posted on 2002-01-26 06:39:18 by Vom-bonjour:-()
From above reply I've optimized the code to this:

mov edx,0FEC71h
invoke wsprintf,ADDR BiosNumber,ADDR strFormat, edx
invoke SetWindowText,hEditName,ADDR BiosNumber

But still the result is GPF. I tried to comment the wsprintf function and no more GPF. Is it possible that I have some error in BiosNumber or strFormat?

I have:

BiosNumber db 100 dup(0),0
strFormat db "%s",0

Posted on 2002-01-26 11:31:37 by stealthFIGHTER
And what about 0FEC71h? What is in that memory address?
Posted on 2002-01-26 14:58:08 by CodeLover

BiosName [B]equ[/B] 0FE061h
BiosCopyright [B]equ[/B] 0FE091h
BiosDate [B]equ[/B] 0FFFF5h
BiosSN [B]equ[/B] 0FEC71h

Posted on 2002-01-26 16:23:15 by stealthFIGHTER

The site seems down :(

Posted on 2002-01-26 18:41:02 by Maverick
ive been interested in finding a way to get the serial number from the bios too. the only good info i have found was at code guru. someone wrote(forgot his name):
The processor serial nunmber can be retrieved using the CPUID instruction. There are at least two things you need to know about:

1. Not all IA processors have a hard-wired serial number, but only beginning w/ PIII processors. Refere to the "Intel Processor Identification and the CPUID Instruction", Order No 241618-017 from Intel for details.
2. Some BIOS implementations let you configutre the PC to inhibit the output of the CPU serial number.

With this information known, here is a piece of code that retrieves the CPU S/N, if available:

DWORD upper32Bits = 0L, middle32Bits = 0L, lower32bits= 0L;
CString s;
mov eax, 0x00
cmp eax, 3
jl not_supported
mov eax, 0x01
mov upper32Bits, eax
mov eax, 0x03
mov middle32Bits, edx
mov lower32bits, ecx
s.Format("%08Lu%08Lu%08Lu", upper32Bits, middle32Bits, lower32bits);
AfxMessageBox(s, MB_OK, NULL);

If the code returns 0000000..... then you either don't have a PIII CPU, or the S/N is inhibited. CPUID can be used to determine what CPU is present. The whole story on how this is to be done is described in the Intel Manual I was talking about (which is downloadable from Intel's web page, btw).

BTW: If your purpose to get the CPU S/N is to create some kind of software copy protection/licensing system, the safest approach is to use a hardware key.

this is good info. maybe you can make use of it.
Posted on 2002-01-26 18:44:48 by smurf
I'm don't get a GP fault here on windows ME

.model flat,stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib


strformat db 'BIOS NAME: %s',0
text db 10 dup(50)



invoke wsprintf, addr text, addr strformat, 0FE061h
invoke MessageBox, NULL, addr text, NULL, MB_OK
invoke ExitProcess,NULL
end start
Posted on 2002-01-26 19:15:52 by Quantum
Smurf: That snippet gets a unique identification number from a P4 Cpu, it has nothing to do with the BIOS serial number.

Here you can download BIOS AGENT http://www.unicore.com/biosagent/ba.exe

This uses a file KE386IO.SYS, which is some sort of driver to get BIOS information. This download also includes a COM program which directly accesses the information from DOS, but I dont have an apprioate dissasmbler to see how it does this either.
Posted on 2002-01-26 22:35:05 by huh
I think win32dasm can handle .com
Posted on 2002-01-26 23:34:23 by Quantum

I'm don't get a GP fault here on windows ME

Well DUH, WinMe = 9x. 9x = no protection.
Posted on 2002-01-27 10:26:05 by f0dder