前端实战篇:JavaScript 反调试技巧的简单应用(下)

代码界的吴彦祖 2018-03-21 16:39:57 ⋅ 169 阅读


上一篇:前端实战篇:JavaScript 反调试技巧的简单应用(上)


前言

上一篇我们通过对函数的重新定义和设置断点的方式来中断或阻止脚本的代码执行达到反调试的目的,这一篇我们继续探讨通过其他方式来反调试

三、时间差异

这是一种从传统反逆向技术那里借鉴过来的基于时间的反调试技巧。当脚本在DevTools等工具环境下执行时,运行速度会非常慢(时间久),所以我们就可以根据运行时间来判断脚本当前是否正在被调试。比如说,我们可以通过测量代码中两个设置点之间的运行时间,然后用这个值作为参考,如果运行时间超过这个值,说明脚本当前在调试器中运行。

实例代码如下:

set Interval(function(){  
var startTime = performance.now(), check,diff;  
for (check = 0; check < 1000; check++){    
   console.log(check);    
   console.clear();  } diff = performance.now() - startTime;  if (diff > 200){    alert("Debugger detected!");  } },500);

四、DevTools检测(Chrome)

这项技术利用的是div元素中的id属性,当div元素被发送至控制台(例如console.log(div))时,浏览器会自动尝试获取其中的元素id。如果代码在调用了console.log之后又调用了getter方法,说明控制台当前正在运行。
实例代码如下:

let div = document.createElement('div');

let loop = setInterval(() => {    
   console.log(div);    
   console.clear(); });
Object.defineProperty(div,"id", {get: () => {    clearInterval(loop);    alert("Dev Tools detected!"); }});

五、隐式流完整性控制

当我们尝试对代码进行反混淆处理时,我们首先会尝试重命名某些函数或变量,但是在JavaScript中我们可以检测函数名是否被修改过,或者说我们可以直接通过堆栈跟踪来获取其原始名称或调用顺序。

arguments.callee.caller可以帮助我们创建一个堆栈跟踪来存储之前执行过的函数,示例代码如下:

function getCallStack() { 
 
 var stack = "#",
 
 total = 0,
 
 fn =arguments.callee;    
 
 while ( (fn = fn.caller) ) {        stack = stack + "" +fn.name;        total++    }    
 return stack }function test1() {    
 
 console.log(getCallStack()); }function test2() {    test1(); }function test3() {    test2(); }function test4() {    test3(); } test4();

备注:源代码的混淆程度越强,达到的效果就越好。

六、代理对象

代理对象是目前JavaScript中最有用的一个工具,这种对象可以帮助我们了解代码中的其他对象,包括修改其行为以及触发特定环境下的对象活动。比如说,我们可以创建一个嗲哩对象并跟踪每一次document.createElemen调用,然后记录下相关信息:

const handler = { 
// Our hook to keep the trackapply: function (target, thisArg, args){
       
   console.log("Intercepted a call tocreateElement with args: " + args);        
   return target.apply(thisArg, args)    } }

控制台输出:

VM64:3 Intercepted a call to createElement with args: div

我们可以利用这些信息并通过拦截某些特定函数来调试代码,但是本文的主要目的是为了介绍反调试技术,那么我们如何检测“对方”是否使用了代理对象呢?其实这就是一场“猫抓老鼠”的游戏,比如说,我们可以使用相同的代码段,然后尝试调用toString方法并捕获异常:

try {    

   document.createElement.toString(); }catch(e){  

   console.log("I saw your proxy!"); }

信息如下:

"function createElement() { [native code] }"

使用代理结果查看:

consthandler = {    
   apply: function (target, thisArg, args){        
       console.log("Intercepted a call tocreateElement with args: " + args);
        return target.apply(thisArg, args)    } }
       
document.createElement= new Proxy(document.createElement, handler);
//Callour not-so-virgin-after-that-party createElement

try {    

   document
.createElement.toString(); }catch(e) {    

   console.log("I saw your proxy!"); }

输出结果:

VM391:13 I saw your proxy!

我们还可以添加toString方法:

const handler = {    
apply: function (target, thisArg, args){        
       console.log("Intercepted a call tocreateElement with args: " + args);        return target.apply(thisArg, args)    } }
document.createElement= new Proxy(document.createElement, handler);
document.createElement= Function.prototype.toString.bind(document.createElement);
//Add toString//Callour not-so-virgin-after-that-party createElementtry {    
document.createElement.toString(); }catch(e) {  
 console.log("I saw your proxy!"); }

输出结果:

"function createElement() { [native code] }"

更多精彩内容可以关注“IT实战联盟”公众号,也可以留言和作者互动或者加入我们交流群哦~~~




全部评论: 0

    我有话说:

    前端实战JavaScript 调试技巧简单应用(上)

    最近作者看了一些关于JavaScript调试帖子,今天给大家整理一下希望有帮助。

    前端实战-聊聊JavaScript内存

    内存生命周期、分配内存、使用分配内存(读与写操作),当应用程序不再需要时,释放掉已分配内存

    接上前端必看8个HTML+CSS技巧

    4款非常容易上手酷炫效果,值得收藏。

    前端实战—在Javascript中,Number类型超长问题详解

    今天给大家分享是在Javascript中,获取到数字超出长度问题。

    MySql实战:写一个简单存储过程,完成订单定时任务

    前言之前我们分享了MySql性能优化、索引详解等内容,本文章主要是针对想要入门MySql存储过程读者,主要实现业务是订单库里面超过30分钟没有支付订单全部置为失效订单......

    移动H5前端五大性能优化方案(实战

    移动H5前端五大性能优化方案(实战

    「转载」蘑菇街消息系统上云实践

    小编又来啦~本周要推荐给大家是一跟中间件上云相关技术文章,这里面详细记录了,蘑菇街自研消息系统上云全过程,也是市面上开放出来为数不多企业自研组件上云实践。有相关需求同学可以好好学习

    推荐一款前端数据源管理工具 algeb

    ALGEB 简介 这是一个比较抽象库,一开始可能比较难理解。我写它初衷,是创建可响应数据请求管理。在传统数据请求中,我们只是把携带ajax代码一堆函数放在一起,这样就可以调用接口。但是这种

    MySql实战:建立高性能Mysql技巧

    体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,一般中小型网站开发都选择 MySQL 作为网站数据库......

    架构实战:一个可供中小团队参考微服务架构技术

    作者近年一直在一线互联网公司(携程,拍拍贷等)开展微服务架构实践,根据我个人一线实践经验和我平时对Spring Cloud调研,我认为Spring Cloud技术栈中有些组件离生产级开发尚有

    2018年8个技巧来构建更好Node.js应用程序

    2018年8个技巧来构建更好Node.js应用程序

    架构实战:认识一微服务架构

    微服务是一个新兴软件架构,就是把一个大型单个应用程序和服务拆分为数十个支持微服务。

    【开源资讯】Electron 10.1.4 发布,跨平台桌面应用开发工具

    简介 Electron 是 GitHub 发布跨平台桌面应用开发工具,支持 Web 技术开发桌面应用,其本身是基于 C++ 开发,GUI 核心来自于 Chrome,而

    Node实战:Express-session解析(八)

    Session和HTTP协议属于不同层面事物,HTTP属于ISO七层模型最高层应用层,前者Session不属于后者,前者HTTP是具体动态页面技术实现,但同时它又是基于后者

    JAVA实现附近范围内公交定位问题

    接上前端实战:通过JS抓取城市所有站点与线路】获取附近定位信息

    抖音品质建设 - iOS启动优化《实战

    前言 启动是 App 给用户第一印象,启动越慢,用户流失概率就越高,良好启动速度是用户体验不可缺少一环。启动优化涉及到知识点非常多,面也很广,一文章难以包含全部,所以拆分成两部分:原理和

    简单】Docker - 实战TLS加密通讯

    快速配置一个最简单docker TLS加密通讯