windows注册表

前言

    注册表是Microsoft Windows中的一个重要的数据库,用于存储系统和应用程序的设置信息。早在Windows 3.0推出OLE技术的时候,注册表就已经出现。随后推出的Windows NT是第一个从系统级别广泛使用注册表的操作系统。但是,从Windows 95开始,注册表才真正成为Windows用户经常接触的内容,并在其后的操作系统中继续沿用至今。
由于注册表的功能非常强大,因此注册表对于病毒、木马来说是非常有利用价值的,而对于反病毒软件来说,注册表也是它需要加强守卫的地方,可以说,注册表是一个正义与邪恶的必争之地。
恶意程序在注册表中常见的操作有修改文件关联、增加系统启动项、映像劫持、篡改浏览器主页等。
数据结构:
    注册表由键(key,或称“项”)、子键(subkey,子项)和值项(value)构成。一个键就是树状数据结构中的一个节点,而子键就是这个节点的子节点,子键也是键。一个值项则是一个键的一条属性,由名称(name)、数据类型(datatype)以及数据(data)组成。一个键可以有一个或多个值,每个值的名称各不相同,如果一个值的名称为空,则该值为该键的默认值。
数据类型:
注册表的数据类型主要有以下五种:

显示类型 数据类型 说明
REG_SZ 字符串 文本字串
REG_BINARY 二进制数 不定长度的二进制值,以十六进制显示
REG_DWORD 双字 一个 32 位的二进制值,显示为 8 位的十六进制值
REG_MULTI_SZ 多字符串 含有多个文本值的字符串,此名来源于字符串间用 nul 分隔、结尾两个 nul
REG_EXPAND_SZ 可扩充字符串 含有环境变量的字符串

注册表的分支结构:
注册表有五个一级分支,下面是这五个分支的名称及作用:

名称 作用
HKEY_CLASSES_ROOT 存储Windows可识别的文件类型的详细列表,以及相关联的程序。
HKEY_CURRENT_USER 存储当前用户设置的信息。
HKEY_LOCAL_MACHINE 包括安装在计算机上的硬件和软件的信息。
HKEY_USERS 包含使用计算机的用户的信息。
HKEY_CURRENT_CONFIG 这个分支包含计算机当前的硬件配置信息。

通过注册表获取开机启动项

原理: 通过枚举注册表中的 “HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run\“子键下的键值项,取得跟随windows启动而启动的程序。

主要代码如下:

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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
VOID CManageRunDlg::InitRunList()
{
// 设置扩展样式
m_RunList.SetExtendedStyle(
m_RunList.GetExtendedStyle()
| LVS_EX_GRIDLINES // 有网格
| LVS_EX_FULLROWSELECT); // 选择单行

// 在ListCtrl中插入新列
m_RunList.InsertColumn(0, "NO.");
m_RunList.InsertColumn(1, "键值名称");
m_RunList.InsertColumn(2, "键 值");

/*
LVSCW_AUTOSIZE_USEHEADER:
列的宽度自动匹配为标题文本
如果这个值用在最后一列,列宽被设置为ListCtrl剩余的长度
*/
m_RunList.SetColumnWidth(0, LVSCW_AUTOSIZE_USEHEADER);
m_RunList.SetColumnWidth(1, LVSCW_AUTOSIZE_USEHEADER);
m_RunList.SetColumnWidth(2, LVSCW_AUTOSIZE_USEHEADER);
}

#define REG_RUN "Software\\Microsoft\\Windows\\CurrentVersion\\Run\\"

VOID CManageRunDlg::ShowRunList()
{
// 清空ListCtrl中的所有项
m_RunList.DeleteAllItems();

DWORD dwType = 0;
DWORD dwBufferSize = MAXBYTE;
DWORD dwKeySize = MAXBYTE;
char szValueName[MAXBYTE] = { 0 };
char szValueKey[MAXBYTE] = { 0 };

HKEY hKey = NULL;
LONG lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
REG_RUN, 0, KEY_ALL_ACCESS, &hKey);

if ( lRet != ERROR_SUCCESS )
{
return ;
}

int i = 0;
CString strTmp;

while ( TRUE )
{
// 枚举键项
lRet = RegEnumValue(hKey, i, szValueName,
&dwBufferSize, NULL, &dwType,
(unsigned char *)szValueKey, &dwKeySize);

// 没有则退出循环
if ( lRet == ERROR_NO_MORE_ITEMS )
{
break;
}

// 显示到列表控件中
strTmp.Format("%d", i);
m_RunList.InsertItem(i, strTmp);
m_RunList.SetItemText(i, 1, szValueName);
m_RunList.SetItemText(i, 2, szValueKey);

ZeroMemory(szValueKey, MAXBYTE);
ZeroMemory(szValueName, MAXBYTE);

dwBufferSize = MAXBYTE;
dwKeySize = MAXBYTE;

i ++;
}

RegCloseKey(hKey);
}

void CManageRunDlg::OnBtnAdd()
{
// TODO: Add your control notification handler code here
CRegAdd RegAdd;
RegAdd.DoModal();

// 判断输入是否完整
if ( strlen(RegAdd.m_szKeyName) > 0 &&
strlen(RegAdd.m_szKeyValue) > 0)
{
HKEY hKey = NULL;
LONG lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
REG_RUN, 0, KEY_ALL_ACCESS, &hKey);

if ( lRet != ERROR_SUCCESS )
{
return ;
}

RegSetValueEx(hKey, RegAdd.m_szKeyName, 0,
REG_SZ, (const unsigned char*)RegAdd.m_szKeyValue,
strlen(RegAdd.m_szKeyValue) + sizeof(char));

RegCloseKey(hKey);

ShowRunList();
}
else
{
AfxMessageBox("请输入完整的内容");
}
}

void CManageRunDlg::OnBtnDel()
{
// TODO: Add your control notification handler code here
POSITION pos = m_RunList.GetFirstSelectedItemPosition();
int nSelected = -1;

while ( pos )
{
nSelected = m_RunList.GetNextSelectedItem(pos);
}

if ( -1 == nSelected )
{
AfxMessageBox("请选择要删除的启动项");
return ;
}

char szKeyName[MAXBYTE] = { 0 };
m_RunList.GetItemText(nSelected, 1, szKeyName, MAXBYTE);

HKEY hKey = NULL;

LONG lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
REG_RUN, 0, KEY_ALL_ACCESS, &hKey);

RegDeleteValue(hKey, szKeyName);

RegCloseKey(hKey);

ShowRunList();
}

Reference