0%

程序安装NDIS6.0的方法(3)

前言

在上一篇文章中写的XP中安装 NDIS5 的方法,但是在WIN7中已经无法对 硬件签名检测 进行配置,
经过实验,在我们拥有正统签名的情况下,可以把签名导入到 受信任的发布者 中,再安装 NDIS6 时,
就不会再提示警告信息,但是如果在证书过期后再安装,就仍然会提示警告信息。

证书提取

这里以 netlwf.inf ndislwf.sys 两个文件为例,首先给sys驱动文件进行签名,然后使用签完名的
sys文件和inf文件生成cat文件,一般情况下签名工具提供生成cat文件的功能,最后把这个cat文件也按照
驱动签名的方式进行签名,注意cat文件只能签 SHA1 格式的签名。

我们可以先在cat文件上 右键->属性->数字签名 中查看证书,并使用 证书导入向导,把证书导入到某位置。
然后在运行中输入 certmgr.msc 打开 证书管理器 ,在需要导出的证书上 右键->所有任务->导出 来使用
证书导出向导 进行导出

证书管理器

注意导出证书选择 Base64 编码 X.509(.CER) 格式

证书格式

导出的证书可以使用记事本打开,格式大致如下

1
2
3
4
5
6
7
-----BEGIN CERTIFICATE-----
MIIFADCCA+igAwIBAgIMXuJStShYQgfuTm0vMA0GCSqGSIb3DQEBBQUAMFExCzAJ
BgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMScwJQYDVQQDEx5H
……
txuUsUQLbRGsx03zapv/+/t0tlFKIQrA4eK5L5y9QwCoT4SLrVgNYjEjOPXa8PYh
JCRoxfNoFZb269zfbDeveRSo/QAn89SSz18q+0+yShE5gLGb
-----END CERTIFICATE-----

代码导入证书

读取证书信息的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
CString GetCertInfo(IN CString &csCertPath)
{
CString csCert;
PCHAR pBuffer = NULL;
HANDLE hFile = INVALID_HANDLE_VALUE;
do
{
// 打开文件
hFile = CreateFile(csCertPath,
GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) break;
// 检查文件的大小
DWORD dwSize = GetFileSize(hFile, NULL);
if (dwSize == INVALID_FILE_SIZE) break;
// 检查是否超出100KB大小
if (dwSize > 102400) break;
// 申请缓冲区
pBuffer = (PCHAR)malloc(dwSize + sizeof('\0'));
if (pBuffer == NULL) break;
memset(pBuffer, 0, dwSize + sizeof('\0'));
// 读取文件内容
DWORD dwRet = 0;
if (!ReadFile(hFile, pBuffer, dwSize, &dwRet, NULL)) break;
// 保存读出的结果
csCert = pBuffer;
} while (0);
if (pBuffer != NULL) free(pBuffer);
if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);
return csCert;
}

导入证书的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
BOOL CACertInstall(IN CString csCertPath, IN CStringW csInfPath)
{
BOOL bRet = FALSE;
DWORD dwCertData = 0;
PBYTE pbCertData = NULL;
HCERTSTORE hStore = NULL;
PCCERT_CONTEXT pCertCtx = NULL;
do
{
// 读取证书信息
CString csCertInfo = GetCertInfo(csCertPath);
if (csCertInfo.IsEmpty()) break;
// 获取解码数据长度
if (!CryptStringToBinary(csCertInfo, csCertInfo.GetLength(),
CRYPT_STRING_BASE64HEADER, NULL, &dwCertData, NULL, NULL)) break;
// 申请内存空间
pbCertData = (PBYTE)malloc(dwCertData);
if (pbCertData == NULL) break;
memset(pbCertData, 0, dwCertData);
// 进行Base64解码
if (!CryptStringToBinary(csCertInfo, csCertInfo.GetLength(),
CRYPT_STRING_BASE64HEADER, pbCertData, &dwCertData, NULL, NULL)) break;
// 转换CERT_CONTEXT结构
pCertCtx = CertCreateCertificateContext(
PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, pbCertData, dwCertData);
if (pCertCtx == NULL) break;
// 打开证书路径(受信任的发布者)
hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0,
CERT_STORE_OPEN_EXISTING_FLAG | CERT_SYSTEM_STORE_LOCAL_MACHINE,
L"TrustedPublisher");
if (hStore == NULL) break;
// 安装证书
if (!CertAddCertificateContextToStore(
hStore, pCertCtx, CERT_STORE_ADD_NEW, NULL))
{
// 错误值不是已存在
if (CRYPT_E_EXISTS != GetLastError()) break;
}
// 安装NDIS网络组件
if (!InstallNetServiceVista(csInfPath)) break;
// 删除证书
CertDeleteCertificateFromStore(pCertCtx);
bRet = TRUE;
} while (0);
// 关闭句柄
if (pbCertData != NULL) free(pbCertData);
if (hStore != NULL) CertCloseStore(hStore, 0);
if (pCertCtx != NULL) CertFreeCertificateContext(pCertCtx);
return bRet;
}

安装网络组件

这里安装 NDIS6 只需要处理一个inf文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
BOOL InstallNetServiceVista(IN CStringW csInfPath)
{
if (csInfPath.IsEmpty()) return FALSE;
// 读取设备实例ID
CStringW csPnpID = InfGetPnpID(csInfPath);
if (csPnpID.IsEmpty()) return FALSE;
// 开始安装网络组件
INetCfg *pnc = NULL;
HRESULT hr = HrGetINetCfg(TRUE, L"NdisSetup", &pnc, NULL);
if (hr == S_OK)
{
// 把网络组件安装成服务
hr = HrInstallNetComponent(pnc, (PCWSTR)csPnpID,
&GUID_DEVCLASS_NETSERVICE, (PCWSTR)csInfPath);
HrReleaseINetCfg(pnc, TRUE);
// 有时候提示需要重启才生效,也算安装成功
// if (hr == NETCFG_S_REBOOT) return TRUE;
if (SUCCEEDED(hr)) return TRUE;
}
return FALSE;
}

卸载的代码与上一篇文章相同。