zoukankan      html  css  js  c++  java
  • 使用Hook(钩子)阻止Flash启动浏览器打开URL

    使用Hook(钩子)阻止Flash启动浏览器打开URL

    贺星河 2005-11-7

              

    【文章目的】

    .net程序中嵌入flash文件,为了防止有人通过flash右键菜单中的“关于Macromedia”打开ie访问internet,或者flash中通过GetURL()方法打开浏览器直接访问internet

     

    【解决方案】

    使用Hook技术,截获flash在启动外部浏览器访问internet时向系统发送的消息,然后用线程将外部浏览器Kill

     

    【编程手记】

    开发工具:VS2005 Beta2,Flash版本为flash 8

    为了达到禁止Flash打开浏览器的目的,从HookHook不知道?天极里面资料很多的)入手,截获到Flash的相关事件信息,提前启动一个专杀浏览器的线程,使得Flash打开浏览器的瞬间关闭。我们先要找到Flash在播放电子杂志时候的一些相关数据,比如系统消息,发送给外部的消息结构为:

        [StructLayout(LayoutKind.Sequential)]

        public struct CWPSTRUCT

        {

            public IntPtr lparam;

            public IntPtr wparam;

            public int message;

            public IntPtr hwnd;

        }

     

     

    //C#中使用钩子

    public delegate int HookProc(int code, IntPtr wparam, ref CWPSTRUCT cwp);

            public static int WH_CALLWNDPROC = 0x004;

     

            //安装钩子的函数

            [DllImport("user32.dll", CharSet = CharSet.Auto,CallingConvention = CallingConvention.StdCall)]

            public static extern IntPtr SetWindowsHookEx(int type, HookProc hook, IntPtr instance, int threadID);

     

            //调用下一个钩子的函数

            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]

            public static extern int CallNextHookEx(IntPtr hookHandle, int code, IntPtr wparam, ref CWPSTRUCT cwp);

     

            //卸载钩子

            [DllImport("User32.dll", CharSet = CharSet.Auto)]

            public static extern bool UnhookWindowsHookEx(IntPtr hookHandle);

     

            //获取窗体线程ID

            [DllImport("User32.dll", CharSet = CharSet.Auto)]

            public static extern int GetWindowThreadProcessId(IntPtr hwnd, int ID);

     

            private HookProc hookProc;

            private IntPtr hookHandle = IntPtr.Zero;

        

    这是打开Flash中一个含链接的事件时候截获的系统消息:

     

    cwp.message =528 && cwp.wparam=513                                   //鼠标事件消息,在Flash上点击左右键盘都会发生

    cwp.message =33cwp.lparam =33619969                                   

    cwp.message =33cwp.lparam =33619969cwp.wparam=658836cwp.hwnd=724410

    cwp.message =33cwp.lparam =33619969cwp.wparam=658836cwp.hwnd=658836

    cwp.message =32cwp.lparam =33619969cwp.wparam=724410cwp.hwnd=724410

    cwp.message =8cwp.lparam =0cwp.wparam=724410cwp.hwnd=527784

    cwp.message =8cwp.lparam =0cwp.wparam=724410cwp.hwnd=527784

    cwp.message =647cwp.lparam =527784cwp.wparam=24cwp.hwnd=658866       //当前窗口的得到或失去焦点消息

    cwp.message =641cwp.lparam =-1073741809cwp.wparam=0cwp.hwnd=527784

    cwp.message =641cwp.lparam =-1073741809cwp.wparam=0cwp.hwnd=658866

    cwp.message =641cwp.lparam =-1073741809cwp.wparam=0cwp.hwnd=724374

    cwp.message =647cwp.lparam =724410cwp.wparam=23cwp.hwnd=658866       //当前窗口得到或失去焦点信息

    cwp.message =641cwp.lparam =-1073741809cwp.wparam=1cwp.hwnd=724410

    cwp.message =641cwp.lparam =-1073741809cwp.wparam=1cwp.hwnd=658866

    cwp.message =641cwp.lparam =-1073741809cwp.wparam=1cwp.hwnd=724374

    cwp.message =992cwp.lparam =-1070940117cwp.wparam=855452cwp.hwnd=855452  //通知外部浏览器打开URL消息

    cwp.message =992cwp.lparam =-1070940117cwp.wparam=855452cwp.hwnd=724374

    cwp.message =992cwp.lparam =-1070940117cwp.wparam=855452cwp.hwnd=658866

    cwp.message =992cwp.lparam =-1070940117cwp.wparam=855452cwp.hwnd=658836

    cwp.message =996cwp.lparam =-1070940117cwp.wparam=462274cwp.hwnd=855452

     

    从以上消息队列中可以找到Flash中相关事件的消息 message 的内容,查阅API的相关资料,经过测试可以得知,message=992 是想要截获的消息,截获到这个消息后,可以使用threadkill IEprocess(有人可能说这里可以直接将截获到的消息丢掉,实际上这是行不通的,有些钩子只能查看消息,不能修改消息,也不能通过返回非0值阻止消息继续传递。很不幸,我们用到的WH_CALLWNDPROC就是其中之一。MSDN里说得很清楚:After the hook procedure returns control to the system, the message is passed to the window procedure. 不过WH_GETMESSAGE钩子可以修改消息,大家可以试试看)

     

           #region 阻止Flash打开URL

            private Thread killThread;

            protected override void WndProc(ref Message m)

            {

                base.WndProc(ref m);

     

                if (m.Msg == 992)

                {

                    if (killThread != null)

                    {

                        killThread.Abort();

                    }

     

                    killThread = new System.Threading.Thread(new System.Threading.ThreadStart(KillIE));

                    killThread.IsBackground = true;

                    killThread.Start();

                }

            }

     

            private void KillIE()

            {

                bool isKilled = false;

                while (!isKilled)

                {

                    System.Threading.Thread.Sleep(10);

                   //这里当然也可以是关闭firefox/maxthon 等其他浏览器

                    Process[] processes = System.Diagnostics.Process.GetProcessesByName("iexplore");

                    foreach (Process ps in processes)

                    {

                        ps.Kill();

                        isKilled = true;

                        break;

                    }

                }

            }

            #endregion

     

    【小结】

    本文只是在做项目的过程中碰到一个小的需求而进行的一个测验,解决方案有很多,目前为止这是我找到的一个性能比较高的方案,供大家参考,谢谢!

     

    全文完

     

    附件:源程序FlashUrlTest.rar,我的.net2.0版本为 2.0.50727,请注意

  • 相关阅读:
    java对象序列化机制
    进程和线程的区别
    关于Java中的String类的不可变
    计算机编码ASCII、UNICODE和UTF-8
    mybatis中的一级缓存和二级缓存
    SQL语句之EXSITS谓词
    git学习笔记
    hdu1542-扫描线求矩形面积并
    首场ACM总结——2019JXCPC(CCPC江西省省赛)
    hdu1199(离散化线段树)
  • 原文地址:https://www.cnblogs.com/hxhbluestar/p/277226.html
Copyright © 2011-2022 走看看