⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 _cmos.cpp

📁 侦测、破解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 + -