-
-
[原创]Internet Explorer 扩展注册项与 COM 实现解析
-
发表于: 3天前 960
-
文章所述全部在KswordARK中实现,项目地址935K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6w2f1%4N6G2M7X3c8p5c8g2k6Q4x3V1k6w2f1%4N6G2M7X3b7`.

要得到 Internet Explorer(IE)扩展注册项及其关联 COM(Component Object Model,组件对象模型)服务器的静态记录,分为四步:
注册表是 Windows 保存系统和用户配置的分层数据库。COM Classes 注册区保存类标识符与创建该类所需服务器之间的映射。InprocServer32 表示进程内 DLL 服务器,LocalServer32 表示可单独启动的本地 EXE 服务器。
IE 扩展来源键 -> 值名、值数据或子键名 -> 有效 CLSID -> HKCU 或 HKLM Classes 注册 -> InprocServer32 或 LocalServer32 默认值
HKCU 是 HKEY_CURRENT_USER,保存当前登录用户的配置。HKLM 是 HKEY_LOCAL_MACHINE,保存整台计算机的配置。两个范围都可能提供同一个 CLSID 的注册信息。
这四步得到的是注册表在读取时的静态关系。注册项存在、服务器文件可见和浏览器进程实际加载扩展是不同层次的事实,最后需要分别表述。
第一步要先确定 IE 从哪里发现扩展,以及每个注册表位置代表什么。COM 是 Windows 用来标识和创建可复用组件的一套规则。IE 历史上提供 BHO(Browser Helper Object,浏览器帮助对象)、Explorer Bar(浏览器停靠栏)、Toolbar(浏览器工具栏)和 URLSearchHook(地址栏搜索处理对象)等扩展点。浏览器先从对应注册表来源取得 CLSID,再通过 COM Classes 注册定位 DLL 或本地 EXE 服务器。
浏览器不会直接从扩展路径列表加载对象。IE 读取对应注册表位置,得到 CLSID,再通过 COM 激活该 CLSID 对应的对象。
CLSID 是用花括号包围的 GUID(Globally Unique Identifier,全局唯一标识符),例如 {01234567-89AB-CDEF-0123-456789ABCDEF}。它用于标识 COM 类,不能凭自身说明扩展名称、服务器路径或浏览器是否已加载它。注册项中出现 CLSID 后,还需要查询 Classes 注册根下的服务器键,才能找到实现对象的 DLL 或本地服务器命令文本。
扩展种类决定注册入口和接口要求。BHO 是可在浏览器进程中参与导航和文档事件的对象。Explorer Bar 通常提供停靠式侧边栏用户界面。Toolbar 关联浏览器工具栏。URLSearchHook 可参与地址栏输入的搜索处理。服务器定位步骤都遵循 COM 注册规则。
一个 CLSID 可能出现在多个来源键中。这种情况表示同一个 COM 类被不同扩展点引用,记录时应保留每次出现的来源路径、值名或子键名,而不是按 CLSID 折叠成唯一记录。服务器注册同样可能同时存在用户级和机器级、32 位和 64 位不同视图。
IE 扩展机制需要保留历史与宿主边界。现代 Windows 版本上的 IE 可用性、IE 模式和实际宿主进程取决于系统组件、策略和安装状态。注册表中保留的扩展项只证明配置存在,不能单独证明某个浏览器进程当前会调用它。
读取结果可明确写出“扩展来源”“CLSID 注册状态”“服务器文本”和“读取视图”。是否被加载、是否实现目标接口、是否在某个浏览器版本中启用,需要由实际 COM 激活、进程模块或浏览器运行时证据进一步确认。
HKEY_CLASSES_ROOT 提供合并后的类注册视图,底层可来自 HKCU\Software\Classes 或 HKLM\Software\Classes。为了看清原始配置,应分别查询这两个根。
InprocServer32 的默认值通常是 DLL 路径,DLL 需要与加载它的浏览器进程架构匹配。LocalServer32 的默认值通常是可带参数的 EXE 命令文本。读取默认值时保存其原文,不用第一个空格强行截断路径,也不把服务器文本替换为文件签名结论。
浏览器宿主和扩展对象需要分开。IE 扩展的 COM 服务器可能由浏览器进程在进程内加载,也可能由系统单独启动为本地服务器。BHO 等进程内组件与浏览器共享同一地址空间、线程和崩溃范围。网页 URL、扩展 CLSID 和 DLL 文件路径属于不同身份字段。
网页内容属于浏览器呈现和安全区域处理的对象,COM 扩展注册属于 Windows 类注册对象,DLL 或 EXE 属于文件系统对象。调查时若只得到 CLSID,最多说明存在一个注册的类身份。若要解释页面行为,还需要独立的浏览器进程、导航事件、加载模块或网络记录证据。
完成第一步后,已经有了扩展类型、用户级或机器级范围,以及 32 位和 64 位视图这三类读取边界。接下来要按来源键的真实结构读取原始数据,才能避免把值名、值数据和子键名混成同一种线索。
第二步要按来源键保存记录,不能只留下看似有用的字符串。URLSearchHooks 与 Toolbar 要枚举键中的所有值。CLSID 可能是值名,值数据可能是显示名称、空字符串、二进制标志或另一个 CLSID,值名和值数据不能混为同一字段。
Browser Helper Objects 与 Explorer Bars 要枚举一级子键。子键名经常是 CLSID,默认值可提供显示名称。默认值缺失不影响通过子键名定位 COM 注册。
读取时分别覆盖 HKLM、HKCU 的 64 位与 32 位视图。64 位进程的默认注册表视图只覆盖一侧,显式使用 KEY_WOW64_64KEY 与 KEY_WOW64_32KEY 才能取得两份配置。
值枚举先取得最大值名和数据长度,再按各自单位分配缓冲区。值名长度是 UTF-16 字符数,值数据长度是字节数。注册表并发变化时 ERROR_MORE_DATA 表示其中一侧容量需要扩大。
值数据只在类型为 REG_SZ 或 REG_EXPAND_SZ 且字节数满足 UTF-16 对齐时转换为文本。Toolbar 中的 REG_BINARY 值仍作为完整记录输出类型和字节数,不能按字符串读取。
子键枚举使用 RegEnumKeyExW。某些扩展键只授予子键枚举权限,名称缓冲区从合理初始值开始并在 ERROR_MORE_DATA 时扩容,能避免依赖不必要的附加查询权限。
默认值通过空值名读取。默认值存在时保存类型和原始文本。默认值缺失时保留子键 CLSID 与“默认值未设置”状态。
这一阶段还要把资源所有权、访问权限和长度单位分开处理。HKEY 是已打开注册表键的资源引用,RegOpenKeyExW 成功后由得到它的一方调用 RegCloseKey。REGSAM 是访问掩码,决定这次句柄允许查询值还是枚举子键。DWORD 是 32 位无符号整数,经常承载长度或访问位。
RegEnumValueW 的 lpcchValueName 以 UTF-16 宽字符数表示名称缓冲区容量和实际长度,lpcbData 以字节表示数据缓冲区容量和实际长度。UTF-16 是 Windows 宽字符 API 使用的文本编码。返回的文本数据未必包含 NUL 终止符,因此要按 API 返回的确切长度构造字符串。只有 REG_SZ 或 REG_EXPAND_SZ 且数据字节数可被 sizeof(wchar_t) 整除时,才把原始字节解码为文本。
[内核课程]《Windows内核攻防实战》!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。