JS调试与反调试

JS调试与反调试

基础知识

浏览器调试检测

  1. 开发者工具栏检测

    /*
    * 通过内外高宽判断是否开启开发者工具
    * 缺点:本身就容易造成误判,因此一般服务方不采用该方法
    * */
    var isDevToolsOpen = false;
    
    function detectDevTools(interval_id) {
        const threshold = 600;
        const width = window.outerWidth - window.innerWidth;
        const height = window.outerHeight - window.innerHeight;
    
        if (width > threshold || height > threshold){
            // 被调试,执行反制手段
            isDevToolsOpen = true;
            // 反制函数
            alert("you are captured !!!");
            // 拆除interval
            clearInterval(intervalDetectId)
        }
    }
    // 不间断检测是否开启调试工具
    var intervalDetectId = setInterval(
        detectDevTools,1000,
    )
    

    破解方法:js文件劫持、将调试窗口与主窗口分离

  2. 通过代码执行时间

    /*
    * 通过代码执行时间来判断是否被调试,特殊代码debugger在调试状态下会暂停程序运行
    * 缺点:
    * */
    var isDevToolsOpen = false;
    
    function detectDevTools() {
    
        var startTime = Date.now();
        for(let i=0;i<3;i++){
            eval('debugger');
        }
        var endTime = Date.now();
        console.log(endTime-startTime)
        var isDev = endTime-startTime> 100;
    
        if (isDev){
            // 被调试,执行反制手段
            isDevToolsOpen = true;
            // 反制函数
            alert("you are captured !!!");
            // 拆除interval
            clearInterval(intervalDetectId)
        }
    }
    // 不间断检测是否开启调试工具
    var intervalDetectId = setInterval(
        detectDevTools,1000,
    )
    

    破解方法:js文件劫持、hook关键函数

  • 补充:此外还有一些其他放大,但可能并不适用,目前暂没发现其他有效的方法。

Debugger专区

/*
	既可以作为检测的一部分,也可以直接干扰调试者。
	debugger只在调试状态下有效,因此可以基于debugger干扰分析者。
	例如:无限debugger(函数自调、定时任务、循环定时任务等)
*/
  1. 无限debuuger
/*
* 无限debugger
*
* */
function debuggers() {
    eval("debugger");
}
setInterval(debuggers,1000);

解决方案:文件劫持、hook函数

  1. 混淆技术
/*
	更多的是使用混淆技术执行debugger,来增加调试者的难度
	较为详细的博客有:https://blog.csdn.net/xw1680/article/details/138547184
*/
/*
调用时混淆
	1)基于Function.constructor,直接Function或某一个类型向上找原型为Function。
		Function.constructor("debugger").call()
	2)基于Object.constructor
		Object.constructor("debugger").call()
		
debugger字符串混淆
	1)拆解:eval("debugg"+"er")
	
整个代码混淆
	在线网站等,如博客所提到:https://blog.csdn.net/qq_15326513/article/details/131741451
*/
  1. console.clear
/*
	console.clear()会清除控制台的调试信息,因此无限执行此函数能增加调试者的调试难度。多与setInterval一起
*/

function debuggers() {
    console.clear()
}
setInterval(debuggers,1000);

常用的反反调试

由于准确地检测调试存在困难,因此现在大多基于debugger来增加调试难度,故反反调试也多关注debugger

使用hook函数和文件劫持是最有效地方式。
  1. hook函数

    /*
    	通过hook函数的方式,能有效解决大多问题,例如hook “eval”函数
    	hook的主要步骤:1、保留原函数;2、重写函数;3、非目标调用原函数
    	优点:打击面积小,针对性强
    */
    var eval_src = eval;
    eval = function(args_str){
      if(args_str.toLowerCase().indexOf('debugger')!=-1){
        return;
      }else{
        eval_src(args_str);
      }
    }
    
  2. 文件劫持

    使用浏览器工具或其他代理工具进行劫持替换
    
  3. 条件断点等

测试实例

网站:https://www.aqistudy.cn/
尝试祛除反调试
1)针对index页面的调试检测
/*
<script type="text/javascript">

var debugflag = false;

  endebug(false, function () {
      document.write('检测到非法调试, 请关闭调试终端后刷新本页面重试!');
      document.write("<br/>");
      document.write("Welcome for People, Not Welcome for Machine!");
      debugflag = true;
  });
  //txsdefwsw();
  document.onkeydown = function() {
    if ((e.ctrlKey) && (e.keyCode == 83)) {
      alert("检测到非法调试,CTRL + S被管理员禁用");
      return false;
    }
  }
  document.onkeydown = function() {
    var e = window.event || arguments[0];
    if (e.keyCode == 123) {
      alert("检测到非法调试,F12被管理员禁用");
      return false;
    }
  }
  document.oncontextmenu = function() {
    alert('检测到非法调试,右键被管理员禁用');
    return false;
  }
	$(function()
	{
		if (!debugflag && !window.navigator.webdriver) {
      loadTab();
    }
		if(!isSupportCanvas())
		{
			$("#browertip").show();
		}
	});

	function isSupportCanvas()
	{
	   var elem = document.createElement('canvas');
	   return !!(elem.getContext && elem.getContext('2d'));
	}
	</script>
*/
解决方案:文件劫持,删除检测代码

2)针对关键eval执行的混淆代码:eval(d2EFOt36ua(`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`));
1、进入查看js代码:
/*
  var debugflag = false;
  document.onkeydown = function() {
    if ((e.ctrlKey) && (e.keyCode == 83)) {
      alert("检测到非法调试,CTRL + S被管理员禁用");
      return false;
    }
  }
  document.onkeydown = function() {
    var e = window.event || arguments[0];
    if (e.keyCode == 123) {
      alert("检测到非法调试,F12被管理员禁用");
      return false;
    }
  }
  document.oncontextmenu = function() {
    alert('检测到非法调试,右键被管理员禁用');
    return false;
  }
  !function () {
    const handler = setInterval(() => {
      if (window.outerWidth - window.innerWidth > 300 ||
       window.outerHeight - window.innerHeight > 300) {
        // document.write((window.outerWidth - window.innerWidth) + ',' + (window.outerHeight - window.innerHeight));
        document.write('检测到非法调试, 请关闭调试终端后刷新本页面重试!<br/>');
        document.write("Welcome for People, Not Welcome for Machine!<br/>");
        debugflag = true;
      }
      const before = new Date();
      (function() {}
        ["constructor"]("debugger")())
      const after = new Date();
      const cost = after.getTime() - before.getTime();
      if (cost > 50) {
        debugflag = true;
        document.write('检测到非法调试, 请关闭调试终端后刷新本页面重试!<br/>');
        document.write("Welcome for People, Not Welcome for Machine!<br/>");
      }

    }, 2000)
  }();
*/
2、分析进行了内外窗口判断,代码运行时间判断
解决方案:在eval外覆盖原内外窗口大小;hook "Function的构造函数"
window.outerWidth = 2056
window.innerWidth = 2000
window.outerHeight = 800
window.innerHeight = 700

var Function_constructor_s = Function.constructor

Function.prototype.constructor = function(args_str){
  if (args_str.toLowerCase().indexOf("debugger")!=-1){
    return function(){};
  }else{
    return Function_constructor_s(args_str);
  }
}

此外还发现无限调用console.clear(),没有再继续分析
  • 12
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值