首页 > 编程知识 正文

360弹出窗口拦截,360 弹窗拦截

时间:2023-05-05 05:36:14 阅读:285983 作者:544

一、查找问题

收到反馈说编码器被360弹窗拦截器拦截,经测试发现强力模式下也并没有直接拦截,但是会出现提示框;猜测有可能是用户不小心添加过滤了或者其他版本会有拦截,导致编码器被关闭无法正确编码。查找资源后发现,弹窗拦截是通过发送Windows消息触发隐藏和关闭的。

于是考虑先把编码器生成后接受到的消息打印出来查看分析。

由于WPF本身是有对消息和窗口句柄等进行封装的,所以需要重新去添加using System.Windows.Interop; 这个namespace中所包含的东西主要是为 Windows Presentation Foundation (WPF) 和其他技术(如 Win32API)之间的互操作提供支持类型,并为涉及 WPF 的其他特定互操作方案提供基类。在WPF中使用WindowProc,首先要获得一个HWND句柄(一个IntPtr类型),然后通过创建一个HwndSource对象,再通过调用这个对象中的AddHook方法来添加WindowProc。其中HwndSource实现包含 WPF 内容的 Win32 窗口。WPF 内容在此窗口中排列、度量、呈现,并且可交互式输入。HwndSource 类设计用于一般的交互操作,而不是设计用作托管 HWND 包装。通常,它不会提供操作窗口的托管方法或检测其状态的属性。相反,HwndSource类提供通过 Handle 属性对 Win32 窗口句柄 (HWND) 的访问,可通过 PInvoke 技术将其传递到 Win32 APIs 以操作该窗口。

现在开始进行挂钩,可以通过添加SourceInitialized的事件处理函数引发添加,直接重载OnSourceInitialized函数来添加。下面是通过添加处理函数的方式实现。

此外也有两种获取HwndSource的方法

上面为将窗口作为互操作方案的源生成HwndSource。

下面则通过WindowInteropHelper获取窗口句柄,通过句柄来生成。然后通过挂钩上消息处理函数自定义的WndProc。对于WinForm可以直接重载WndProc函数protected override void WndProc(ref Message m) 然后在窗体显示时Shown添加过滤即可。WPF中再添加窗口内容呈现的处理函数进行过滤把窗口创建呈现之后产生的消息打印到桌面。
protected virtual IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)前四个参数跟MSG结构体的意义一致,最后一个handled则代表这个消息是否告诉系统已经处理结束,是否需要继续放行传递让其他的方法执行。

大致生成了如下消息,通过拦截与不拦截、生成窗口后再添加拦截等测试,经分析,主要是自定义消息49642以及
WM_SHOWWINDOW = 24 (0x0018)当隐藏或显示窗口是发送此消息给这个窗口
WM_CLOSE = 16(0x0010) 当一个窗口或应用程序要关闭时发送一个信号的问题。

二、验证方法

经过对已拦截的消息的分析,先对已知的消息进行相关测试。

既然获取到了WM_SHOWWINDOW(wParam = 0x000000)隐藏窗口以及WM_CLOSE,能否直接拦截过滤掉,把handled设置为True告诉系统已经处理过。

结果:
能够正常编码生成文件,但是窗口消失。既然无法直接通知系统已关闭,能否收到隐藏窗体时,直接调用ShowWindow的方法直接把窗体显示。

结果:
无论是否更改handled的值告诉系统或者更改显示窗体的方法,都无法在收到隐藏窗体消息的时候发出显示窗体的消息重新显示窗体。由于无法在收到隐藏窗体消息的时候直接显示窗体,所以需要查找出错的环节,首先验证在窗体被隐藏后能否通过发送消息显示出来。
结果:
通过外部程序发送显示的消息WM_SHOWWINDOW(wParam = 0x000001)能够正常显示;
编辑此区域
接下来验证是否是所调用的方法出现错误,把该函数以及参数新建到一个控制台程序在窗体隐藏时运行。 Win32.ShowWindow(hwnd, Win32.SW_SHOW);(在Win32中定义如下)[DllImport("user32.dll")]public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);//ShowWindow参数public const int SW_SHOW = 1;

结果:
经测试发现可以把窗体唤醒显示。因此初步判断异常出现在接收到隐藏窗体消息时无法正确显示。
4. 在WM_SHOWWINDOW(wParam = 0x000000)的执行过程中添加LogHelper记录,通过对比相关消息发现,确实有进入执行该步骤,但却无法显示窗体,推测窗体处于要隐藏但尚未隐藏的状态,即收到要隐藏的消息,但窗体的wParam还是等于1的,而且在WM_SHOWWINDOW(wParam = 0x000000)这个消息的处理中发出WM_SHOWWINDOW(wParam = 0x000001)消息有被微软本身做出相关处理,不执行。

验证在WM_SHOWWINDOW(wParam = 0x000000)消息之后发出显示窗体的消息能否把窗体显示,即在WM_CLOSE中处理。

结果:
能够正确在360弹窗拦截器隐藏窗口发出关闭消息后马上显示窗体,拦截次数从9次变成10次并且不会被再次隐藏。
此外,在使用外部软件显示窗体时,会被拦截器再次拦截,故把handled值改为False测试,发现在显示之后还是会被拦截,推测是360弹窗拦截器有对消息做重复检测,但通过handled=True告诉系统已经处理过,让弹窗拦截器无法截获该消息,认为窗体已经正确关闭。至此,已经解决360弹窗拦截的问题,以上就是我对修复该问题的分析流程。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。