Reset BIOS Passwords - An Explanation and Tool
I’ve been seeing a lot of sites throwing around a “how to reset BIOS passwords” tip that revolve around using the DOS/Windows DEBUG tool. In case you haven’t seen it, it goes a little like this:
- Create a boot floppy/disc with the debug tool on it
- Type -o 70 2e
- Type -o 71 FF
- Type quit
- Reboot
Curious as to why this works? So was I, but none of the sites I saw included an explanation. So after some googling, I uncovered the nitty-gritty details.
The CMOS memory is actually accessible to the user for reading and writing. I’m not aware of a recent operating system that doesn’t restrict write access to the administrator/super user, but it is there nontheless. It contains a lot of information, such as the system time (direct access to the real-time clock), BIOS information, and CMOS data. With this knowledge, I would suggest taking a look at this link, which is a reference to how the CMOS memory is laid out. It is what I used to determine what the hex values being output were doing.
The -o option of debug just outputs a value to an io port. The CMOS memory is accessed through ports 70 and 71, which explains the first parameter of the steps above. The second part can be seen from the CMOS reference I linked to above - by latching the address 0×2e for writing, and then setting its value to 0xff, we are manually telling the CMOS that it has an invalid checksum. The behavior when this occurs is to revert to the default BIOS, a feature which is supported independent of operating system or processor architecture - ie, any AT/ATX motherboard will do this.
None of the sites list instructions for if you are a Linux user, and assume you’ll have access to the debug program. So, now understanding how this specific utilization of debug worked, I wrote my own version in C. It can be compiled using gcc, and is compatible with all *nix distributions - so add it to your rescue LiveCD toolkit, you never know when you’ll need it :)
Here is the source:
resetBIOS.c
#include <stdio.h > #include <stdlib.h> #include <unistd.h> #include <sys/io.h> /* Written by Robert Peaslee - www.robertpeaslee.com */ /* compile: gcc -o resetBIOS resetBIOS.c */ /* Run as superuser. */ int main() { /* Allow writing to ports 70 and 71 */ if( ioperm(0x70, 1, 1) || ioperm(0x71, 1, 1) ) { perror("Error setting write permissions"); printf("\n"); exit(1); } /* output 0x2e to port 70, which is the address where the * CMOS checksum is stored */ outb(0x2e, 0x70); /* Small sleep to allow the changes to take effect. */ usleep(100000); /* Tell the CMOS that the checksum is bad, forcing it to * load the default BIOS on reboot. */ outb(0xff, 0x71); /* Reset the port permissions to not be writeable */ if( ioperm(0x70, 3, 0)) { perror("Error restoring permissions"); printf("\n"); exit(2); } exit(0); }And if you only want the assembly specific portions without relying on external libraries:
out 70, 0x2e out 71, 0xff…but note you’ll have to add your own data/text sections and a main: entry point if you want to actually assemble it. Additionally, you’ll have to convert this to at&t syntax if you want to inline it in C code using the gcc compiler.
So there you have it - a full explanation of why it works, an example in C, and a complete reference of the layout of CMOS memory. If you still have questions, leave them in the comments!