📄 _cmos.cpp
字号:
// _____________________________________
// | |
// | 文件描述 |
// ___________|_____________________________________|___________
//
// 文件名:_CMOS.CPP
// 作者:阿卓
// 内容:清除和解码CMOS密码的C++程序代码段。
// 声明:本文件及其相关文档内容可以自由使用、修改和传播,并可用
// 于任何商业和非商业目的。对于使用本文件及其相关文档内容
// 而产生的任何后果,作者概不负责。
//
// 技术要点之一:
// 使用了在WINDOWS 9X和NT环境下直接读写端口的方法。由于
// WINDOWS(特别是WINDOWS NT)对硬件直接访问设置了限制,使得端
// 口的读写难以实现。于是就寻寻觅觅,终于在互联网上觅得一共
// 享软件名曰:NTPort Library。此软件提供WINDOWS 9X/NT环境下
// 的直接端口读写而不需要写DDK程序。使用本程序时,需要将
// ntport.dll拷到system(NT:system32)目录下,如果是NT,还要将
// zntport.sys拷贝到system32目录下。
//
// 技术要点之二:
// CMOS密码解码算法。
// CMOS密码的生成算法是:将用户输入的密码字符串中的字符c按先
// 后顺序重复这样的操作(sum是最终存储到CMOS中的一个16位值,
// 初值为0):
// sum = sum + c;
// sum 按位循环左移2位(最后一个字符不左移)
// 我的解密算法是:
// 找到一个合适的c(c的低2位与sum的低2位相同)
// sum减去c
// sum右移2位
// 重复上述过程,递归求解,遇到无解时回溯,直至sum的值
// 落到一个合适的范围之内(可显示的字符范围之内)
//
// 当前版本:v1.4
// 最后更新日期:11/7/2001
//
// 版本历史:
// v1.0
// 算法初步成型,探测结果为纯数字,没有优化到可键入字符集
// 中,未采用NTPort Library,运行于MS-DOS方式下。
// v1.1
// 将探测结果优化到可键入的字符集中,并移植到WINDOWS 9X环境
// 下。
// v1.2
// 增加直接清除功能。
// v1.3
// 采用NTPort Library,使得程序能在NT架构环境中能操作端口。
// v1.4
// 当前版本,优化探测结果,得到的密码更容易键入。增加详细注
// 释。
//
// _______________________文件描述结束__________________________
// 这是MFC程序需要的头文件,以支持预编译头文件
#include "stdafx.h"
// 这是NTPort Library的头文件
// 要使用这个库,需要在Project/Settings.../Link中添加ntport\ntport.lib
#include "ntport\\ntport.h"
// ___________
// ____| Clear() |____________________________________________
// 功能:向CMOS的一些端口输出一些无意义数据,使得CMOS的校验和出
// 错,导致CMOS自动载入缺省设置,恢复到无密码状态。
// 参数详解:无参数
// 返回值:无
// _____________________________________________________________
void Clear(void)
{
// 还记得使用DEBUG来破CMOS密码的日子吗?这个原理是一样的
Outport(0x70, 0x21);
Outport(0x71, 0x20);
// 这是个额外方案,以确保清除成功
Outport(0x70, 0x2e);
Outport(0x71, 0x00);
Outport(0x70, 0x2f);
Outport(0x71, 0x00);
}
// ____End of Clear()___________________________________________
// _________________
// ____| GetPortData() |______________________________________
// 功能:从CMOS的0x1c和0x1d端口读入一个16位的加密状态的密码数据。
// 可能不同的BIOS有不同的端口,这两个端口适用于普通的AWARD
// BIOS,这是本软件为普通AWARD BIOS版的原因,也是导致解密不
// 成功或者探测的密码无效之类问题的原因,可以在将来版本制作
// 多种解决方案。
// 参数详解:无参数
// 返回值:一个16位的加密状态的CMOS密码数据
// _____________________________________________________________
unsigned int GetPortData(void)
{
unsigned int Data;
unsigned char Data1, Data2;
Outport(0x70, 0x1c);
Data1 = (unsigned char)Inport(0x71);
Outport(0x70, 0x1d);
Data2 = (unsigned char)Inport(0x71);
Data = (Data2 << 8) | Data1;
return Data;
}
// ____End of GetPortData()_____________________________________
// 这是一个字符表,排在前面的字符比较容易键入,所以先试探此类字符
// 这是易键入性优化的关键所在。
static char CharSet[] = {
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'`', '-', '=', '[', ']', '\\', ';', '\'', ',', '.', '/',
'~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '{', '}', '|', ':', '"', '<', '>', '?'
};
// _____________
// ____| MinChar() |__________________________________________
// 功能:内部使用函数,它返回在字符集中最小的字符。
// 参数详解:无参数
// 返回值:在字符集中最小的字符
// _____________________________________________________________
static char MinChar(void)
{
int i;
char Min = 127;
for(i = 0; i < sizeof(CharSet); i ++)
if(CharSet[i] < Min)
Min = CharSet[i];
return Min;
}
// ____End of MinChar()_________________________________________
// _____________
// ____| MaxChar() |__________________________________________
// 功能:内部使用函数,它返回在字符集中最大的字符。
// 参数详解:无参数
// 返回值:在字符集中最大的字符
// _____________________________________________________________
static char MaxChar(void)
{
int i;
char Max = 0;
for(i = 0; i < sizeof(CharSet); i ++)
if(CharSet[i] > Max)
Max = CharSet[i];
return Max;
}
// ____End of MaxChar()_________________________________________
// _________________
// ____| IsInCharSet() |______________________________________
// 功能:内部使用函数,它判断某个字符是否在字符集内。
// 参数详解:
// char c
// 待判断的字符
// 返回值:
// 0 - 不在字符集内
// 1 - 在字符集内
// _____________________________________________________________
static int IsInCharSet(char c)
{
int i;
for(i = 0; i < sizeof(CharSet); i ++)
if(CharSet[i] == c)
return 1;
return 0;
}
// ____End of IsInCharSet()_____________________________________
// ____________
// ____| Decode() |___________________________________________
// 功能:核心解码函数,递归,回溯。
// 参数详解:
// unsigned int SourceCode
// 16位的加密状态的CMOS密码数据
// unsigned char *Password
// 存储解码结果的缓冲区,注意:结果是倒序存储的
// 返回值:
// -1 - 解码失败
// 0 - 解码成功
// _____________________________________________________________
int Decode(unsigned int SourceCode, unsigned char *Password)
{
unsigned int i, TempCode, Mask = 0x03;
unsigned char LastTwoBits;
if(SourceCode < (unsigned int)MinChar())
// 所剩SourceCode不合法,回溯
return -1;
if(SourceCode < (unsigned int)MaxChar())
if(IsInCharSet(SourceCode))
{
// 所剩SourceCode合法,探密完成!
*Password = SourceCode;
return 0;
}
// 取出SourceCode的低2位
LastTwoBits = SourceCode & Mask;
for(i = 0; i < sizeof(CharSet); i ++)
{
// 若低2位相同才继续探测
if(((CharSet[i] ^ LastTwoBits) & Mask) == 0)
{
*Password = CharSet[i];
TempCode = (SourceCode - CharSet[i]) >> 2;
if(Decode(TempCode, Password + 1) == 0)
return 0;
}
}
//向前探索失败,回溯
return -1;
}
// ____End of Decode()__________________________________________
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -