恶搞英语大厅的原理(准确来说应该是恶搞IE)

恶搞英语大厅的原理(准确来说应该是恶搞IE)

源代码下载地址:  http://download.csdn.net/detail/linger2012liu/4033059

由于个人知识有限,若发现不对,敬请指正。

恶搞程序的本意应该不是针对我们学校的英语大厅,而是IE。恰好英语大厅是用的是IE内核,于是我们也可以用它来恶搞大厅了。

恶搞是这样子的:修改某网页的源代码(当然是在我们客户端),然后更新显示。正如作者所描述的:“此程序除了恶搞外,其实就是一个IE内容修改的程序!还有什么用途~~

发挥你的想象力吧!“

那么我们恶搞大厅时各个步骤做了什么呢?下面分析一下。首先,点击左上角的“放大镜”并拖到英语大厅,该步骤是获取大厅的窗口句柄,并根据句柄获得该窗口的html代码。然后我们把一段html代码(可能夹杂着javascript代码)插入到代码中的适当位置。这时,大厅会出现一个按钮,点击按钮后,会出发相应的javascript的运行。插入的代码不同,效果也不同,比如可能是显示正确答案,可能是把正确答案都填上去了。

由于现在上不了大厅了,所以我直接拿网页做测试,当然原理都是一样的。首先写以下html代码,另存为test.html。

<html>

<body>

<p>请点击这里</p>

<!-- <pοnmοusedοwn='alert("hehe")'>请点击这里</p> -->

</body>

</html>

 

打开改网页,将放大镜放到网页上,抓取html代码,恶搞显示如下:


修改以下代码,点击开始恶搞,如下(主要是把注释的代码复制到前面,把点击事件添加到文本中)

 

这时,剧本应该是这样演的,点击文本后会弹出提示框。但也许是我IE设置问题,出现如下,


然后就点击那里允许执行阻止的内容,其实就是js代码。再点击一下开始恶搞(因为刚才的操作可能自动重新加载页面了)。到网页中,点击文字,出现提示框了。设想成功,恶搞就是修改IE代码的功能。

 

那么接下来是怎么写一个修改一个IE的网页源代码的程序。查阅了相关的知识,实现主要是这样:打开网页,找到要修改网页的窗口句柄,根据句柄改掉对应网页的内容。这种方法,因为是用窗口句柄做中介的,因此肯定也适合英语大厅等一类用IE内核的程序。

首先新建一个c#的控制台程序,我这里命名为fuckIE,在引用中添加Microsoft.mshtml这个引用。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Windows.Forms;

usingSystem.Runtime.InteropServices;

using mshtml;

namespace fuckIE

{

    class Program

{

//一些api函数的声明

        [DllImport("USER32.DLL")]

        public static extern IntPtr FindWindow(stringlpClassName, string lpWindowName);

 

        [DllImport("user32.dll")]

        privatestatic extern IntPtr FindWindowEx(IntPtrhwndParent, IntPtr hwndChildAfter, string lpszClass, stringlpszWindow);

 

        [DllImport("user32.dll", EntryPoint = "EnumChildWindows")]

        public static extern bool EnumChildWindows(IntPtrhwndParent, EnumChildProc EnumFunc, IntPtr lParam);

 

 

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]

        public static extern uint RegisterWindowMessage(stringlpString);

 

        [DllImport("oleacc.dll", PreserveSig = false)]

        [return:MarshalAs(UnmanagedType.Interface)]

        public static extern object ObjectFromLresult(UIntPtrlResult, [MarshalAs(UnmanagedType.LPStruct)]Guid refiid, IntPtrwParam);

 

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]

        public static extern IntPtr SendMessageTimeout(IntPtrhWnd, uint Msg, UIntPtrwParam, IntPtr lParam, SendMessageTimeoutFlags fuFlags, uint uTimeout, out UIntPtr lpdwResult);

 

        public enum SendMessageTimeoutFlags:

        uint

        {

            SMTO_NORMAL = 0x0000,

            SMTO_BLOCK = 0x0001,

            SMTO_ABORTIFHUNG = 0x0002,

            SMTO_NOTIMEOUTIFNOTHUNG = 0x0008

        }

 

 

       public IntPtr destHandle = IntPtr.Zero;

        public delegate bool EnumChildProc(IntPtrhwnd, IntPtr lParam);

 

        boolFindChildClassHwnd(IntPtr hwndParent, IntPtr lParam)

        {//该函数用来从一个顶级窗口(我这里是IE的打开的某网页)查找类名为Internet Explorer_Server的子窗口

            IntPtrhwnd = FindWindowEx(hwndParent, IntPtr.Zero,"Internet Explorer_Server", null);

           

            if(hwnd != IntPtr.Zero)

            {

                //pfw->m_hWnd= hwnd;        // found: save it

                destHandle = hwnd;

                returnfalse;                            // stop enumerating

            }

            EnumChildWindows(hwndParent,FindChildClassHwnd, lParam); // recurse

//每段枚举子窗口,递归调用

            returntrue;

        }

                                  // keep looking

        

        [STAThreadAttribute]

        static void Main(string[]args)

        {

       

          //  IntPtr ieh = FindWindow("InternetExplorer_Server",null); //这样会失败,因为这只能适合顶级窗口

            IntPtrieh = FindWindow(null, "E:\\past\\恶搞\\fuckIE\\fuckIE\\test.html- linger");

//首先找到顶级窗口,第二个参数为窗口标题,即如下图片的左上角的文字


            Console.WriteLine("ie句?柄À¨²:êo"+ieh);

            E:\past\恶?搞?\fuckIE\fuckIE\test.html - linger

            if(ieh == IntPtr.Zero)

            {

                Console.WriteLine("can not find the window");

                return;

            }

 

            Programinstance = new Program();

            instance.FindChildClassHwnd(ieh, IntPtr.Zero);

//查找类名为InternetExplorer_Server的子窗口

 

            if(instance.destHandle == IntPtr.Zero)

            {

                Console.WriteLine("can not find the window");

                return;

            }

            Console.WriteLine("目?标À¨º句?柄À¨²"+instance.destHandle);

           //目标句柄找对了,注意用spy++找的 是16进制

 

            UIntPtrlRes = new UIntPtr();

 

            uintapp2_GenerateEvent = RegisterWindowMessage("WM_HTML_GETOBJECT");

           SendMessageTimeout(instance.destHandle, app2_GenerateEvent, UIntPtr.Zero, IntPtr.Zero,SendMessageTimeoutFlags.SMTO_NOTIMEOUTIFNOTHUNG,1000, out lRes);

 

            //IHTMLDocument得Ì?不?到Ì?body.innerHTML

            IHTMLDocument2obj = (IHTMLDocument2)ObjectFromLresult(lRes,typeof(IHTMLDocument).GUID,IntPtr.Zero);

            Console.WriteLine(obj.body.innerHTML);

            //obj.body.innerHTML= "<p οnmοuseοver='alert(\"hehe\")'>本À?来¤¡ä什º2么¡ä都?没?有®D的Ì?</p>";

 

            obj.body.innerHTML = " <pοnmοusedοwn='alert(\"hehe\")'>请点击这里</p>";

//修改为自己想要的代码

                       Console.WriteLine(obj.body.innerHTML);

 

        }

    }

}

 

 

 

 

 

 

下面测试效果。

打开test.html网页,此时不要点击其他网页, 也不要最小化IE浏览器,不然是找不到该句柄的。(人家恶搞的程序是用拖拽放大镜的方法找的,我对界面编程不是很了解,所以只好用窗口标题找窗口句柄。)


运行程序,


还是出现这个,


点击那里,再点击“允许阻止的内容”,出现下面对话框,再点确定。


关闭刚才打开的控制台程序,再次运行。

到网页中点击那里的文字,实验成功!!!

 

有个疑问就会如果查看该网页源代码,发现源代码并没有改掉,对浏览器的机理还不是很了解啊。不过猜测,IE这个查看源文件的功能,可能是从服务器那里拿来的,当然我这里是本地文件,服务器就是自己电脑。

                                                      

一个恶搞程序大概如此。如果把上面的c#代码稍微修改一下, 就可以用到英语大厅了。主要是窗口标题名,和怎么修改html代码。前者比较容易,用任务管理器就可以准确看到进程的窗口标题名,英语大厅也不例外,当然我电脑没有大厅。


至于修改html代码就是做一些字符串处理,还要懂一些javascript。当然,修改html之前,得研究一下源代码,看一下怎么可以用javascript把答案显示出来,或者把答案填上去。

看了之前的两份插入代码,都是在原有html里添加一个button,然后触发一个javascript事件,一是显示正确答案,二是把正确答案填上去。

还有,我们可以恶搞英语大厅的一个前提,是答案已存在我们客户端电脑里,也许做大厅软件的队伍为了方便还是为了减轻服务端的压力,把答案检测放在客户端进行,服务端负责接收分数就可以了。所以,我觉得恶搞大厅有3种渠道,一是分数的来源,二是分数的缓存,三是数据包。第一,我们IE恶搞的方法就是属于对分数的来源做处理,把正确答案填上去,分数自然高。第二,我想在客户端里一定有几个变量用来存储分数,只要修改了他们即可,也许在javascript就有。第三,分数检测出后,肯定会给服务端发送包含分数的数据包,只要伪造一个数据包,发送过去,你想拿多少分都可以。

     更正:后来苏淦告诉我上面所说的3种方法后两种还是不行的,因为大厅记录了我们的答案,应该是把我们填的答案也提交上去了吧,不可能傻逼到存在本地磁盘

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值