user-0 提问: hook不到注册表编辑器中的操作

回复:
user: user-0
content: @zwfgdlc  您28楼的代码咋用啊？regedit.exe 怎么用您的dll？

user: user-1
content: HOOK  简单易懂的HOOK     链接: http://pan.baidu.com/s/1hs7aTV2 密码: y98m

user: user-0
content: @zwfgdlc 我的hook dll和测试程序都是64位的  代码如下： 感兴趣的可以试试  #include "stdafx.h" #include "HookRegApi.h"  #ifdef _DEBUG #define new DEBUG_NEW #endif  #define  UM_WNDTITLE WM_USER+100 // #define CODE_LEN 12  #pragma data_seg(".Share") 	HWND g_hWnd=NULL; 	HHOOK hhk=NULL;	 	HINSTANCE hInst=NULL; #pragma data_seg() #pragma comment(linker, "/section:.Share,rws")  HANDLE hProcess=NULL; BOOL bIsInjected=FALSE;  typedef LONG (WINAPI *RegCKeyExA)( 					  HKEY hKey,                // handle to an open key 					  LPCTSTR lpSubKey,         // address of subkey name 					  DWORD Reserved,           // reserved 					  LPTSTR lpClass,           // address of class string 					  DWORD dwOptions,          // special options flag 					  REGSAM samDesired,        // desired security access 					  LPSECURITY_ATTRIBUTES lpSecurityAttributes, 					  // address of key security structure 					  PHKEY phkResult,          // address of buffer for opened handle 					  LPDWORD lpdwDisposition   // address of disposition value buffer 					  );   RegCKeyExA oldRCKExA=NULL;  FARPROC pfMsgBoxExA=NULL;  BYTE OldCodeExA[5];  BYTE NewCodeExA[5];   LONG WINAPI MyRegCreateKeyExA( 					  HKEY hKey,                // handle to an open key 					  LPCTSTR lpSubKey,         // address of subkey name 					  DWORD Reserved,           // reserved 					  LPTSTR lpClass,           // address of class string 					  DWORD dwOptions,          // special options flag 					  REGSAM samDesired,        // desired security access 					  LPSECURITY_ATTRIBUTES lpSecurityAttributes, 					  // address of key security structure 					  PHKEY phkResult,          // address of buffer for opened handle 					  LPDWORD lpdwDisposition   // address of disposition value buffer 					  );  void HookOn()  {  	 ASSERT(hProcess!=NULL); 	 DWORD dwTemp=0,dwOldProtect,dwRet=0; 	 SIZE_T dwWrite;   	 VirtualProtectEx(hProcess,pfMsgBoxExA,5,PAGE_READWRITE,&dwOldProtect);  	 dwRet=WriteProcessMemory(hProcess,pfMsgBoxExA,NewCodeExA,5,&dwWrite); 	 if (0==dwRet||0==dwWrite) 	 { 		 TRACE("write error"); 	 } 	 VirtualProtectEx(hProcess,pfMsgBoxExA,5,dwOldProtect,&dwTemp); }  void HookOff() {  	 ASSERT(hProcess!=NULL); 	DWORD dwOldProtect;  	::VirtualProtect(oldRCKExA, CODE_LEN, PAGE_EXECUTE_READWRITE, &dwOldProtect); 	memcpy(oldRCKExA, OldCodeExA, CODE_LEN); 	::VirtualProtect(oldRCKExA, CODE_LEN, dwOldProtect, NULL);  }   void Inject() {    if (!bIsInjected)  {  	 bIsInjected=TRUE;  	oldRCKExA=(RegCKeyExA)::GetProcAddress(GetModuleHandle(TEXT("Advapi32.dll")), "RegCreateKeyExW");  	DWORD dwTemp=0,dwOldProtect,dwRet=0; 	::VirtualProtect(oldRCKExA, CODE_LEN, PAGE_EXECUTE_READWRITE, &dwOldProtect); 	memcpy(OldCodeExA, oldRCKExA, CODE_LEN); 	memset(oldRCKExA, 0x90, CODE_LEN); 	/* 	mov rax, FakeCreateProcessInternal 	jmp rax 	*/ 	*(LPWORD)oldRCKExA = 0xb848; 	*(INT64*)((INT64)oldRCKExA+2) = (INT64)MyRegCreateKeyExW; 	*(LPWORD)((INT64)oldRCKExA+10) = 0xe0ff; 	::VirtualProtect(oldRCKExA, CODE_LEN, dwOldProtect, NULL);  } }  LONG WINAPI MyRegCreateKeyExA( 					  HKEY hKey,                // handle to an open key 					  LPCTSTR lpSubKey,         // address of subkey name 					  DWORD Reserved,           // reserved 					  LPTSTR lpClass,           // address of class string 					  DWORD dwOptions,          // special options flag 					  REGSAM samDesired,        // desired security access 					  LPSECURITY_ATTRIBUTES lpSecurityAttributes, 					  // address of key security structure 					  PHKEY phkResult,          // address of buffer for opened handle 					  LPDWORD lpdwDisposition   // address of disposition value buffer 					  ) { 	char str[1000]={0};   	 		DWORD d= GetCurrentProcessId(); 		sprintf_s(str, 1000,"ExA item: HKEY_CURRENT_USER\\%s \nRegedit is being Created !\nPID: %ld",lpSubKey, d);   		::MessageBoxA(NULL,str,"warning",MB_ICONWARNING);  	return 0; }  // CHookRegApi BEGIN_MESSAGE_MAP(CHookRegApi, CWinApp) END_MESSAGE_MAP()  CHookRegApi::CHookRegApi() { 	 }  CHookRegApi theApp; BOOL CHookRegApi::InitInstance() { 	CWinApp::InitInstance();  	hInst=AfxGetInstanceHandle(); 	DWORD dwPid=::GetCurrentProcessId(); 	hProcess=::OpenProcess(PROCESS_ALL_ACCESS,0,dwPid);  	Inject();// 	return TRUE; }  LRESULT CALLBACK MouseProc(int nCode,      // hook code 			WPARAM wParam,  // message identifier 			LPARAM lParam   // mouse coordinates 			) { 	if (nCode==HC_ACTION) 	{ 		::SendMessage(g_hWnd,UM_WNDTITLE,wParam,(LPARAM)(((PMOUSEHOOKSTRUCT)lParam)->hwnd)); 	} 	return CallNextHookEx(hhk,nCode,wParam,lParam); } LRESULT CALLBACK KeyboardProc(int nCode,      // hook code 				WPARAM wParam,  // message identifier 				LPARAM lParam   // mouse coordinates 				) { 	if (nCode==HC_ACTION) 	{ 		::SendMessage(g_hWnd,UM_WNDTITLE,wParam,lParam); 	} 	return CallNextHookEx(hhk,nCode,wParam,lParam); }  BOOL WINAPI StartHook(HWND hWnd) { 	g_hWnd=hWnd; 	hhk=::SetWindowsHookEx(WH_MOUSE,MouseProc,hInst,0); 	if (hhk==NULL) 	{ 		return FALSE; 	}  	else 	{ 		return TRUE; 	} }  VOID WINAPI StopHook() { 	HookOff();  	if (hhk!=NULL) 	{ 		UnhookWindowsHookEx(hhk); 		FreeLibrary(hInst); 	} }  int CHookRegApi::ExitInstance() { 	HookOff();  	return CWinApp::ExitInstance(); }

user: user-2
content: 完整代码,你直接用这个试试   #include <stdio.h> #include <tchar.h> #include <Windows.h> #include <ntdll.h> #include <Shlwapi.h> #include <strsafe.h>  #pragma comment(lib, "shlwapi.lib") #pragma comment(linker, "/export:SetHook=SetHook") #pragma comment(linker, "/export:UnHook=UnHook")  HHOOK hHook; HMODULE hDll;  LRESULT CALLBACK GetMsgProc( 	_In_  int code, 	_In_  WPARAM wParam, 	_In_  LPARAM lParam) { 	return CallNextHookEx(hHook, code, wParam, lParam); }  extern "C" int __stdcall SetHook() { 	hHook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, hDll, 0); 	return hHook ? 1 : 0; }  extern "C" int __stdcall UnHook() { 	return UnhookWindowsHookEx(hHook); }  LPVOID pfnNtSetValueKey = 0; typedef NTSTATUS (__fastcall* FNNTSETVALUEKEY)( 	IN HANDLE KeyHandle, 	IN PUNICODE_STRING ValueName, 	IN ULONG TitleIndex OPTIONAL, 	IN ULONG Type, 	IN PVOID Data, 	IN ULONG DataSize);  LPVOID x64HookNtApi(LPCTSTR lpszDll, LPCSTR lpszFunc, LPVOID FakeFunc, int Len = 16) { 	DWORD dwOldProtect = 0; 	LPVOID pfn = GetProcAddress(GetModuleHandle(lpszDll), lpszFunc); 	if (!pfn) 	{ 		return 0; 	}  	VirtualProtect(pfn, Len, PAGE_EXECUTE_READWRITE, &dwOldProtect); 	LPVOID OldCode = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Len); 	memcpy(OldCode, pfn, Len); 	memset(pfn, 0x90, Len); 	memcpy(pfn, "\xff\x25\x00\x00\x00\x00", 6); 	*(PINT64)((INT64)pfn + 6) = (INT64)FakeFunc; 	FlushInstructionCache(GetCurrentProcess(), pfn, Len); 	VirtualProtect(OldCode, Len, PAGE_EXECUTE_READWRITE, &dwOldProtect);  	return OldCode; }   PUNICODE_STRING pKeyName; TCHAR szMsg[2048] = { 0 };  NTSTATUS __fastcall HookNtSetValueKey( 	IN HANDLE KeyHandle, 	IN PUNICODE_STRING ValueName, 	IN ULONG TitleIndex OPTIONAL, 	IN ULONG Type, 	IN PVOID Data, 	IN ULONG DataSize) { 	ULONG Len = 2048; 	if (NtQueryObject(KeyHandle, ObjectNameInformation, pKeyName, Len, &Len) == 0) 	{ 		switch (Type) 		{ 		case REG_DWORD: 			StringCchPrintf(szMsg, _countof(szMsg), TEXT("KeyName:%s  ValueName:%s  Values:%d DataType:REG_DWORD"), pKeyName->Buffer, ValueName->Buffer, *(int*)Data); 			break; 		case REG_QWORD: 			StringCchPrintf(szMsg, _countof(szMsg), TEXT("KeyName:%s  ValueName:%s  Values:%lld DataType:REG_QWORD"), pKeyName->Buffer, ValueName->Buffer, *(PLONGLONG)Data); 			break; 		case REG_SZ://字符串类型数据 			StringCchPrintf(szMsg, _countof(szMsg), TEXT("KeyName:%s  ValueName:%s  Values:%s DataType:REG_SZ"), pKeyName->Buffer, ValueName->Buffer, Data); 			break; 		default: 			break; 		} 		OutputDebugString(szMsg); 	}  	return ((FNNTSETVALUEKEY)pfnNtSetValueKey)(KeyHandle, ValueName, TitleIndex, Type, Data, DataSize); }   BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved) { 	if (dwReason == DLL_PROCESS_ATTACH) 	{ 		DisableThreadLibraryCalls(hModule); 		TCHAR szModuleFile[MAX_PATH] = { 0 }; 		hDll = hModule;  		GetModuleFileName(NULL, szModuleFile, _countof(szModuleFile)); 		LPTSTR lpszFileName = PathFindFileName(szModuleFile); 		if (StrCmpI(lpszFileName, TEXT("regedit.exe")) == 0) 		{ 			pfnNtSetValueKey = x64HookNtApi(TEXT("NTDLL.DLL"), "NtSetValueKey", HookNtSetValueKey); 			pKeyName = (PUNICODE_STRING)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 2048); 			return 1; 		} 	}  	if (dwReason == DLL_PROCESS_DETACH) 	{ 		UnhookWindowsHookEx(hHook); 		HeapFree(GetProcessHeap(), 0, pKeyName); 	} 	return 1; }

user: user-3
content: 权限问题？ 请判断每个函数调用的返回值。

user: user-2
content: 引用 19 楼 wangcg123 的回复:@zwfgdlc 哦，这种方法我知道，能实现； 我想知道Setwindowhookex-勾子方案，能勾住我自己小程序的Reg api调用，为什么勾不住“注册表编辑器“中的操作？ “注册表编辑器“它不使用RegCreatekeyA/RegCreateKeyW/RegCreatekeyExA/RegCreateKeyExW 这些API 吗？？？？ 64位系统,在运行里打开注册表编辑器进程regedit.exe是64位的进程,你的的DLL是32位的,不能加载到64位进程,要把DLL编译成64位DLL才可以

user: user-0
content: @zwfgdlc 哦，这种方法我知道，能实现； 我想知道Setwindowhookex-勾子方案，能勾住我自己小程序的Reg api调用，为什么勾不住“注册表编辑器“中的操作？ “注册表编辑器“它不使用RegCreatekeyA/RegCreateKeyW/RegCreatekeyExA/RegCreateKeyExW 这些API 吗？？？？

user: user-2
content: 引用 17 楼 wangcg123 的回复:@zwfgdlc  您的代码我能编译，但如何使用呢？ 编译成64位DLL,然后注入到64位的regedit.exe进程

user: user-0
content: @zwfgdlc  您的代码我能编译，但如何使用呢？

user: user-2
content: WIN7 x64测试通过, 缺少ntdll.h文件自己去搜索   #include <stdio.h> #include <tchar.h> #include <Windows.h> #include <ntdll.h> #include <Shlwapi.h> #include <strsafe.h>  #pragma comment(lib, "shlwapi.lib")  LPVOID pfnNtSetValueKey = 0; typedef NTSTATUS (__fastcall* FNNTSETVALUEKEY)( 	IN HANDLE KeyHandle, 	IN PUNICODE_STRING ValueName, 	IN ULONG TitleIndex OPTIONAL, 	IN ULONG Type, 	IN PVOID Data, 	IN ULONG DataSize);  LPVOID x64HookNtApi(LPCTSTR lpszDll, LPCSTR lpszFunc, LPVOID FakeFunc, int Len = 16) { 	DWORD dwOldProtect = 0; 	LPVOID pfn = GetProcAddress(GetModuleHandle(lpszDll), lpszFunc); 	if (!pfn) 	{ 		return 0; 	}  	VirtualProtect(pfn, Len, PAGE_EXECUTE_READWRITE, &dwOldProtect); 	LPVOID OldCode = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Len); 	memcpy(OldCode, pfn, Len); 	memset(pfn, 0x90, Len); 	memcpy(pfn, "\xff\x25\x00\x00\x00\x00", 6); 	*(PINT64)((INT64)pfn + 6) = (INT64)FakeFunc; 	FlushInstructionCache(GetCurrentProcess(), pfn, Len); 	VirtualProtect(OldCode, Len, PAGE_EXECUTE_READWRITE, &dwOldProtect);  	return OldCode; }   PUNICODE_STRING pKeyName; TCHAR szMsg[2048] = { 0 };  NTSTATUS __fastcall HookNtSetValueKey( 	IN HANDLE KeyHandle, 	IN PUNICODE_STRING ValueName, 	IN ULONG TitleIndex OPTIONAL, 	IN ULONG Type, 	IN PVOID Data, 	IN ULONG DataSize) { 	ULONG Len = 2048; 	if (NtQueryObject(KeyHandle, ObjectNameInformation, pKeyName, Len, &Len) == 0) 	{ 		switch (Type) 		{ 		case REG_DWORD://整数类型数据 			break; 			StringCchPrintf(szMsg, _countof(szMsg), TEXT("KeyName:%s  ValueName:%s  Values:%d"), pKeyName->Buffer, ValueName->Buffer, Data); 		case REG_SZ://字符串类型数据 			StringCchPrintf(szMsg, _countof(szMsg), TEXT("KeyName:%s  ValueName:%s  Values:%s"), pKeyName->Buffer, ValueName->Buffer, Data); 			break; 		default: 			break; 		} 		 		OutputDebugString(szMsg); 	}  	return ((FNNTSETVALUEKEY)pfnNtSetValueKey)(KeyHandle, ValueName, TitleIndex, Type, Data, DataSize); }   BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved) { 	if (dwReason == DLL_PROCESS_ATTACH) 	{ 		DisableThreadLibraryCalls(hModule); 		TCHAR szModuleFile[MAX_PATH] = { 0 };  		GetModuleFileName(NULL, szModuleFile, _countof(szModuleFile)); 		LPTSTR lpszFileName = PathFindFileName(szModuleFile); 		if (StrCmpI(lpszFileName, TEXT("regedit.exe")) == 0) 		{ 			pfnNtSetValueKey = x64HookNtApi(TEXT("NTDLL.DLL"), "NtSetValueKey", HookNtSetValueKey); 			pKeyName = (PUNICODE_STRING)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 2048); 			return 1; 		} 	}  	return 1; }

user: user-4
content: 引用 3 楼 wangcg123 的回复:@paschen     哪些部分，dll路径我加上绝对路径也不行（system32、syswow64都试过了）  你用64位程序试下

user: user-0
content: 原始目标是记录本机上哪些进程什么时间修改过注册表？ win7 64位操作系统 我的程序目前只能拦截32位程序的注册表API调用， 64位程序的API 调用发现不了

user: user-3
content: 逆向regmon？

user: user-0
content: @paschen     哪些部分，dll路径我加上绝对路径也不行（system32、syswow64都试过了）

user: user-5
content: 注册表管理器调用的是： RegQueryValueExW RegSetValueExW 之类，确认是否Hook这些API

user: user-5
content: 运行32位的注册表编辑器来测试 C:\Windows\SysWOW64\regedit.exe

user: user-0
content: 我32和64都编译出来了，也能监控我自己其它测试程序的注册表API调用了， 就是监控不了微软的注册表编辑器里的操作，why？？？？？谁能解惑

user: user-3
content: 引用 1 楼 zhao4zhong1 的回复:WinAPIOverride32 这个好象支持64位 inline hook

user: user-0
content: 我把汇编部分代码换掉了，换成了按字节内存拷贝，现在能监控我测试exe的API 调用了，但依然监控不到注册表编辑器中的修改？？？  能指点下吗，我用setwindowHookEx(WH_MOUSE_LL作注入，回调函数没干啥事, 日志里看在鼠标移动到注册表编辑器中时，是触发了的，也就是dll加载了

user: user-0
content: @paschen  您好，请问您那有x64版本的例子吗? dll注入+hook， 监控所有进程的某API 调用？ 非常感谢 wangchuanguo@163.com