背景:
微软最近的KB5034203补丁包中explorer.exe包含这样一段代码, 这两天传来传去, 各种说法都有, 我也很好奇, 但是一直没等到具体的技术细节分析, 自己分析一下.
正文
explorer.exe启动时会加载twinui.pcshell.dll并执行其中的ShellFeedsAvailability::WriteFeedsAvailabilityToRegistry
, 这个函数很重要, 如果它没有执行, 那么IsHijackingProcessRunning()那些代码都不会执行到:
此函数内部会调用ShellFeedsAvailability::CheckFeedsServerAvailability()
从微软服务器下载json配置文件并决定相关功能开关.首先组装配置文件URL:
URL:
随后PingFeedsEnablementEndpoint()函数用这个URL请求json配置:
获取到的json内容:
再将获取到的json传递到IsFeedsEnabledAtEndPoint, 这个函数会解析json配置文件的一个重要字段reclaimEnabled
, 如果为false, 那么后面检测360的那段逻辑也不会执行, 而如果是true, 则将注册表Campaign设置为"feeds-reclaim":
然后返回到最初的WriteFeedsAvailabilityToRegistry, 将注册表CampaignState写为2, 再给Shell_TrayWnd发一个自定义消息, WParam为12:
这个消息会在explorer.exe的Feeds::FeedsDynamicContent::ProcessMessage
中处理, 主要是启动一个ID为6的timer, 默认300秒(或10秒后)运行, 运行一次后就killtimer:
Feeds::FeedsDynamicContent::OnTimer
中判断TimerID为6且reclaim feature开启就会调用ShellFeedsCampaignHelper::RunFeedsCampaign::
RunFeedsCampaign会检查前面那两个注册表键值, 如果设置了并且值符合要求, 就会执行ShellFeedsCampaignHelper::CheckCampaignAvailability
:
CheckCampaignAvailability函数里一系列环境判断, 但会优先查看feeds是否被隐藏, 如果没有被隐藏, 后续的检测, 包括对360进程的检测都不会执行:
同时这个函数里也有一些其他判断, 比如:
如果所有条件都成立, 则执行CampaignAction_Reclaim:
调试前我就已经纯手动关了feeds(任务栏右键->资讯->关闭), 函数逻辑及执行前任务栏右下角状态:
CampaignAction_Reclaim执行后:
也就是说CampaignAction_Reclaim函数主要就是把被隐藏的feeds组件重新展示出来(当然前提是满足一系列条件).
此外explorer.exe中新增了一些代码, 会将feeds组件的某些注册表参数值做"加密"(这个也是由feature开关决定是否要执行):
"加密"相关逻辑:
导入的HashData函数的具体哈希逻辑没兴趣看:
整体就是判断一系列条件是否全满足(其中一个必要条件是存在360进程), 且feeds组件是隐藏状态且超过一定时间, 那么就再次给它展示出来. (据说360并不会主动隐藏微软的feeds组件, 是360系统优化中的其中一个功能, 需要用户手动操作才会隐藏feeds, 这个我没实际验证)
仅客观技术分析, 以上都是静态代码逻辑能明确看到, 并且在调试器实际验证观察过的(除了注册表值加密那部分, 那部分我不关心, 所以并没有让那段代码跑起来实际观察验证, 加密逻辑很简单, 静态看就差不多了).
至于网上所说的是微软为了避免跟360冲突崩溃/主动隐藏自身广告/兼容360搜索窗口错位, 暂时没有看到明确相关的逻辑(但也不是说完全不可能, 也许只是我暂时没看到, 因为时间有限, 要对两个版本的多个二进制文件所有差异做100%全覆盖分析太费事了, 我主要想弄明白的主要还是explorer.exe"检测到360后到底会做什么".)
调试环境
原始镜像:
zh-cn_windows_10_business_editions_version_22h2_updated_oct_2023_x64_dvd_eb713365.iso
补丁包:
windows10.0-kb5034203-x64_14f2cba156944cea66379d78c305f5aa5a6517e7.msu
(这个补丁包里explorer等组件版本大多是3996, 这是目前在微软官方网站能找到的首个包含IsHijackingProcessRunning的版本)
注:
上面提到的feature开关(带feature_xxxx_private_IsEnabled的), 和json里的那个字段是独立的, 如果想调试复现的话, 要注意把相关feature开关也打开(调试器里把相关函数头改为mov eax,1; ret).
另外借"操作系统检测三方软件"这个话题, 再额外发一段windows内核中的逻辑:
这是几年前调一个驱动问题的时候无意中发现的, 在最新Win11上依旧存在, 但这个我也没有实际安装卡巴斯基调试验证, 但是有点技术背景的应该都能看出个大概: 微软hook了卡巴斯基驱动的ZwQueryValueKey, 让卡巴斯基读取UseVTHardware的时候返回0. 至于目的, 可能是因为卡巴斯基要用VT, win自己也要用VT,或者卡巴斯基的VT开了之后有其他问题. 具体只有当时写代码的人或者看原始commit信息才知道了.
发卡巴斯基这段并不是为了吐槽微软, 只是恰巧想起来了而已, 实际我是理解这种特殊处理的.
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2024-2-23 12:32
被lidowx编辑
,原因: 补充