日前遇到一件事: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. MySQL使用RPM包方式安装

        CentOS7安装MySQL的方法之RPM包方式        

  2. LeetCode OJ:Implement Stack using Queues(队列实现栈)

    Implement the following operations of a stack using queues. push(x) -- Push element x onto stack. po ...

  3. 配置django上传文件目录的http访问

    1.假设你的html模版文件使用以下路径来访问上传文件内容: url="{{ MEDIA_URL }}{{ images.image }}" 2.设置settings文件: MED ...

  4. MoreEffectiveC++Item35(操作符)(条款5-8)

    条款5 对定制的"类型转换函数"保持警惕 条款6 区别increment/decrement操作符的前值和后置形式 条款7 千万不要重载&&,||,和,操作符 条款 ...

  5. L166

    THE idea of underwater mining is not restricted to the ocean floor (see article). High water tables ...

  6. 【HEVC学习与研究】29、解码第一个Coding Quadtree结构(1)

    ctu tree属性 http://blog.csdn.net/shaqoneal/article/details/26088817

  7. vue和react

    1. 数据渲染 vue是使用template模板进行渲染,react使用的是jsx语法,对组件进行渲染 vue模板中使用{{ this.data }} 双括号包着变量,代表变量表示的值.外面那层表示需 ...

  8. flowable EngineConfiguration的实现分析(2)

    EngineConfiguration的实现类是一个抽象类:AbstractEngineConfiguration 一.引擎配置的分类 继承 AbsractEngineConfiguration的子类 ...

  9. MFC CListControl 点击列头排序的实现

    SetItemData可以为每一行绑定一个DWORD类型的变量.用GetItemData可以获得这个变量.举个例子,假设CListCtrl中你需要显示某个数据表中的记录,该表有个流水号主键ID,一般这 ...

  10. Qt QScrollArea and layout in code

    Qt QScrollArea and layout in code 一.参考文档: . Qt 第六章 QScrollArea类给QWidget添加滚动条 http://blog.csdn.net/co ...