注册表函数Hook失败

Home / C++ MrLee 2017-2-27 4833

最近在做一个功能的时候,发现无往不利的Detours在Hook几个注册表函数的时候,竟然失败了,但又不是完全地失败。
具体表现是,在程序最开始处Hook上RegQueryValueExW,在整个程序运行的过程中,只有一部分调用进行了我自己实现的方法中,而有一部分调用却没有进入。
前前后后猜了很多原因,一开始以为是调用了SHQueryValueEx、RegEnumRegQueryMultipleValues等其他方法,但是使用ApiMonitor却发现调用确实是发生在RegQueryValueExW,但是调用返回的数据却是空。这就奇怪了,因为从程序执行结果上来看,明明是获取到了正确的值。
当时找到合理的解决方案,于是使用了一个临时的也是最土的方案,在模块初始化前RegSetValue保存并修改注册表的值,在模块初始化完成以后,再恢复回原来的注册表值。由于修改的是IE的相关键值,因为被360等各种报。
昨天又用ApiMonitor尝试了一下,突然发现,原来注册表相关函数,竟然在Advapi32.DLL和Kernel32.dll两个系统模块里存在两套实现,如下图:

图1 注册表函数有两套实现


图1中分别显示了对Kernel32(上半部分)和对Advapi32(下半部分)中RegQueryValueExW函数的调用 。
程序里默认使用Detours对函数进行Hook的代码如下:
// 函数真实地址
LONG (WINAPI *PfnRegQueryValueExW)(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData) = &::RegQueryValueExW;
// Hook该方法
DetourAttach(&(PVOID&)PfnRegQueryValueExW,  HookRegQueryValueExW);
// Hook函数实现
LONG WINAPI HookRegQueryValueExW(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData)
{
    LONG lResult = PfnRegQueryValueExW(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData);
    return lResult;
}

 
在VS里调试时打开反汇编(Alt+8),单步跟踪,可以看到这样写的结果是,HookRegQueryValueExW函数里调用的其实是位于Advapi32里的_RegQueryValueExWStub@24方法,而该方法内部实现则是调用了Kernel32中的RegQueryValueExW方法。
到此问题原因找到了,只要让上述代码能Hook到Kernel32中函数即可。方法如下:
    PfnRegQueryValueExW = (LONG (__stdcall *)(HKEY,LPCWSTR,LPDWORD,LPDWORD,LPBYTE,LPDWORD))GetProcAddress(GetModuleHandle(L"Kernel32.dll"), "RegQueryValueExW");
    DetourAttach(&(PVOID&)PfnRegQueryValueExW,  HookRegQueryValueExW);
    PfnRegQueryValueExW = (LONG (__stdcall *)(HKEY,LPCWSTR,LPDWORD,LPDWORD,LPBYTE,LPDWORD))GetProcAddress(GetModuleHandle(L"advapi32.dll"), "RegQueryValueExW");
    DetourAttach(&(PVOID&)PfnRegQueryValueExW,  HookRegQueryValueExW);

刚查证了下MSDN,MSDN里写的竟然只有Advapi32,还是实践出真知啊。

本文链接:https://www.it72.com/11848.htm

推荐阅读
最新回复 (1)
  • RenaSchwing2914 2017-6-5
    引用 2
    你好,关于钩子函数有点问题想请教一下,方便的话加一下qq:2219468832,多谢了
返回