最近作者看了一些关于JavaScript反调试的帖子,今天给大家整理一下希望有帮助哦~~~
前言
对于JavaScript来说,你只需要花一点时间进行调试和分析,你就能够了解到JavaScript代码段的功能逻辑。而我们所要讨论的内容,可以给那些想要分析你JavaScript代码的人增加一定的难度。不过我们的技术跟代码混淆无关,我们主要针对的是如何给代码主动调试增加困难。
本文所要介绍的技术方法大致如下:
1. 检测未知的执行环境(我们的代码只想在浏览器中被执行);
2. 检测调试工具(例如DevTools);
3. 代码完整性控制;
4. 流完整性控制;
5. 反模拟;
就是如果我们监控到到了“非正常”的情况,程序的运行流程将会改变,并跳转到伪造的代码块,并“隐藏”真正的功能代码。
一、对函数的重新定义
这是一种最基本也是最常用的代码反调试技能了。在JavaScript中,咱们能够对用于搜集信息的函数进行重新定义。例如,函数console.log()能够用来搜集函数和变量等信息,并将其显现在操控台中。例如我们把这个函数重新定义一下,就能够修改函数的行为,并隐去特定信息或显现假的信息。
可以在控制台直接运行这个函数来看一下结果:
#测试代码块
console.log("HelloWorld");
var fake = function() {};
window['console']['log']= fake;
console.log("Youcan't see me!");
运行后结果:
VM48:1 Hello World
如上测试代码,第二个信息console.log()信息并输出,因为我们把console.log()函数给重新定义了,即“禁用”了它原有的功能。但是我们也可以让它显示伪造后的信息,例如:
console.log("Normalfunction");
//First we save a reference to the original console.log functionvar
original = window['console']['log'];
//Next we create our fake function//Basicly we check the argument and if match we call original function with otherparam.
// If there is no match pass the argument to the original function
var fake = function(argument) {
if (argument === "Ka0labs") {
original("Spoofed!");
} else {
original(argument);
}
}
// We redefine now console.log as our fake function
window['console']['log']= fake;
//Then we call console.log with any argument
console.log("Thisis unaltered");
//Now we should see other text in console different to "Ka0labs"
console.log("Ka0labs");
//Aaaand everything still OK
console.log("Byebye!");
输出结果:
Normal function
VM117:11 This is unaltered
VM117:9 Spoofed!
VM117:11 Bye bye!
实际上,为了操控代码的运行方式,咱们还能用更好的方法来修正函数的功用。例如,根据上述代码来构建一个代码段,对eval函数重新定义。就能够把JavaScript代码传递给eval函数,接下来代码将会被计算并运行。假如咱们重新定义了这个函数,咱们就能够运行不同的代码了:
//Just a normal eval
eval("console.log('1337')");
//Now we repat the process...
var original = eval;
var fake = function(argument) {
// If the code to be evaluated contains1337...
if (argument.indexOf("1337") !==-1) {
// ... we just execute a different code
original("for (i = 0; i < 10;i++) { console.log(i);}");
} else {
original(argument);
}
}
eval= fake;
eval("console.log('Weshould see this...')");
//Now we should see the execution of a for loop instead of what is expected
eval("console.log('Too1337 for you!')");
输出运行结果:
1337
VM146:1We should see this…
VM147:10
VM147:11
VM147:12
VM147:13
VM147:14
VM147:15
VM147:16
VM147:17
VM147:18
VM147:19
这样的方法虽然非常巧妙,但这也只是一种非常基础并且常见的方法,也容易被检测到。
二、断点
我们在了解代码的功能的时候,一般通过JavaScript调试工具(例如DevTools)通过设置断点的方式来中断或阻止脚本代码的执行,而断点也是代码调试中最基本的了。
如果你研究过调试器或者x86架构,你可能会比较熟悉0xCC指令。在JavaScript中,我们有一个名叫debugger的类似指令。当我们在代码中声明了debugger函数后,脚本代码将会在debugger指令这里停止运行。比如说:
console.log("Seeme!");
debugger;
console.log("Seeme!");
许多商业产品会在代码中设置一个无限循环的debugger指令,不过某些浏览器会屏蔽这种代码,而有些则不会。这种办法的首要意图就是让那些想要调试你代码的人感到厌烦,由于无限循环意味着代码会不断地弹出窗口来问询你是否要继续运转脚本代码:
setTimeout(function(){while (true) {eval("debugger")
更多精彩内容可以关注“IT实战联盟”微信公众号,也可以留言和作者互动或者加入我们实战交流群哦~~~
注意:本文归作者所有,未经作者允许,不得转载