本帖最后由 冥界3大法王 于 2026-8-22 11:16 编辑
本次修改挑战的是这个浏览器(哈哈,你懂滴。。俺就不说谁谁谁了)
我这个电脑注册表有问题。。
即便每次设置了浏览器为默认,下次重启还得设置,算了。。今天试着来攻破下难关。
先去定位搜索一下相关字符串,发现无非最后还是落在语言文件中,如下图:
来到x64dbg中附加 该浏览器 ,一般会发现多个。选择哪个呢? 当然是你激活的看到的浏览器标签名相关的那个优先了。。
如果你不附加的话,你可以选择使用 ScyllaHide-1.4(最后源码编译的就是该版本,懒人开启全部选项)
来到x64dbg中搜索defaultBrowser 最会得到下面的信息,我随便通过gemini Google来分析了下:(怎么说呢?有对有错,试了之后得结论!)
反正 你让我猜的话,我肯定是Alt+E (模块中先看 tabbit.dll and chrome.dll 类似的模块名啦)
在您列出的这一大堆字符串引用中,最可疑、最值得优先逆向分析的是以下几组。
根据 Chromium 源码架构,我们可以将这些地址按“危险程度”(即直接控制检测与弹窗的概率)分为三个梯队:
第一梯队:绝佳切入点(最为可疑 ★★★★★)
这两组地址处于控制默认浏览器检测逻辑和顶栏/弹窗提示 (InfoBar/Modal) 的核心控制流中,修改它们所在的函数最容易直接干掉弹窗。
1. 弹窗 UI 交互与触发点(最直接的控制逻辑)
00007FF8AD2BC5EB : DefaultBrowserInfoBar_Ignore
00007FF8AD2BCAC9 : DefaultBrowserInfoBar_Accept
00007FF8AD2BCBB8 : DefaultBrowser.InfoBar.UserInteraction
00007FF8AD2F4B8F : DefaultBrowserInfoBar
00007FF8AD2BE166 : DefaultBrowserModal
可疑原因:
这些是 Chrome 顶部出现的 "Chrome 不是您的默认浏览器 - 设为默认" 那个黄色/蓝色提示条(InfoBar)以及弹窗(Modal)的构造与事件响应函数。
沿着这里的 lea 指令向上追踪函数头部,或者看谁调用了这个函数,把调用处的跳转(如 JZ/JE)直接 NOP 掉,或者让判断函数直接返回 0,InfoBar 就永远无法被创建出来。
2. 底层系统状态校验点(决定“是否触发”的源头)
00007FF8A447ADE0 : PerformDefaultBrowserCheckValidations
00007FF8A447AECD : PerformDefaultBrowserCheckValidations
00007FF8A447AE36 : DefaultBrowser.HttpProgIdAssocValidationResult
00007FF8A5BC7DF1 : DefaultBrowser.State
可疑原因:
PerformDefaultBrowserCheckValidations(执行默认浏览器检测校验)是 Chromium 内部用来向 Windows 系统查询注册表和 HTTP 关联关系的函数。
如果在这个函数的入口处直接写 MOV EAX, 1; RET(假装当前已经是默认浏览器),后方所有的弹窗、提示、设置页状态更新都会被一刀切地阻断。
第二梯队:次要可疑点(前端与交互 API ★★☆☆☆)
00007FF8B226821F : requestDefaultBrowserState
00007FF8B22682F1 : setAsDefaultBrowser
00007FF8B219B263 : skipDefaultBrowser
可疑原因:
这些是 Chrome 内部 WebUI(比如首次运行界面 ProfilePicker 或 chrome://settings 设置页面)调用 C++ 后端的桥梁(Mojo/JS-Bridge 接口)。修改这里可能只会让设置界面的按钮失效,但未必能阻止启动时的自动弹窗检测。
第三梯队:完全不建议动(纯静态文本/国际化翻译 ☆☆☆☆☆)
00007FF8A6ECFE91 及周围的一大片(defaultBrowserMakeDefault 等)
00007FF8B219B7E7 : defaultBrowserTitle
排除原因:
这一大排连续的地址(A6ECFE91 ~ A6ECFFF4)只是注册 i18n 语言包(JSON / 资源映射表) 的字符串 key,用来给按钮或标题赋值文本内容。修改这里只会导致界面文字变空,根本无法阻止检测和跳转逻辑的执行。
实战定位与修改推荐路径
在 x64dbg 或 IDA 中,建议按以下顺序下手:
- 跳转到
00007FF8A447ADE0 (PerformDefaultBrowserCheckValidations):
查看这个函数:若该函数返回 Bool 值,直接强制其返回 1;或者通过 Xrefs (查找谁调用了它),找到外层的 IF 判断,把跳转逻辑 Patch 掉。
- 跳转到
00007FF8AD2F4B8F (DefaultBrowserInfoBar):
查看此处的函数调用,在入口处直接 RET(强行阻止 InfoBar 对象的实例化)。
尝试修改后,程序运行不起来了。。主明修改位置不对。。。
如果光修改注册表键值的检测呢?内容如下:
光修改“注册表键值检测”是可行的,但通常治标不治本,甚至可能会引发其他预期之外的问题。
以下是深入分析为什么“只改注册表检测”能生效,以及为什么逆向人员通常不推荐只改这里的原理:
一、 为什么光修改注册表检测“能生效”?
Chromium 在 Windows 上的默认浏览器检测逻辑,最底层的依据就是去读取系统注册表中的 UserChoice 键值:
HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice
在汇编层面,它大概率会调用 RegOpenKeyExW / RegQueryValueExW 或者 AssocQueryStringW。
如果你定位到 chrome.dll 中读取注册表的地方,进行以下 Patch:
- 伪造读取结果:无论注册表中写的是什么,汇编 Patch 强制让读取结果返回你的浏览器 ProgID(例如
ChromeHTML)。
- Patch 校验逻辑:找到
PerformDefaultBrowserCheckValidations 里对比注册表字符串的 cmp / wcsncmp 指令,把条件跳转(如 JNZ)改为 NOP,让它永远认为“注册表里的默认浏览器就是我”。
这样修改后,底层检测函数会返回 true,上层的弹窗(InfoBar)确实就不会触发了。
二、 为什么只改注册表检测“不够优雅/有隐患”?
在 Windows 10/11 上,微软为了防止第三方软件恶意篡改默认浏览器,对注册表检测和修改机制做了非常复杂的对抗,只改注册表检测会遇到以下三个痛点:
1. 注册表检测不是唯一的检测途径
现代 Chromium 内核(尤其是微软的 Edge 或各家二次开发的内核)除了读注册表,还会:
- 调用 COM 接口(如
IQueryAssociations)向 Windows 询问关联关系。
- 检查 Win11 特有的 Hash 校验值(
UserChoice 下的 Hash 键)。如果发现 Hash 不匹配,系统会判定注册表被篡改,此时即使你的 Patch 骗过了注册表字符串匹配,Chromium 后续的合法性校验(Validation)依然可能抛出 Error 状态,触发恢复默认提示。
2. “掩耳盗铃”效应(状态不一致)
如果你只 Patch 了注册表读取函数,让它盲目返回“我是默认浏览器”:
- 启动弹窗消失了:这达到了你的目的。
- 但设置页面乱套了:当你主动打开
chrome://settings/defaultBrowser 时,浏览器UI会坚信自己是默认浏览器,但当你点击“设为默认”或“刷新状态”时,由于底层注册表并没有真正被系统接纳,可能会导致设置页面卡死、逻辑死锁或提示异常。
3. 拦截点太靠下,浪费 CPU 开销
注册表检测属于底层 IO/API 操作。每次启动时,程序依然要走一遍复杂的注册表读取、字符串解析、内存分配流程,最后才在比较环节被你的 Patch 骗过去。
三、 最佳 Patch 策略对比
为了达到最稳定、最干净的效果,逆向修改时通常有三个层次:
| Patch 层次 |
做法 |
优点 |
缺点 |
| 底层:只改注册表检测 |
Patch RegQueryValue 或 HttpProgIdRegistryValidation 的对比指令 |
能阻止部分弹窗 |
容易被 COM 接口或 Hash 校验绕过;逻辑较绕 |
| 中层:直接 Patch 检测函数返回值(推荐 ★★★) |
在 PerformDefaultBrowserCheckValidations 入口直接 MOV EAX, 1; RET |
最干净! 一劳永逸,上层所有逻辑都以为自己是默认浏览器 |
需要精准定位函数头 |
| 顶层:只 Patch 弹窗 UI |
在 DefaultBrowserInfoBar 构造函数入口直接 RET |
不管是不是默认,强行不让弹窗显示出来 |
底层检测依然在运行,且设置页依然会显示“非默认” |
总结建议
如果你已经用 x64dbg 找到了 PerformDefaultBrowserCheckValidations(也就是上一问列表中的 00007FF8A447ADE0),直接在这个函数的开头 Patch 掉返回值(mov eax, 1; ret),效果绝对比单独去改内部的“注册表检测逻辑”要好得多,因为这一步直接把包含注册表在内的所有校验全部跳过了。
结论果然是AI说的对,不够全面,掩耳盗铃。。。
先来还试着定位上面的字符串
也是不对的。。
最后最后来到图中所示的位置处,Ctrl+Home来到段首,Ctrl+R查找引用点
发现外层是一个
Jxx =======>修改为JMP
call
竟然成功啦。。。
还会提醒是不是默认浏览器,但是! 我们已经可以白嫖啦。{:301_986:}
|