自启动技术-注册表

本文最后更新于:2021-08-11 下午

注册表方式实现自启动

实现开机自启动的方式有很多,其中修改注册表的方式是最为广泛的。

函数介绍

RegOpenKeyEx

打开一个指定的注册表键

1
2
3
4
5
6
7
LSTATUS RegOpenKeyExA(
HKEY hKey,
LPCSTR lpSubKey,
DWORD ulOptions,
REGSAM samDesired,
PHKEY phkResult
);

hKey:打开注册表项的句柄。该句柄由RegCreateKeyEx或RegOpenKeyEx函数返回,或者它可以是以下预定义键之一:

  • HKEY_CLASSES_ROOT
  • HKEY_CURRENT_CONFIG
  • HKEY_CURRENT_USER
  • HKEY_LOCAL_MACHINE
  • HKEY_USERS

lpSubKey:将打开的注册表子项的名称

ulOptions:保留,必须设置为0

samDesired:对指定键希望得到的访问权限进行的访问标记。这个参数可以是下列值得组合

含义
KEY_CREATE_LINK 准许生成符号键
KET_CREATE_SUB_KEY 准许生成子键
KEY_ENUMERATE_SUB_KEYS 准许生成枚举子键
KEY_EXECUTE 准许进行读操作
KEY_NOTIFY 准许更换通告
KEY_QUERY_VALUE 准许查询子键
KEY_ALL_ACESS 提供完全访问,它是上面数值的组合
KEY_READ 是KEY_QUERY_VALUE,KEY_ENUMERATE_SUB_KEYS,KEY_NOTIFY的组合
KEY_SET_VALUE 准许设置子键的数值
KEY_WRITE 是KEY_SET_VALUE、KET_CREATE_SUB_KEY的组合
KEY_WOW64_32KEY 表示64位系统中的应用程序应该在32位注册表试图上运行。32位系统会忽略该标志。
KEY_WOW64_64KEY 表示64位系统的应用程序应该在64位注册表试图上运行。32位系统上忽略该标志。

phkResult:指向一个变量的指针,该变量保存打开注册表键的句柄。如果不再使用返回的句柄,则调用RegClose来关闭它。

返回值:如果成功,返回0;失败返回一个非零的错误代码。

RegSetValueEx函数

在注册表项下设置指定值得数据和类型

1
2
3
4
5
6
7
8
LSTATUS RegSetValueExA(
HKEY hKey,
LPCSTR lpValueName,
DWORD Reserved,
DWORD dwType,
const BYTE *lpData,
DWORD cbData
);

hKey:指定一个已打开项的句柄,或一个标准项名。

lpValueName:指向一个字符串的指针,该字符串包含了与设置值的名称。若拥有该名称的值并不存在于指定的注册表中,则此函数会将其加入到该项。如果此值是NULL或指向空字符串,则此函数将会设置该项的默认值或未命名值得类型和数据。

Reserved:保留值,必须为0;

dwType:指定将存储的数据类型,该参数可以为以下值之一。

含义
REG_BINARY 任何形式的二进制数据
REG_DWORD 一个32位的数字
REG_DWORD_LITTLE_ENDIAN 一个格式为“低字节在前”的32位数字
REG_DWORD_BIG_ENDIAN 一个格式为“高字节在前”的32位数字
REG_EXPAND_SZ 一个以0结尾的字符串,该字符串包含环境变量(如“%PATH”)
REG_LINK 一个Unicode格式的带符号链接
REG_MULTI_SZ 一个以0结尾的字符串数组,该数组以链接两个0作为终止符
REG_ONE 未定义值类型
REG_RESOURCE_LIST 一个设备驱动器资源列表
REG_SZ 一个以0结尾的字符串

lpData:指向一个缓冲区,该缓冲区包含了为指定值名称存储的数据。

cbData:指定由lpData参数所指向的数据大小,单位是字节。

返回值:返回0表示陈成功;返回其他任何值都代表一个错误代码。

实现原理

对于Windows来说,提供了专门的开机自启动注册表,每次开机时,它都会在这个注册表键下遍历键值,以获取键值中的程序路径,并创建进程启动程序。所以要想实现注册表开机自启动,只需要在这个注册表键下添加想要设置自启动的程序路径就可以了。

这里用最常见的RUN键来进行设置,该键位置是[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run]和[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run

代码实现在HKEY_LOCAL_MACHINE下进行设置,这需要管理员运行权限。

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
#include "pch.h"
#include <iostream>
#include <Windows.h>

BOOL Register(char* lpszFileName, char* lpszValueName) {
HKEY hKey;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_WRITE, &hKey) != 0) {
printf("打开注册表失败\n");
return FALSE;
}
if (RegSetValueEx(hKey, lpszValueName, 0, REG_SZ, (BYTE*)lpszFileName, (lstrlen(lpszFileName) + 1)) != 0) {
printf("设置注册表值失败\n");
RegCloseKey(hKey);
return FALSE;
}
RegCloseKey(hKey);
return TRUE;
}

int main()
{
if (Register("C:\\Users\\b1ackie\\Desktop\\Register.exe", "b1ackie") == FALSE) {
printf("自启动失败\n");
system("pause");
exit(-1);
}
printf("自启动成功\n");
system("pause");
return 0;
}

打开程序,提示自启动成功,说明注册表设置成功。

用regedit命令查看注册表相关信息,可以成功看到当前的注册表信息,注意图中路径的不同,这是因为重定位的原因。

也可以使用火绒剑,如图可以看到启动项的信息,现在重启计算机,就会自动启动了。

参考

参考《Windows黑客编程技术详解》一书