查看: 303|回复: 3

门店电脑防异常软件实践:注册表扫描与AppLocker+MinHook拦截方案

[复制链接]
发表于 昨天 09:00 | 显示全部楼层 |阅读模式
在门店运维中,电脑频繁出现弹窗、卡死或被小游戏占用是常见问题。这些异常通常由病毒、恶意驱动或流氓软件导致。常规做法是通过TeamViewer、向日葵等远程工具手动清理,但门店需要安装远程软件并提供连接码,沟通成本高,且无法主动发现异常。本文结合古茗技术团队的实际经验,分享一套从远程控制到自动监控、再到主动拦截的Windows管控方案,涉及注册表扫描、IObit Unlocker强删、AppLocker策略、MinHook API挂钩以及SSDT Hook等核心技术。

一、一键远程:摆脱门店配合
传统远程依赖门店提供连接码,效率低下。除了购买企业版远程软件(如TeamViewer批量部署包)或开源方案外,团队自研了一款输入门店编码即可一键远控的小工具。具体实现涉及公司内部接口,但核心思路是:通过云端下发加密凭证,本机后台持续监听远控指令,配合Windows服务自动建立RDP或VNC连接。这可以大幅降低门店操作门槛。

二、被动转主动:监控门店软件列表
为尽早发现异常,需要从注册表拉取已安装程序列表并上报云端。核心代码示例(C#):
  1. public static List<IAppData> getAllSoftWare()
  2. {
  3.     List<IAppData> appDataList = new List<IAppData>();
  4.     RegistryKey Key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall");
  5.     if (Key != null)
  6.     {
  7.         foreach (RegistryKey SubKey in Key.GetSubKeyNames())
  8.         {
  9.             // 读取DisplayName,排除SystemComponent为1的项
  10.             string SoftwareName = SubKey.GetValue("DisplayName", "").ToString();
  11.             if (!string.IsNullOrEmpty(SoftwareName) && SubKey.GetValue("SystemComponent", "0").ToString() != "1")
  12.             {
  13.                 var data = new IAppData();
  14.                 data.DisplayName = SoftwareName;
  15.                 // 填充其他字段
  16.                 appDataList.Add(data);
  17.             }
  18.         }
  19.     }
  20.     return appDataList;
  21. }
复制代码
此方法获取的程序列表与控制面板“程序和功能”一致,可识别大多数需要安装的软件。但对于绿色免安装程序,注册表无法扫描。替代方案是监控进程列表(但进程可被隐藏,如SSDT Hook技术)或扫描文件系统并匹配特征码(类似杀毒软件)。团队目前暂未处理免安装场景,因为门店需求主要针对常见安装型流氓软件。

三、自动删除异常软件:IObit Unlocker + 命令行强删
获取软件列表后,若发现已知的恶意软件,需要自动删除。两个障碍:1)进程占用的文件无法直接删除;2)杀毒软件或病毒自身设置了权限保护,阻止删除和注册表修改。
解决方案是使用IObit Unlocker命令行模式强制删除:
  1. runCmd('IObitUnlocker.exe /Delete "文件的绝对路径"')
复制代码
但该命令会弹出确认对话框。为避免用户看到弹窗,可以在启动后立即杀掉IObitUnlocker进程:
  1. if (/*删除成功或超时*/)
  2. {
  3.     Process[] processes = Process.GetProcessesByName("IObitUnlocker");
  4.     foreach (Process process in processes)
  5.     {
  6.         process.Kill(false);
  7.     }
  8. }
复制代码
此外,安装IObit Unlocker时也有界面。团队将安装后的目录直接压缩上传云端,再下发解压到门店电脑,跳过安装过程(也可使用/silent参数静默安装但程序会自动启动界面)。此方法可静默解除文件占用并删除。

四、拦截软件安装:从策略组到API Hook
删除了异常软件,门店仍可能重新下载安装。必须从源头拦截。
1. 利用AppLocker策略组
Windows自带的AppLocker可通过gpedit.msc配置规则。支持三种策略:
- 发布者:根据数字签名(仅MSI/MSP文件)
- 路径:拦截指定文件夹或可执行文件,可设置例外
- 文件哈希:根据文件哈希值精确拦截
例如:将整个文件夹设为拒绝执行,再将常用软件(如浏览器、收银程序)路径添加至允许列表。配置后,双击被拦截的文件会弹出系统拒绝访问提示。
也可用PowerShell命令自动化配置:
  1. Import-Module AppLocker
  2. Get-AppLockerPolicy
  3. Set-AppLockerPolicy -Policy $policy -Merge
复制代码
缺点:1)提示文字无法自定义,对门店用户不友好;2)Win10/11家庭版默认不开启AppLocker,需通过组策略编辑器手动启用。

2. 使用MinHook实现CreateProcess拦截
更彻底的方案是挂钩Windows API。程序通过CreateProcess创建进程,可HOOK该API,在调用前判断是否放行。使用MinHook库实现(C++):
  1. #include <MinHook.h>
  2. typedef BOOL(WINAPI* myCreateProcessW)(
  3.     _In_opt_ LPCWSTR lpApplicationName,
  4.     _Inout_opt_ LPWSTR lpCommandLine,
  5.     _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
  6.     _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
  7.     _In_ BOOL bInheritHandles,
  8.     _In_ DWORD dwCreationFlags,
  9.     _In_opt_ LPVOID lpEnvironment,
  10.     _In_opt_ LPCWSTR lpCurrentDirectory,
  11.     _In_ LPSTARTUPINFOW lpStartupInfo,
  12.     _Out_ LPPROCESS_INFORMATION lpProcessInformation
  13. );
  14. myCreateProcessW fpCreateProcessW = NULL;
  15. BOOL WINAPI HookedCreateProcessW(/*参数同上*/)
  16. {
  17.     if (/*判断需要拦截*/) {
  18.         return TRUE;  // 阻止创建
  19.     }
  20.     return fpCreateProcessW(/*原始参数*/);
  21. }
  22. BOOL Hook() {
  23.     MH_Initialize();
  24.     MH_CreateHookApiEx(L"kernel32", "CreateProcessW", &HookedCreateProcessW, &fpCreateProcessW);
  25.     MH_EnableHook(MH_ALL_HOOKS);
  26.     return TRUE;
  27. }
复制代码
此代码编译为DLL,需要全局注入。

DLL全局注入方式:
- 注册表注入:在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows下,将AppInit_DLLs设为DLL路径,LoadAppInit_Dlls设为1。原理:程序加载user32.dll时会加载该注册表指定的DLL。限制:64位电脑只能注入64位进程;少数系统进程无法注入。但explorer.exe、cmd、powershell等主流进程均可注入,可拦截桌面双击和cmd启动的安装程序。
- SetWindowsHookEx:通过消息钩子注入,但32/64位不互通,且只能注入注册了窗口类的程序(Windows Forms可以,WPF不行)。
- SSDT Hook:内核层HOOK NtCreateProcessEx,可实现全局拦截(包括进程内部CreateProcess)。团队未完全实现,但指出杀毒软件常用此技术,可参考“SSDT 进程保护”。

对于门店场景,大部分异常软件来自用户双击安装包(由explorer.exe发起),注册表注入即可覆盖。若想拦截更复杂的链式安装(如A程序调用B程序),需要内核HOOK。

五、拦截浏览器并引导至软件管理
门店常通过浏览器搜索下载软件,容易被误导安装流氓软件。可以拦截浏览器进程,同时提供一个受控的软件安装界面。
拦截方法:
1. 使用WMI事件监听进程创建,检测到浏览器进程即结束。C#示例:
  1. public static void preventBrowser()
  2. {
  3.     var queryString = "SELECT * FROM __InstanceCreationEvent WITHIN 5 WHERE TargetInstance ISA 'Win32_Process'";
  4.     var query = new EventQuery(queryString);
  5.     using (var watcher = new ManagementEventWatcher(query))
  6.     {
  7.         watcher.EventArrived += OnProcessStarted;
  8.         watcher.Start();
  9.         Console.ReadLine();
  10.     }
  11. }
  12. private static void OnProcessStarted(object sender, EventArrivedEventArgs e)
  13. {
  14.     var process = e.NewEvent.Properties["TargetInstance"].Value as ManagementBaseObject;
  15.     if (process != null)
  16.     {
  17.         // 等待进程信息初始化
  18.         for (int i = 0; i < 60; i++)
  19.         {
  20.             if (process.Properties.Count <= 0) Thread.Sleep(50);
  21.             else break;
  22.         }
  23.         string processName = process["Name"].ToString();
  24.         string processPath = process.Properties["ExecutablePath"]?.Value?.ToString();
  25.         if (isBrowser(processName, processPath, process.Properties["CommandLine"]?.Value?.ToString()))
  26.         {
  27.             try
  28.             {
  29.                 int pid = int.Parse(process.Properties["ProcessId"].Value.ToString());
  30.                 Process.GetProcessById(pid).Kill();
  31.             }
  32.             catch { }
  33.         }
  34.     }
  35. }
复制代码
说明:WMI轮询间隔(WITHIN 5)导致5秒延迟,且进程信息初始化有额外等待,因此对快速执行的静默安装可能失效,但手动双击浏览器足够拦截。同时需禁用浏览器的自动更新任务,以免误拦更新进程:
  1. Global.RunCmd("schtasks /change /tn "SogouExplorer Updater Task" /disable");
  2. Global.RunCmd("reg add "HKEY_LOCAL_MACHINE\\SOFTWARE\\Policies\\Mozilla\\Firefox" /v DisableAppUpdate /t REG_DWORD /d 1 /f");
复制代码

2. 拦截后弹窗引导门店使用内部软件商店,统一下载经过审核的安装包。商店程序通过Simple Process.Start执行安装包,并轮询进程是否存在:
  1. Process process = new Process();
  2. process.StartInfo.FileName = exePath;
  3. process.StartInfo.UseShellExecute = false;
  4. process.Start();
  5. while (true)
  6. {
  7.     Thread.Sleep(3000);
  8.     Process[] localByName = Process.GetProcessesByName(exeName);
  9.     if (localByName.Length == 0)
  10.     {
  11.         Log("安装完成 " + exeName);
  12.         break;
  13.     }
  14. }
复制代码
注意:门店用户可能直接结束商店程序,导致管控失效。可像杀毒软件一样使用SSDT Hook Hook NtTerminateProcess保护自身进程,但团队最终选择更彻底的桌面管控。

六、桌面管控:完全改变用户认知
最根本的解决方案是替换Windows桌面,呈现一套仅包含收银功能的虚拟界面。功能包括:程序快捷方式、网络设置、关机/音量控制等,完全屏蔽开始菜单、任务栏和传统桌面。用户只能操作点单、收银流程,无法安装或运行无关软件。此方案可彻底杜绝误操作,但实现细节较多,团队将在后续文章中分享。

总结
本文从门店电脑频繁中病毒的痛点出发,逐步演进:先通过一键远程提升处理效率,再通过注册表监控发现异常软件,用IObit Unlocker自动删除,利用AppLocker和API Hook拦截软件安装,最后以WMI事件拦截浏览器并引导至官方软件商店。整套方案显著降低异常软件感染率,并增强了对门店收银机的可控性。对于需要类似场景(如公共终端、企业内网)的开发者,这些技术手段有很高的参考价值。
回复

使用道具 举报

发表于 昨天 09:10 | 显示全部楼层

Re: 门店电脑防异常软件实践:注册表扫描与AppLocker+MinHook拦截方案

很感谢分享这么详细的实战方案!特别是用注册表扫描结合AppLocker和MinHook拦截的思路,对门店这种有统一管理需求但又要兼顾用户体验的场景很有参考价值。 想请教几个细节:用MinHook挂钩CreateProcess时,如何维护允许列表的实时更新?比如门店临时需要安装一个合法软件,会不会需要手动停用钩子或下发策略?另外IObit Unlocker杀掉进程后,如果文件还没完全解锁就删除,会不会导致文件系统残留?希望以后能看到更多关于免安装程序识别和SSDT Hook防护的分享,谢谢!
回复 支持 反对

使用道具 举报

发表于 昨天 09:10 | 显示全部楼层

Re: 门店电脑防异常软件实践:注册表扫描与AppLocker+MinHook拦截方案

楼主这篇分享非常实在,尤其是从“远程依赖门店配合”到“主动监控+自动清理”的转变思路,确实很符合门店运维的实际痛点。注册表扫安装软件 + IObit Unlocker 强删的做法,在对付常见流氓软件时性价比很高;AppLocker 策略组和 MinHook 拦截的结合,也体现了从规则到驱动的分层防御。想请教两个小细节: 1. 注册表扫描部分过滤了 SystemComponent 为 1 的项,但有些恶意软件可能会伪装成系统组件,你们有没有遇到需要额外排除或合并其他键值的情况? 2. 自研的一键远程工具里,后台监听远控指令并建立 RDP/VNC 连接,在门店网络环境复杂(比如只有 WiFi、有内网隔离)时,会不会遇到连接不稳定的问题?有没有做过 NAT 穿透或中继方案? 感谢分享,这种实战方案比理论文章有用得多。
回复 支持 反对

使用道具 举报

发表于 昨天 09:10 | 显示全部楼层

Re: 门店电脑防异常软件实践:注册表扫描与AppLocker+MinHook拦截方案

感谢楼主的分享,内容非常扎实,特别是从远程控制到主动拦截的完整链路,对门店运维场景很有参考价值。 关于AppLocker在家庭版上的限制,确实是个痛点。我自己测试过,Win10/11家庭版可以通过修改组策略编辑器的访问权限来强制启用,但有一定风险。不知道楼主在实际部署中是否有更稳定的绕过方法?另外,MinHook拦截CreateProcess的方案,在处理UAC提权后的进程创建时,需要注意管理员权限下Hook的生效范围(比如注入到所有进程还是只针对特定进程)。如果方便的话,能否再详细讲讲你们在SSDT Hook层面的具体落地?因为门店电脑环境复杂,驱动级拦截的稳定性很关键。 IObit Unlocker强删后杀进程防弹窗的思路很实用,不过如果遇到系统关键进程或驱动保护的流氓软件,IObit有时也会卡住。你们有考虑过直接用NtDeleteFile或底层文件系统过滤驱动来替代吗?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-6-26 01:54 , Processed in 0.038412 second(s), 17 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部