聲明
本文僅供學(xué)習(xí)參考,請勿將其用于任何違法操作。本文中所涉及的技術(shù)和方法僅用于解析和理解游戲開發(fā)中可能存在的漏洞和調(diào)試技巧,并非用于破壞游戲平衡、修改游戲數(shù)據(jù)或進行其他違法行為。本人強烈呼吁讀者遵守法律法規(guī),尊重游戲開發(fā)者的勞動成果和游戲規(guī)則,并在合法范圍內(nèi)進行學(xué)習(xí)和研究。如因不當使用本文所述方法導(dǎo)致任何違法行為或造成任何不良后果,責(zé)任將完全由使用者自行承擔(dān)。
環(huán)境
本文使用Edge瀏覽器進行示范

Edge
原理
由于4399屏蔽了F12、Ctrl+Shift+I和右鍵菜單,我們直接通過瀏覽器菜單中的開發(fā)人員工具(以下稱為開發(fā)者工具)選項打開開發(fā)者工具。

這時候瀏覽器被強制暫停了,同時開發(fā)者工具中定位到了虛擬機中運行的匿名函數(shù),里面有一個
debugger。

我們使用快捷鍵Ctrl+Shift+F全局搜索
debugger。
搜索debugger
定位到前兩處搜索結(jié)果。

前兩處搜索結(jié)果
其中
function() {}['constructor']('debugger')等價于new Function('debugger'),意思是將debugger這句代碼當成函數(shù)體,js中寫入debugger并在打開開發(fā)者工具的前提下會使網(wǎng)頁進入斷點調(diào)試模式,搭配上setInterval()定時器,可以做到無限觸發(fā)調(diào)試模式的效果。然后定位到第三處搜索結(jié)果。

第三次搜索結(jié)果
依然是在定時器中使用了
debugger,不同的是這里沒有運行在虛擬機中。這里使用了after.getTime() - before.getTime() > 2000判斷執(zhí)行時間是不是超過了兩秒,因為打開控制臺的時候會阻塞代碼(js是單線程的),會導(dǎo)致兩次定時器運行的時間間隔變長,從而判斷控制臺被打開了。另外Anti_numtots>=2判斷了是否有兩次的執(zhí)行時間超過了100毫秒,如果超過了,也算作打開了開發(fā)者工具。如果發(fā)現(xiàn)打開了開發(fā)者工具,則提示彈窗,并且刷新網(wǎng)頁。自此我們大致了解了4399屏蔽開發(fā)者工具的原理(為什么是大致?看到后面就懂了)。
然后我們可以開始阻止4399的無限debugger了
以下將使用替換法:
首先在左側(cè)文件列表中找到Antiindulgence.js文件。

Antiindulgence.js
右鍵選擇替代內(nèi)容

替代內(nèi)容
這時候開發(fā)者工具提示我們要把Antiindulgence.js文件存儲在哪里,我們可以隨便選擇一個空文件夾。

提示
選擇完成后瀏覽器會提示我們是否要給予這個目錄的訪問權(quán)限,我們選擇允許。

權(quán)限
這時候Antiindulgence.js文件就被保存到了本地,當瀏覽器中運行Antiindulgence.js文件的時候會使用這個本地的文件代換服務(wù)器上的文件。

使用文本方式打開Antiindulgence.js文件。然后刪除以下代碼即可。

刪除這些代碼
//瘋狂調(diào)試模式
setInterval(function(){
check();
}, 2000);
var check = function(){
function doCheck(a){
if (('' + a / a)['length'] !== 1 || a % 20 === 0){
(function() {}['constructor']('debugger')());
} else {
(function() {}['constructor']('debugger')());
}
doCheck(++a);
}
try {
doCheck(0);
}catch(err){}
};
check();
function consoleOpenCallback() {
alert('關(guān)閉調(diào)試窗');
window.location.reload();
}
var Anti_numtots = 0;
(function () {
window._windon_handler = setInterval( function() {
var before = new Date();
debugger;
var after = new Date();
if (after.getTime() - before.getTime() > 100) {
if (after.getTime() - before.getTime() > 2000) {
consoleOpenCallback();
clearInterval(_windon_handler);
}else{
Anti_numtots++;
if(Anti_numtots>=2){
consoleOpenCallback();
clearInterval(_windon_handler);
}
}
}else{
Anti_numtots = 0;
}
}, 1000)
})();
然后刷新網(wǎng)頁,可以正常運行了。
emmm運行了一會兒發(fā)現(xiàn)又被暫停了。

這是從哪里冒出來的?我們查看調(diào)用棧,找到了一處令人懷疑的地方。

這個函數(shù)內(nèi)創(chuàng)建了一個script標簽,atob是js內(nèi)置的解析Base64編碼字符串的函數(shù),我們在控制臺中執(zhí)行
atob("KGZ1bmN0aW9uIGEoKXt0cnl7KGZ1bmN0aW9uIGIoKXtkZWJ1Z2dlcjtiKCl9KSgpfWNhdGNoKGUpe3NldFRpbWVvdXQoYSw1ZTMpfX0pKCk")。
好家伙,果然是罪魁禍首。
我們也可以使用上面提到的替換法,將BuildWeb.framework.js文件替換成本地的。

我們直接在本地刪除函數(shù)
_JS_PokiSDK_preInit的函數(shù)體。
我這里直接注釋掉了
刷新網(wǎng)頁。至此所有問題都解決啦!!
其他
在上面提到的Antiindulgence.js文件中,我們可以找到屏蔽F12、Ctrl+Shift+I和右鍵菜單的代碼,用替換法刪除這些代碼即可恢復(fù)這些功能

屏蔽F12、Ctrl+Shift+I和右鍵菜單的代碼