关于Ring3层的注册表监控
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于Ring3层的注册表监控相关的知识,希望对你有一定的参考价值。
最近一直想做远程操作的注册表,将客户端的注册表发送到主控端,遇到两个问题:
1.不能每次点击TreeControl都是一次请求的发送,太浪费资源。
2.在客户端的注册表监控效果也不是很好。(驱动不稳定,只想用Ring3层)
第一个问题比较好解决,在主控端加一个缓存结构就Ok,但是第二个问题还有一些问题。
常用的注册表监控一般都会使用钩子,Hook有关注册表操作的函数。但是这种方法是针对进程
而言,如果要监控全局,就要对每个进程Inject,这基本不现实。
一个使用DETOUR库的RegQueryValueExW函数
1 DETOUR_TRAMPOLINE(LONG APIENTRY Real_RegQueryValueExW(HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD), RegQueryValueExW); 2 LONG APIENTRY Mine_RegQueryValueExW( 3 HKEY hKey, 4 LPCWSTR lpValueName, 5 LPDWORD lpReserved, 6 LPDWORD lpType, 7 LPBYTE lpData, 8 LPDWORD lpcbData) 9 { 10 LONG nRet; 11 __try{ 12 nRet = Real_RegQueryValueExW(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData); 13 if(!HOOK_RegQueryValueEx) 14 return nRet; 15 if(GetCurrentProcessId() == ExplorerPID) 16 return nRet; 17 if(GetCurrentProcessId() == RegMonPID) 18 return nRet; 19 if((PID == 0) || ((GetCurrentProcessId() == PID) && (PID>0)) ) 20 { 21 if(nRet != ERROR_SUCCESS) 22 return nRet; 23 COPYDATASTRUCT data; 24 PARAMS params = {0}; 25 params.PID = GetCurrentProcessId(); 26 params.hKey = hKey; 27 28 if(lpValueName == NULL || /*lpType == NULL ||*/ lpData == NULL || lpcbData == NULL) 29 return nRet; 30 31 memcpy(params.buffer1, lpValueName, wcslen(lpValueName)*2); 32 33 if(lpType == NULL) 34 params.type = 0; 35 else 36 params.type = *lpType; 37 38 if(*lpcbData == 0) 39 { 40 return nRet; 41 } 42 else if(*lpcbData>1024) 43 { 44 memcpy(params.buffer2, lpData, 1024); 45 params.cbBuffer2 = 1024; 46 } 47 else 48 { 49 memcpy(params.buffer2, lpData, *lpcbData); 50 params.cbBuffer2 = *lpcbData; 51 } 52 53 params.result = nRet; 54 55 data.cbData = sizeof(PARAMS); 56 data.lpData = ¶ms; 57 data.dwData = TYPE_RegQueryValueExW; 58 SendMessage(hWnd, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&data); 59 } 60 61 }__finally{ 62 }; 63 return nRet; 64 }
要在Ring3全局监控注册表的变化,只能使用RegNotifyChangeKeyValue微软提供的接口,但得不到具体的改变。
MSDN提供的例子:
1 #include <windows.h> 2 #include <tchar.h> 3 #include <stdio.h> 4 5 //void main(int argc, char *argv[]) 6 void __cdecl _tmain(int argc, TCHAR *argv[]) 7 { 8 DWORD dwFilter = REG_NOTIFY_CHANGE_NAME | 9 REG_NOTIFY_CHANGE_ATTRIBUTES | 10 REG_NOTIFY_CHANGE_LAST_SET | 11 REG_NOTIFY_CHANGE_SECURITY; 12 13 HANDLE hEvent; 14 HKEY hMainKey; 15 HKEY hKey; 16 LONG lErrorCode; 17 18 // Display the usage error message. 19 if (argc != 3) 20 { 21 _tprintf(TEXT("Usage: notify [HKLM|HKU|HKCU|HKCR|HCC] [<subkey>]\\n")); 22 return; 23 } 24 25 // Convert parameters to appropriate handles. 26 if (_tcscmp(TEXT("HKLM"), argv[1]) == 0) hMainKey=HKEY_LOCAL_MACHINE; 27 else if(_tcscmp(TEXT("HKU"), argv[1]) == 0) hMainKey=HKEY_USERS; 28 else if(_tcscmp(TEXT("HKCU"), argv[1]) == 0) hMainKey=HKEY_CURRENT_USER; 29 else if(_tcscmp(TEXT("HKCR"), argv[1]) == 0) hMainKey=HKEY_CLASSES_ROOT; 30 else if(_tcscmp(TEXT("HCC"), argv[1]) == 0) hMainKey=HKEY_CURRENT_CONFIG; 31 else 32 { 33 _tprintf(TEXT("Usage: notify [HKLM|HKU|HKCU|HKCR|HCC] [<subkey>]\\n")); 34 return; 35 } 36 37 // Open a key. 38 lErrorCode = RegOpenKeyEx(hMainKey, argv[2], 0, KEY_NOTIFY, &hKey); 39 if (lErrorCode != ERROR_SUCCESS) 40 { 41 _tprintf(TEXT("Error in RegOpenKeyEx (%d).\\n"), lErrorCode); 42 return; 43 } 44 45 // Create an event. 46 hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 47 if (hEvent == NULL) 48 { 49 _tprintf(TEXT("Error in CreateEvent (%d).\\n"), GetLastError()); 50 return; 51 } 52 53 // Watch the registry key for a change of value. 54 lErrorCode = RegNotifyChangeKeyValue(hKey, 55 TRUE, 56 dwFilter, 57 hEvent, 58 TRUE); 59 if (lErrorCode != ERROR_SUCCESS) 60 { 61 _tprintf(TEXT("Error in RegNotifyChangeKeyValue (%d).\\n"), lErrorCode); 62 return; 63 } 64 65 // Wait for an event to occur. 66 _tprintf(TEXT("Waiting for a change in the specified key...\\n")); 67 if (WaitForSingleObject(hEvent, INFINITE) == WAIT_FAILED) 68 { 69 _tprintf(TEXT("Error in WaitForSingleObject (%d).\\n"), GetLastError()); 70 return; 71 } 72 else _tprintf(TEXT("\\nChange has occurred.\\n")); 73 74 // Close the key. 75 lErrorCode = RegCloseKey(hKey); 76 if (lErrorCode != ERROR_SUCCESS) 77 { 78 _tprintf(TEXT("Error in RegCloseKey (%d).\\n"), GetLastError()); 79 return; 80 } 81 82 // Close the handle. 83 if (!CloseHandle(hEvent)) 84 { 85 _tprintf(TEXT("Error in CloseHandle.\\n")); 86 return; 87 } 88 }
暂时先这样解决吧,有什么好的方法再多多积累。
以上是关于关于Ring3层的注册表监控的主要内容,如果未能解决你的问题,请参考以下文章