如何防止他人惡意調試你的 web 程序

1前言

看到社區很多都在討論如何調試,如何高級的調試,以及一些調試的奇技淫巧,今天我想和大家聊聊,怎麼禁止調試,禁止他人調試我們的程序

爲什麼會有這篇文章呢,源自一次我尋找盜版電影的遭遇,一次好奇心的驅使下,由於很多這種平臺都是隻做搬運,不做存儲,因爲存儲盜版電影向他人提供是違法的,特別是那種剛出的新電影! 當時好奇想通過看某站的控制檯,想了解一下他們是怎麼是通過啥接口,怎麼請求,請求來的格式啥樣的,抱着這樣的好奇心,開始了我的奇妙之旅...

看完本篇文章你將學會
我無法斷定你能學到什麼,但是以下是我希望你能從本篇文章中學到的:

  1. 如何簡單的防止你的程序被他人惡意調試
  2. 逆向思維學會如何更好的調試

2具體實現

防止調試的方法,這裏我們主要是通過不斷debugger的方法來瘋狂輸出斷點,讓控制檯打開後程序就無法正常執行
我們都知道debugger只有在控制檯被打開的時候纔會執行,所以後面的所有方法都是圍繞着這一特性來進行,廢話不多說,我將通過以下幾個案例向你們展示道高一尺魔高一丈的道理,先上代碼:

方法一:

(() => {
    function block({
        setInterval(() => {
            debugger;
        }, 50);
    }
    try {
        block();
    } catch (err) {}
})();

通過上方的代碼我們可以看到,在頁面中打開控制檯後,會有以下結果:

需要在這裏說明以下幾點:

  1. 程序被 debugger阻泄了,我們無法像以往一樣在 Source Tab 中的對應 js 代碼處添加斷點調試,無法調試程序的執行邏輯.在程序異常複雜且被混淆後的代碼是異常難讀的!通常我們會在 source 的左邊加上 breakpoint 來讓程序每次走到加點的地方停下來,以便讓我們查看一些變量的值或是步驟的流程邏輯(如下圖所示)
  1. 我們都知道,第一次打開控制檯是看不到 network tab 中的任何請求的,所以我們想通過 network tab 來查看網頁都做了哪些請求,也是看不到的,當我們打開控制檯就會出 debugger阻擋我們,我們可以通過下面的解決方法來處理,或者是用抓包工具來查看具體的請求

大家可以先不看解決方法,想想如果是你,這個時候怎麼突破這個屏障呢? 第一次遇到這種情況我也是很懵,不知道咋處理,後面發現問題簡直不要太簡單,我們可以帶着疑問來看:

對於第一個示例,我們如何解決?(繞過它)

答案是: 禁止斷點

可以看到很簡單,在 Chrome 控制檯的 Source Tab 頁點擊 Deactivate breakpoints 按鈕或者按下 Ctrl + f8(如下圖所示)。但是對於控制檯不熟悉的小夥伴,很難會想到這裏去.

但是,難道這篇文章就這樣結束了?那我可頂不住小夥伴們的 "就這?" 😂

其實,上面的解決方法並沒有幫我們解決根本問題,我們需要做的是調試,上面雖然把debugger都去掉了,但是我們也無法在通過點擊每一行代碼左邊的行號添加 breakpoint,所以根本性的問題,並沒有解決,只是去除了那礙眼的瘋狂 debugger,我們還是得另闢蹊徑

方法二:

對對應的代碼行,通過添加logpoint爲 false,然後按回車後刷新網頁,發現成功跳過無限 debugger,於是我們就可以愉快的自由調試了~

對應的還有一種方法

即通過add script ignore list來添加需要忽略執行代碼行或文件


可以看到,我們也可以通過刪除 script ignore list 裏已添加的忽略代碼,恢復初始狀態

但是,你這麼聰明,那人家不得想想對策?

對於上面的第一個方法 🎈

setInterval(() => {debugger;}, 50);寫在一行中,你即使通過添加logpoint爲 false,也沒用,仍然是瘋狂 debugger,即使你可能想到,通過左下角的代碼格式化,來格式一下setInterval(() => {debugger;}, 50);將它變成多行的,也是沒用的,仍然會在刷新後重新彈 debugger

(() => {
    function block({
        setInterval(() => {debugger;}, 50);
    }
    try {
        block();
    } catch (err) {}
})();

對於第二個方法,我們對代碼進行如下改造😬

(() => {
    function block({
        setInterval(() => {
            Function("debugger")();
        }, 50);
    }
    try {
        block();
    } catch (err) {}
})();

我們可以通過將debugger改寫成Function("debugger")();的形式,來應對;Function 構造器生成的 debugger 會在每一次執行時開啓一個臨時 js 文件,哈哈~對方表示好無奈 😅

於是會有以下結果

這無限套娃,真夠狠的,我們要堅信正義最後總會勝利,不能給想非法調試我們程序的人機會,所以我們要把各種情況都考慮周全,可以說這種方法是最恨的,但是這還不算完~ (好傢伙~ 😀 想非法調試我程序,那你就得戰勝我)

強化以上方法

上面的代碼由於沒有加密混淆,多少可能還是會被別人讀一些,那麼我們加密混淆看看是啥樣的
好傢伙,你這咋讀?

eval(function(c,g,a,b,d,e){d=String;if(!"".replace(/^/,String)){for(;a--;)e[a]=b[a]||a;b=[function(f){return e[f]}];d=function(){return"\\w+"};a=1}for(;a--;)b[a]&&(c=c.replace(new RegExp("\\b"+d(a)+"\\b","g"),b[a]));return c}('(()=>{1 0(){2(()=>{3("4")()},5)}6{0()}7(8){}})();',9,9,"block function setInterval Function debugger 50 try catch err".split(" "),0,{}));

格式化後的樣子

我們繼續對代碼進行改造,讓對方儘量的難以識別我們的代碼
Function("debugger").call()改成(function(){return false;})["constructor"]("debugger")["call"]();並且,添加條件,當窗口外部寬高,和內部寬高的差值大於一定的值,我把 body 裏的內容全部清空掉,看你還能不能操作我的按鈕啊啥的~哈哈哈 😀

需要特別說明的是: 像 toG 的項目或者是一些爲了保護自己的版權又或者是一些比較敏感的項目,出於安全的考慮在部署到生產環境後最好是不讓別人調試的,當然,前端所做的也就那麼一些,需要前後端一起配合,便可以很好的對項目或者數據進行私密的保護 🧡

最後: 附上這份未混淆的來之不易的的代碼(記得混淆後使用哦~) 😢 一定要記得點贊加關注~原創太不容易了.

你可以把它當作你的工具函數,在需要不讓別人輕易調試的項目中引用

(() => {
    function block({
        if (
            window.outerHeight - window.innerHeight > 200 ||
            window.outerWidth - window.innerWidth > 200
        ) {
            document.body.innerHTML =
                "檢測到非法調試,請關閉後刷新重試!";
        }
        setInterval(() => {
            (function ({
                return false;
            }
                ["constructor"]("debugger")
                ["call"]());
        }, 50);
    }
    try {
        block();
    } catch (err) {}
})();

3推薦一個調試頁面的小技巧

說了那麼多的防止被人調試,那麼最後也說一個本人覺得眼前一亮的調試樣式的方法
通過給style標籤添加style="display: block",contenteditable兩個屬性實現在頁面中便捷的調試樣式

複製下方代碼到你的 html 文件中,玩一下~

<!DOCTYPE html>
<body>
    <div>來調試我吧~</div>
    <style style="display: block" contenteditable>
        body {
            background-colorrgb(140209230);
            color: white;
        }
        div {
            background-color: green;
            width300px;
            height300px;
            line-height300px;
            text-align: center;
        }
    
</style>
</body>

4最後

我所知道的禁止調試的方法就只有如上所述,但是肯定還有很多好玩的,小夥伴們可以在評論區留言,一起共同學習~

最後拋出一個問題,如何監測控制檯是否被打開(我上面提到過),感興趣且有頭緒,或者已經有方法的小夥伴可以小夥伴可以在評論下方說說自己的想法,也可以加我們交流羣一起玩耍~

本文分享自微信公衆號 - 1024譯站(trans1024)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章