注册表监视,总结说来,可行的方法有以下四种,有其他做法,欢迎指出:
1.使用RegNotifyChangeKeyValue
这个函数可以监视注册表某一项及其子项的变化(包括添加、删除、修改等)。
此种方法的缺点:可以直接获取的注册表改变信息少之又少,如果是要获取比如修改项、修改时间、修改方式等,要通过其他方式来获取。
优点:平台兼容性好,98以后的系统基本都适用,与RegSaveKey、RegRestoreKey进行关联使用,实现注册表指定项的恢复。
//监视HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run项
#include <windows.h>
//定义一个监视注册表启动项的函数
int reg()
{
HANDLE hNotify;
HKEY hKeyx;
//DWORD dwRes;
hNotify = CreateEvent(NULL, //不使用SECURITY_ATTRIBUTES结构
FALSE, //不自动重置
TRUE, //设置初始状态
"RegistryNotify" //事件对象的名称
);
if (hNotify == 0)
{
MessageBox(NULL,"CreateEvent failed"," ",MB_OK);
ExitProcess(0);
}
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, //根键
"Software\\Microsoft\\Windows\\CurrentVersion\\Run", //子键
0, //reserved
KEY_NOTIFY, //监视用
&hKeyx //保存句柄
) != ERROR_SUCCESS)
{
CloseHandle(hNotify);
MessageBox(NULL,"RegOpenKeyEx failed"," ",MB_OK);
ExitProcess(0);
}
if (RegNotifyChangeKeyValue(hKeyx, //监视子键句柄
TRUE, //监视此项的子键
REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET, //监视增加或删除了子键,监视键值发生是否改变
hNotify, //接受注册表变化事件的事件对象句柄
TRUE //注册表变化前报告
) != ERROR_SUCCESS)
{
CloseHandle(hNotify);
RegCloseKey(hKeyx);
MessageBox(NULL,"RegNotifyChangeKeyValue failed"," ", MB_OK);
ExitProcess(0);
}
if (WaitForSingleObject(hNotify, INFINITE) != WAIT_FAILED)
{
MessageBox(NULL,"注册表有改动"," ",MB_OK);
}
CloseHandle(hNotify);
RegCloseKey(hKeyx);
return 0;
}
void main()
{
reg();
}
2.使用ETW
ETW的意思就是windows事件追踪。
此种方法的缺点:注册表事件的跟踪直到windows server 2008和vista版本才具有,在其他低版本中,这种方式不起作用。
3.使用wmi
这种方式优点:系统兼容性强
缺点:RegistryKeyChangeEvent、RegistryTreeChangeEvent、RegistryValueChangeEvent获取相关数据时,它们只能监视“HKEY_LOCAL_MACHINE”下的变动,其他根键下的变动监视不了。
4.使用detours.lib
detours.lib是微软出的一个库,他可以用来监视win32 API的调用。根据这个机制,也可以监视注册表的变动。只需要监视对注册表进行操作的win32 API就可以了。这个库的32位版本可以从微软官网上免费下载,而且有相关商业开发的限制,具体可以看微软的说明,64位版的,只能付费得到。适用到微软各系统。