JavaScript奇技淫巧:加密JS代碼反調試
JavaScript奇技淫巧:加密JS代碼反調試
JS代碼混淆加密,已被很多人使用,因為它真的很有用、很實用,可以用于保護代碼、防護分析、復制、盜用,還可以用于小游戲過審、APP加固等方面。
混淆加密后的JS代碼,可能被他人分析,為了對抗分析調試,本文分享一種反調試技術。
功能效果
使函數名不可修改,修改則代碼無法運行
技術原理
將JS代碼用可逆算法進行加密。公開或發(fā)布的代碼時,只提供這部分“密文”。
運行代碼中包含解密函數,但密鑰是隱式傳遞,難被發(fā)現。而且還可對解密函數再加密,使分析難上加難。
實例演示
示例代碼:

先用JShaman進行簡單的混淆,僅啟用函數名加密,為的是得到隨機的函數名,得到代碼如下:

函數名從原始的get_copyright變成了_0xag。
在分析調試時,分析者經常會將無意義的函數名改成有含義的名字,使便于理解。
本文我們要做的,就是禁止改名,如果修改函數名,函數就無法執(zhí)行。
繼續(xù)操作,處理以下幾行,即函數中包含的代碼:

采用xor算法,將其變成加密字符:

注意,加密時傳入的參數是“_0xag”,即代碼所在的函數名,此值在解密時是不會顯式出現的。
之前的代碼,改造為以下形式:

運行:

輸出結果與修改代碼前相同。
這段代碼的含意是:解密、并用eval執(zhí)行。這就達到了跟原始代碼一樣的功能效果。
精妙之處在于:解密時,并未傳入加密時的參數:“_0xag”!
而如果對函數進行改名,比如改為abc,執(zhí)行將會出錯:

這是由于:解密時隱式的使用了arguments.callee.name,即調用者函數名。
當函數名是_0xag時,與加密時傳入的密鑰參數一至,那么可以解出正確的代碼字符,也就可以被eval執(zhí)行,而函數名改為abc時,相當于傳入的字符就變成了abc,自然無法解密出正確的原始代碼,也就無法用eval執(zhí)行。
完整代碼
function random_key(key, i) {
return key.charCodeAt( Math.floor(i % key.length) );
}
function enxor(data, key) {
return data.split("").map(function(c,i,a){
return data.charCodeAt(i)^random_key(key,i);
}).join(",");
}
function dexor(data, key) {
return data.split(",").map(function(c,i,a){
return String.fromCharCode(c^random_key(key,i));
}).join("");
}
var js_code=`
var _0xbc99c = "jshaman.com";
var from_year = 523898 ^ 522651;
var _0x7d68de = "(c)" + from_year + "-" + new Date().getFullYear() + "," + _0xbc99c;
console.log(_0x7d68de);
`
function _0xag(){
var decode_js_code = dexor("85,70,25,19,71,0,0,0,3,4,102,9,27,65,90,127,18,18,18,15,62,93,25,15,73,60,95,21,67,92,85,70,25,19,71,57,66,23,12,56,38,85,25,19,71,98,16,77,83,84,103,9,64,65,57,127,5,74,83,81,106,1,67,107,17,62,66,88,62,87,39,7,28,87,95,59,85,88,92,71,125,24,27,72,69,127,27,88,7,21,48,93,39,24,2,62,66,88,74,71,125,29,90,65,76,127,94,29,22,71,27,81,12,4,79,118,30,31,4,19,25,69,20,13,62,58,81,10,73,78,127,27,88,67,75,125,16,83,65,56,111,72,26,2,94,102,83,67,107,4,48,94,11,14,11,58,30,20,14,0,119,111,72,25,80,59,6,64,5,2,118,11,114",arguments.callee.name);
eval(decode_js_code);
}
console.log(_0xag());