美文网首页
网页小游戏的JS注入学习笔记

网页小游戏的JS注入学习笔记

作者: DHFE | 来源:发表于2018-10-06 23:01 被阅读38次

    这篇文章来源于看了以下这篇文章和游戏后所想所写:
    网页颜色分辨测试小游戏的js化辨别及优化
    测测你的眼睛对色差的辨识度

    游戏也是一个很简易的网页小游戏。


    作者使用F12发现图形块颜色都是在前端生成这一小漏洞,写了一个小工具自动化闯关。

    // 作者源码
    
    //取到所有background
    var stylelist = new Array();
    
    $("#box span").each(function() {
        for(var i = 0; i < $("#box span").length; i++) {
            stylelist[i] = $(this).attr("style");
        }
    });
    //分割数组
    var s = stylelist.join(",") + ",",
        copy;
    for(var i = 0; i < stylelist.length; i++) {
        //取出唯一style
        if(s.replace(stylelist[i] + ",", "").indexOf(stylelist[i] + ",") > -1) {
            copy = stylelist[i];
        }
    }
    //不解释了吧
    $("#box span").each(function() {
        if($(this).attr("style") != copy) 
        $(this).click(); 
        return;
    });
    

    分割数组那块当时没看懂,后来懂了。
    s保存着所有spanstyle值的join连接后的字串,将字串用replace替换为空值,然后用indexOf在stylelist中查找,如果有值(0 > -1 )说明此值会重复,否则此值为only ,然后保存好重复的style值,对比替换即可。

    原UP评论下有同学提到可以暴力循环点击每个元素,试了下发现可行,分数也比原来提高很多。(4000 > 7000),想来,一是省略了很多for循环,取元素的步骤,的确提高性能。

    我在后续使用原生JS重写了一次,然后在60s中跑出了如下成绩:

    document.getElementsByClassName("btn")[0].addEventListener("click", function () {
        var fn = function () {
            var length = document.querySelectorAll("#box span").length;
            for (var i = 0; i < length; i++) {
                document.querySelectorAll("#box span")[i].click();
            }
        };
        setInterval(fn, 0);
    })
    

    最后想进一步优化,setInterval使用的是JS引擎的event loop模型,其回调会放入事件队列中等待主线程任务执行完毕后才会执行回调,那么可以使用for循环代替setInterval来省略这其中等待的时间吗?

    document.getElementsByClassName("btn")[0].addEventListener("click", function () {
        var fn = function () {
            var arr = document.querySelectorAll("#box span");
            var length = arr.length;
    
            for (var i = 0; i < length; i++) {
                arr[i].click();
            }
        };
        for (var j = 0; j < 30000; j++) {
            fn();
        }
    })
    

    点击开始测试按钮后,页面没有了响应(也无法刷新),为什么?

    我的想法是,这个游戏本身的计时器也是使用setInterval或者setTimeout来计时的,for循环在执行这30000次循环时候,主线程一直在工作,所以事件队列内的回调函数无法执行,当然没有响应,并且我们也知道在浏览器中JS执行的时候,其浏览器的渲染引擎也是被阻塞,不工作的,所以在页面上我们看不到任何的色块。

    而且因为这种操作十分占用CPU,导致整个Chrome进程都巨卡无比,差点浏览器就崩溃了。

    点击按钮后我开了个秒表,大慨在49s左右,主线程执行完毕,瞬间页面就跳了出来。


    看到左上角的30000了吗?哈哈。

    感谢原作者的文章,让我对一些游戏外挂有了全新的认识。

    相关文章

      网友评论

          本文标题:网页小游戏的JS注入学习笔记

          本文链接:https://www.haomeiwen.com/subject/zuvcaftx.html