注册表操作实验
目录
实现HKEY_LOCAL_MACHINE根键自启动项目的添加
实验设备:
目标系统:Windows
软件工具:VS2022/VC6
实验要求:
- 在程序中完成本机HKEY_LOCAL_MACHINE根键自启动项目的添加和查询。
- 要求有regedit编辑器查询结果截图,程序注释。
实验内容:
实验思路步骤:
Win32API参考手册http://www.yfvb.com/help/win32sdk/
1、先查资料详细了解注册表。
注册表是Windows操作系统中的一个重要数据库。其中包含了许多与系统相关的配置信息。Windows提供了一个编辑器方便我们编辑。可以按Win+R输入regedit来打开。或者直接去系统目录下寻找。
设置自启动的键值项有很多,这里仅仅介绍两种通用的,其他的我也没了解。
HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run
HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Run
可以看到上面两项唯一的区别就是根键(简称键)不同,子键是一样的。HKEY_CURRENT_USER与HKEY_LOCAL_MACHINE的区别是影响范围。前者影响只当前用户而后者是系统配置影响所有用户。只要里面添加入新的键值对就可以实现自启动。
进行如上图的写入操作后就可以实现开机自启动。可以看到我是在HKEY_CURRENT_USER根键下也就是说这个设置只会影响我目前的登陆账户。
2、API函数。
编写程序操作注册表就必须使用系统API函数,目前需要用到的函数有:RegOpenKeyEx、RegCreateKeyEx、RegSetKeyValue、RegDeleteKeyValue、RegCloseKey
创建指定的注册表项RegCreateKeyEx()
HKEY hKey--需要打开的主键的名称,LPCTSTR lpSubKey--需要打开的子键的名称,DWORD ulOptions--保留,设为0,REGSAM samDesired---安全访问标记,也就是权限,PHKEY phkResult---得到的将要打开键的句柄。
向注册表写入信息RegSetVauleEx()函数。
此函数中,需要传入的参数依次是,HKEY(RegOpenKeyEx函数中的最后一个参数)、键名、NULL、REG_SZ、启动程序的完整地址、值数据的大小。
检索信息--RegQueryVaule()函数。
相关函数在Win32API参考手册中查询:Win32API参考手册
3、注意:操作HKEY_LOCAL_MACHINE根键内容时需要管理员权限否则会失败,而HKEY_CURRENT_USER只需要默认权限就足够了。
具体实现过程
实现HKEY_LOCAL_MACHINE根键自启动项目的添加
Win+r打开命令提示符,输入regedit,进入注册表编辑器,在\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run下目前有如下项目。
实现添加自启动项目。 打开注册表使用到了函数GetModuleFileName()目的是得到本程序的路径。
添加到注册表的路径
使用system("pause")语句,因为需要管理员身份运行编译后的可执行文件,函数RegSetValueEx才能执行成功。也就是,编译完后,用管理员身份执行程序,没有这条语句的话便不能观察到运行结果,这样做的目的是方便观察。
写入项目
关闭注册表
注意这里用管理员身份运行程序,发现执行成功。并且在注册表中发现了新添加的项目。
HKEY_LOCAL_MACHINE根键自启动项目的查询
前面几步和启动过程差不多,但是这里的RegQueryValueEx()函数传递的参数为: hkey,"test",NULL,NULL,(LPBYTE)file,&lpdword。
找到则输出文件所在路径,
查看运行结果:
1、进入注册表,如下图,可以看到‘test”的数据为:
C:\Users\曾盈\Desktop\1.exe,程序执行结果和注册表查询结果一致。
源代码
添加:
#include <stdio.h>
#include <windows.h>
int main()
{
char file[100];//存放本程序的路径
GetModuleFileName(NULL,file,100);//得到本程序的路径
LPCTSTR regname = "Software\\Microsoft\\Windows\\CurrentVersion\\Run";
// LPCTSTR:指向常量字符的长指针,这里指向自启动添加到注册表的路径
HKEY hkey;
LONG ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, regname,0,KEY_ALL_ACCESS|KEY_WOW64_64KEY,&hkey);
//使用参数"KEY_ALL_ACCESS|KEY_WOW64_64KEY",因为操作位数不同。
if(ret == ERROR_SUCCESS)
printf("成功打开注册表编辑器!\n");
else
printf("未打开注册表编辑器,错误代码:%d\n",ret);
system("pause");
/*使用该语句,因为需要管理员身份运行编译后的可执行文件,函数RegSetValueEx才能执行成功。
也就是,编译完后,用管理员身份执行程序,没有这条语句的话
便不能观察到运行结果,这样做的目的是方便观察。
*/
ret = RegSetValueEx(hkey, "test", 0, REG_SZ,(BYTE *)file, strlen(file)+1);
//将项目文件放到本程序路径中
if(ret == ERROR_SUCCESS)
printf("成功创建项目 'test' \n");
else
printf("创建项目失败!错误代码:%d\n",ret);
RegCloseKey(hkey);//关闭注册表
system("pause");
return 0;
}
查询:
#include <stdio.h>
#include <windows.h>
#define buff 200
int main()
{
char file[buff];//file,用于接收该数据的缓冲区的指针
DWORD lpdword = buff;
LPCTSTR regname = "Software\\Microsoft\\Windows\\CurrentVersion\\Run";
HKEY hkey;
LONG ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,regname,0,KEY_READ|KEY_WOW64_64KEY,&hkey);
if(ret == ERROR_SUCCESS)
printf("成功打开注册表编辑器!\n");
else
printf("未打开注册表编辑器,错误代码:%d\n",ret);
ret = RegQueryValueEx(hkey,"test",NULL,NULL,(LPBYTE)file,&lpdword);
/*
查找与hkey关联名称为"test"的数据
最后一个参数指向的缓冲区的大小(以字节为单位)
*/
if(ret == ERROR_SUCCESS)
printf("%s\n",file);
else
printf("RegQueryValueEx()函数失败!错误代码:%d\n",ret);
RegCloseKey(hkey);//关闭注册表
return 0;
}