日前遇到一件事:WebBrowser中的网页会用到一个“大众”ActiveX控件,为了保证兼容性以及和其它程序互不干扰,我们采用这样一种方案:
1. 我们的软件会自带该控件;
2. 如果系统中已注册有该控件的话,我们不用会我们的控件进行覆盖注册;
3. 不管怎么样,我们的程序都只会加载我们自带的控件。
 
要做到第3条,显然要HOOK控件位置有关的注册表项。因为之前在做播放器时使用过同样的手段来处理媒体解码器,所以其实并没有什么难度。但事实上却差点阴沟里翻船。
 
我一定确定以及肯定的是,我需要HOOK的只有几个API:RegQueryValue、RegQueryValueEx、RegGetValue。用ZwQueryKey还原一下路径,如果路径是"CLSID\{GUID}\InprocServer32",把我们自带控件的路径返回即可。
 
然而,程序实际运行却并没有预期效果,程序虽然执行到了API的替代函数中,但是结果却要么加载到其它版本的控件,要么加载失败。
 
修正了数遍代码,把捕获条件放宽收窄N次,尝试HOOK其它一些API之后,换了N台机器,检查了N遍注册表后,问题依旧。
 
跟踪了无数遍,程序始终会执行到API的替代函数中,也返回了正确结果。但是在procemon的监测里,却又始终能看到返回注册表中真实值的注册表读取操作。
我花了一些时间后,意识到:在API替代品中就已经被我处理掉的请求,应该是不会进入到Procemon纪录中的。也就是说,procemon中监控到的请求,跟被我HOOK到的请求,其实是来自完全不同的调用路径。但是查看procemon纪录中这些操作的调用堆栈,无一不是来自已经被我HOOK了的API。
 
这说明了一个更加难以解释的问题:同样的API,同样的参数(路径),为什么有些能够HOOK到,有些则HOOK不到?
 
为此又回过头去检查和修正捕获操作的代码,但毫无收获。
 
最后告诉我答案的来自美工使用旧版本程序的一个错误报告:XP系统下提示Advapi32.dll找不到某注册表API。我突然想起,procemon纪录中的调用堆栈中的API,似乎并不是Advapi32.dll模块的,而是Kernel32.dll。马上查询了一下,确认程序链接的都是Advapi32.dll,而procemon中监控到的,也确认属于Kernel32.dll。
 
答案呼之欲出,用depends看了一下Lernel32.dll,果然如此,一模一样的API,一个不少!!!也就是说,我HOOK了advapi32.dll的API,但程序却明修栈道,暗渡陈仓,调用了一两次advapi32.dll中的API,最后却从Kernel32.dll绕道去拿了数据。
 
虽然问题找到了,但是依然还是不太明白。以前HOOK注册表并没有出现过类似问题,显然,那些程序里注册表调用都走的是Advapi32.dll,MSDN中所有的注册表API也都注明在Advapi32.dll里,那为什么这一次却到了Kernel32.dll,唯一能想到的解释,或许这IE内核有关。但这一点就无力求证了。
 
最后,虽然没有文档告诉我Kernel32.dll中注册表函数的原型,但尝试用Advapi32.dll中的原型HOOK了一下,程序正常。可见是一个牌子,两套班子。
 
Tip:RegGetValue要求Vista以上或XP64bit。

advapi32.dll kernel32.dll 中的两套注册表API的更多相关文章

  1. 入侵检测中需要监控的注册表路径研究(Windows Registry Security Check)

    1. Windows注册表简介 注册表(Registry,繁体中文版Windows称之为登录档)是Microsoft Windows中的一个重要的数据库,用于存储系统和应用程序的设置信息.早在Wind ...

  2. Ubuntu中的两套网络连接管理方式

     版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/haifeng_gu/article/details/78286895 Linux里面有两套管理网络 ...

  3. 3dTiles 数据规范详解[3] 内嵌在瓦片文件中的两大数据表

    转载请声明出处:全网@秋意正寒 零.本篇前言 说实话,我很纠结是先介绍瓦片的二进制数据文件结构,还是先介绍这两个重要的表.思前想后,我决定还是先介绍这两个数据表. 因为这两个表不先给读者灌输,那么介绍 ...

  4. Inno Setup中做补丁通过注册表获取原程序安装目录

    今天找VM补丁看到的,是个innosetup封装的,所以习惯性的喜欢去看人家的iss文件是怎么编写的. DefaultDirName={reg:HKLM\SOFTWARE\VMware%2c%20In ...

  5. 关于 JAVA 中使用 Preferences 读写注册表时要注意的地方

    要注意的只有一个地方,那就是键名或者项名不要包含大写字母,否则读不到数据. 代码是这样的: 1: Preferences preferences = Preferences.systemRoot(); ...

  6. MAC中如何配置两套android-sdk环境

    1 背景介绍 随着android studio的完善和普及,越来越多Android app开发者从Eclipse+ADT环境转到Android Studio(后文统一用AS表示).但是,AS往往需要较 ...

  7. 数据结构学习-数组A[m+n]中依次存放两个线性表(a1,a2···am),(b1,b2···bn),将两个顺序表位置互换

    将数组中的两个顺序表位置互换,即将(b1,b2···bn)放到(a1,a2···am)前边. 解法一: 将数组中的全部元素(a1,a2,···am,b1,b2,···bn)原地逆置为(bn,bn-1, ...

  8. SetCookies, cookie规范注册表和cookie存储将会优先于设置在HTTP客户端级别中默认的那些

    遇到下面问题解决方法: Hey? 404 抱歉,你输入的网址可能不正确,或者该网页不存在. 7 秒后返回首页 使用独立的本地执行上下文来实现对每个用户(或每个线程)状态的管理. 定义在本地内容中的co ...

  9. Ruby Rails学习中:注册表单,注册失败,注册成功

    接上篇 一. 注册表单 用户资料页面已经可以访问了, 但内容还不完整.下面我们要为网站创建一个注册表单. 1.使用 form_for 注册页面的核心是一个表单, 用于提交注册相关的信息(名字.电子邮件 ...

随机推荐

  1. 027——VUE中事件修饰符:stop prevent self capture

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. 022——VUE中remove()方法的使用:

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. CF911B

    题解: 枚举一下x x<=min(a,b) 然后判断a/x+b/x是否>=x 代码: #include<bits/stdc++.h> using namespace std; ...

  4. AndroidStudio构建常见错误解答解决思路

    一.Error:Configuration with name 'default' not found.解决思路 出现这问题的原因是你依赖的工程没有make project,意思是你导入项目的工程没有 ...

  5. 【LeetCode 67_字符串_算术运算】Add Binary

    string addBinary(string a, string b) { int alen = a.size(); int blen = b.size(); ) return b; ) retur ...

  6. 每周荐书:机器学习、Java虚拟机、微信开发(评论送书)

    每周荐书:机器学习.Java虚拟机.微信开发(评论送书) 感谢大家对每周荐书栏目的支持,先公布下上周中奖名单 年精心雕琢,难得的"理论 + 实战案例 + 趟坑经验"总结 从需求分析 ...

  7. Java 输出文件通过 BufferedWriter.newline() 方法换行

    最近项目中需要导出文件,其实导出文件是一个挺简单的事情.但是却遇到了很奇怪的问题. 首先导出到文件需要用到 BufferedWriter.而换行则是通过 bw.newline() 方法,问题将出在 n ...

  8. 为什么 UEFI 方式启动的 U 盘必须使用 FAT32 文件系统?

    如果你希望更刺激地安装 Windows,那么你需要了解很多 Windows 系统相关的问题. 为什么 UEFI 方式启动的 U 盘必须使用 FAT32 文件系统? 因为 NTFS 是 Windows ...

  9. mfc 鼠标、键盘响应事件

    一.基本目标 1.有一个基本的MFC程序,点击“关闭”则“关闭”这个程序,这点没什么好讲的,把自带的“取消”按钮,右键->属性的Caption改成“关闭”二字就可以了 2.鼠标在对话框中移动,则 ...

  10. 《DSP using MATLAB》示例Example7.10

    代码: ws1 = 0.2*pi; wp1 = 0.35*pi; wp2 = 0.65*pi; ws2 = 0.8*pi; As = 60; tr_width = min((wp1-ws1), (ws ...