创作不易,希望点个赞!
如果本文有任何问题错误,欢迎评论指正!

(点个赞!点个赞!点个赞!点个赞!点个赞!点个赞!)

前面文章:

爬虫(js逆向)网络基础协议与抓包原理-chrome开发工具-fiddler抓包-重放攻击(1)
爬虫(js逆向)js基础-函数进阶-原型链(prototype、proto、构造函数-this绑定对象(2)
爬虫(js逆向)非指纹built-in函数-js进阶-混淆与伪代码-常见反爬措施-爬虫逆向方法论(3)
爬虫(js逆向)调试干扰-处理debugger-调试检测-内存爆破-JS逆向举例(4)

对于前面文章的补充:

  1. 关于之前讲述的控制台打开检测原理

    看到一个页面,并非单存的是通过html组成
    实际上是:html+css+javascript 组成
    关于html、css文章,我的博客有非常详细的介绍
    html_后端工程师必备知识-这些你都懂了吗?大概3w多字
    CSS_后端工程师必备知识-从入门到劝退详解-呕心沥血撰写(滑稽)写了大概4W多字,自认为非常详细
    而javascript的知识内容在前面博客有提及,包含我的有道云笔记(简写常用)(详细的可以看w3c教程)

  2. Autoresponseder 替换注意事项

    Autoresponseder 是fiddler的一个功能,使用方式在第一篇js逆向文章已经非常的详细讲述
    实际上,比如直接打开百度,看到的页面源代码,html+css+js,可以通过fiddler拦截其中比如js,编写自己的js规则

  3. 关于js的一些作用域问题

    负责收集并维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限。

    var a = 1;引擎会在定义这个变量的局部中寻找,比如定义在某个函数内,在函数内没有查找到,那么会接着查找,直到找到
    否则报错

    LHS 与 RHS作用域查询机制是什么?

    var a = 1;  // LHS查询:赋值操作左侧的查询,LHS查询试图找到变量的容器本身,,从而对其赋值。
    console.log(a) // RHS查询:赋值操作右侧的查询,可以理解为“取到某某的值”
    

    相关文章:
    https://www.h5w3.com/57138.html
    https://www.h5w3.com/62830.html
    https://www.h5w3.com/70576.html
    https://www.h5w3.com/34296.html
    https://www.h5w3.com/32056.html
    https://juejin.cn/post/6844904033308655623

一、hook定义

  • Hook 技术又叫做钩子函数,在系统没有调用该函数之前,钩子程序就先捕获该消息,钩子函数先得到控制权,这时钩子函数既可以加工处理(改变)该函数的执行行为,还可以强制结束消息的传递。

  • 简单来说,就是把系统的程序拉出来变成我们自己执行代码片段。

  • 在js中,系统程序可以指浏览器API,也可以指代码中实现的一些方法等

  • 分类:手动hook\自动hook

1 为什么能实现hook

客户端拥有js的最高解释权,可以决定在任何时候注入js而服务器无法左右

只能通过检测和混淆手段令hook难度加大,但是却无法阻止。

2 hook目的是什么

js hook目的是找到函数入口以及一些参数变化,便于分析js逻辑

但是 hook的能力远不及此。我们只借助其寻找函数入口。

二、hook使用

1 hook步骤

  1. 寻找hook点 (确定目标,想要hook浏览器的document或者eval函数等等,window.a,或者相关参数)
  2. 编写hook逻辑
  3. 调试

2 函数hook公式:

func为需要处理的函数,赋值给一个新的备份变量old_func,重写需要处理的函数方法funcarguments为函数传入的参数
mytask为处理业务的代码,打印,也可以写一个debugger方便调试,然后return old_func.apply(arguments),返回这个函数的调用

old_func = func
func = function(arguments){
	mytask;
	return old_func.apply(arguments)
}

那么hook的原理是什么呢?

第三篇文章,提及了原型链,重写了函数的方法,那么会发生改变
eval举例,先看原生的eval
在这里插入图片描述
修改后,可以明显的发现,其原型链指向的内容发生变化
在这里插入图片描述
那么通过上面的eval举例,实际上为了应对反爬措施(开发业务代码的,判断原型链是否发生了变化),利用了hook,可以伪装没有被修改,需要抹除被hook的痕迹,也就是需要生成对应的 伪造指纹,下面第三节的第3小节有讲述evalhook完毕需要伪造正常的指纹,避免被发现

func.prototype..... = .......
func :要hook的函数

3 对象中属性hook公式:

3.1 defineProperty方法

相关文章1
相关文章2(这篇文章直白易懂)

基本语法: Object.defineProperty(obj, prop, descriptor)

  • 参数(obj): 被操作的对象本身
  • 参数(prop): 属性名称, 指定对象要修改或者新增的属性名
  • 参数(descriptor): 对属性的描述(如 value指定属性的值)

descriptor 属性详解

  • value: 需要设置属性的值(默认为 undefined)
  • writable: 该属性是否为可修改的(默认为 false)
  • configurable:是否可以配置descriptor中的属性是否可以修改(默认为 false 除了 value和writable属性外)
  • enumerable:该属性是否可枚举(默认为false)
  • set(): 该属性修改时会调用此函数(默认为undefined)
  • get(): 该属性获取时 会调用此函数(默认为undefined)

在这里插入图片描述

3.2 实现方法

实际上是借助上面提到的 defineProperty方法,obj.attr 某属性进行复制一个新的变量old_attr

old_attr = obj.attr
Object.defineProperty(obj, 'attr', {
        get: function() {
            console.log(cookie_cache);
            return old_attr 
	},
        set: function(val) {
		 return  ......
}

通过案例说明公式原理,实际上,复制了浏览器document对象cookie值为1,然后将其赋值给一个新变量document.cookie_bak,结合definePropertydescriptor属性get,方法,当访问documentcookie的属性时候,会执行此函数,经过cookie_bak,伪装没有修改过,那么此时,访问document.cookie,时候,因为函数中编写了debugger,那么会进入到debugger状态,这样就成功了,那么调用堆栈,就可以找蛛丝马迹呢~~~

document.cookie = '1'
document.cookie_bak = document.cookie
Object.defineProperty(document,'cookie',{
    get:function(){
        debugger;
        return document.cookie_bak
    }
})
document.cookie

进入到debugger状态

在这里插入图片描述

三、hook实操

st 2、9
bs2、10

1、应对cookie解密(st2)

下面新增set,调用创建的的适合进入debugger状态

Object.defineProperty(document,'cookie',{
    get:function(){
        debugger;
        return ;
    },
    set:function(){
		debugger;
		return;
	}
})

调试前,打开script监听

在这里插入图片描述
提前打开控制台,点击需要调试的网页,可以看到网页在加载且进入,只有触发F8,F10,F11这些才会加载script

在这里插入图片描述
打开console,注入hook代码

在这里插入图片描述
关闭script事件监听,并且单步F10调试,慢慢按,遇到一个debugger,右键行号,点击neve paue here,过debugger

在这里插入图片描述
继续调试~~~
在这里插入图片描述
点击上一级调用后,找到了
在这里插入图片描述

2、应对cookie解密(st9)

修改下hook代码

Object.defineProperty(document,'cookie',{
    get:function(){
        debugger;
        return ;
    },
    set:function(val){
		debugger;
		return;
	}
})

经过注入代码,单步调试后

在这里插入图片描述
一一查看堆栈

在这里插入图片描述
可以看到,这是sign关键词

在这里插入图片描述
将这段复制出来在控制台打印,每次打印都是不同变化

在这里插入图片描述
骚操作(滑稽)

在这里插入图片描述

  • 现在已经确定了cookie生成源代码地方
  • 那么剩下的就是如何扣下这些生成代码逻辑
  • 扣代码后面提及

3、通过eval确定debugger产生位置代码

debugger,有些并不会直接写出来,而是通过eval混淆调用,是看不到名称的,如果在解决了常规debugger情况,有些东西还是拿不到,就要考虑打开网站之前就要做debugger测试hook,是否是eval型debugger

构建eval方式的hook,且伪造指纹

eval_bk = eval
eval = function(val){
    debugger;
    return  eval_bk(val)
}
eval.toString = function(){
    return " function eval() [native code]"
}

注入hook,经过调试(其中测试的时候,我发现chrome无痕调试比较准确能够)

在这里插入图片描述
向上找堆栈,发现是在这里进入的第二层,为此处调用的eval
在这里插入图片描述
继续F10 往下执行,进入了第二层代码,函数入口

在这里插入图片描述

4、hook的弊端和缺陷

(1)函数hook 一般情况下不会出现hook失败的情况,只有可能是 proto 模拟的不好导致被检测到了。

(2)属性hook 当所有网站的逻辑都采用Object.defineProperty绑定后,属性hook就会失效。暂时没有发现好的解决方案。

第一次执行绑定没有问题,第二次绑定会报错,如果整个网站都用这个绑定的时候,代码绑定之前,可以hook,绑定之后无处理。

有些网站会自己写hook,如果尝试hook,hook失败的话,会写一个蜜罐逻辑,让调试者调试失效

在这里插入图片描述

(3)局部hook,原理是一样的,只不过需要在进入作用域的那一刻进行hook。

如果不想手动写脚本,比如自定义通用脚本,可以借助油猴

四、hook插件:油猴脚本

chrome网上应用商店

搜 tampermonkey
在这里插入图片描述
下载后添加

在这里插入图片描述
官方文档(最好去看,下面内容只截取一部分)

https://www.tampermonkey.net/faq.php?version=4.13&ext=dhdg&updated=true

1、油猴脚本参数介绍

红色的很重要

@name :脚本名,你爱叫什么叫什么。

@namespace :脚本的命名空间。(一般就是写个url,告诉自己用在哪里)。

@version:版本,你爱写多少写多少。

@author:作者,你爱写谁写谁。

@description:描述,你爱怎么描述怎么描述。反正别人也看不懂。

@homepage, @homepageURL, @website and @source: 一般正常人都不写这几个参数。从脚本名称链接到给定页面的作者主页。

@icon, @iconURL and @defaulticon:一般正常人都不写这几个参数,低分辨率脚本图标。

@icon64 and @icon64URL:一般正常人都不写这几个参数,高分辨率脚本图标。

@updateURL: 更新检查的url,@version参数开启,会向url检查更新。

@downloadURL:定时监测到更新会自动下载url内容,若为 none则不检查

@include @match @exclude:匹配规则相关。支持精确匹配与正则匹配。@exclude是排除,不写相当于脚本白写

@require @resource :导包,支持url引入。比如引入 jquery,可以使用$

@connect:标记定义域,感觉很有用,但是我菜,所以很少用

@grant:白名单函数:比如:@grant window.close 。很强大,如果默认不写则会对一些原生函数如:eval等进行保护,显然这不是我们所期待的,所以就直接 @grant none了

@antifeature :官方文档的意思:开发人员是否允许别人把脚本货币化。

@noframes:在主页上运行而不在iframes上运行。

@unwrap:卵用没有,官方文档的意思:在chrome上,不需要它,自动被忽略了(淦!)

@nocompat:一般默认,官方文档写了好长,大概的意思指支持标记浏览器。如:@nocompat Chrome,这样就不能在火狐浏览器运行它了。

逆向中最重要的参数!!!
@run-at: 指定油猴脚本在什么时候执行,默认是在所有js加载完成后执行。(那hook脚本还有个屁用啊!)
参数:
@run-at document-start :脚本尽快注入(相当于script断点之后,进入页面一瞬间注入)
@run-at document-body :如果页面body元素存在,则注入(所以练习平台第二题就注不进去了)
@run-at document-end :脚本将在DOMContentLoaded事件发生注入。
@run-at document-idle:默认值。脚本将在DOMContentLoaded事件发生之后才注入
@run-at context-menu:如果在浏览器上下文菜单中单击脚本(仅限于基于桌面Chrome的浏览器),则会注入脚本。

2、油猴脚本基本使用

示例网站:
http://cpquery.cnipa.gov.cn/

在这里插入图片描述

将代码放入进去ctrl+s保存

// ==UserScript==
// @name         万能hook eval函数
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  eval-everything
// @author       An-lan
// @include      *
// @grant        none
// @run-at      document-start
// ==/UserScript==

// ==UserScript==
// @name         万能hook eval函数
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  eval-everything
// @author       An-lan
// @include      *
// @grant        none
// @run-at      document-start
// ==/UserScript==


(function() {
    alert('hook success');
    var eval_bk = eval;
    eval = function(val){
       debugger;
       console.log(val);
       return eval_bk(val);
    };
    eval.toString = function(){
         return "function eval() { [native code] }"
    };
    eval.length = 1;
})();

打开网址,成功!
在这里插入图片描述
如果没有自启动函数也能成功

// ==UserScript==
// @name         万能hook eval函数
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  eval-everything
// @author       An-lan
// @include      *
// @grant        none
// @run-at      document-start
// ==/UserScript==

 alert('hook success');
 var eval_bk = eval;
 eval = function(val){
    debugger;
    console.log(val);
    return eval_bk(val);
 };
 eval.toString = function(){
      return "function eval() { [native code] }"
 };
 eval.length = 1;

gif 动态演示,保存编辑好脚本后,打开网页,F5刷新,可以看到自动跳转到了debugger地方,这个时候就可以查看堆栈了
(滑稽,一开始漏写debugger语句进脚本,不会自动调到脚本,TMD找了15分钟原因)

调试的网址,不贴出来了!!!

开启油猴脚本后,在目标网址打开控制台,F5刷新网页,就能进来,接着就可以分析堆栈了~~

在这里插入图片描述

五、hook补充

1. 局部函数的hook

    function a() {
        function b(a) {
            return a
        }

        // hook b的 arguments  a 为 5的时候打断点
        b_bk = b;
        b = function (val) {
            if (val === 5) {
                debugger;
            }
            return b_bk(val)
        }
        // 下面为业务逻辑代码
        b(1);
        b(2);
        eval('b(' + 5 + ')');
    }
    a()

在这里插入图片描述

如何hooke到d呢?暂时没有思路。。。

function c() {
	let d = 2;
}

2. 全局变量的hook

Object.defineProperty(window, 'hook', {
        set: function () {
            debugger;
        }
    })

在这里插入图片描述

3. 一些常用的hook逻辑

  • hook eval 、
  • hook Function 、
  • hook JSON.stringify、
  • JSON.parse 、
  • hook cookie、
  • hook window
  • hook String

实际上查看String相关的方法,可以通过hook下面的方式,得到非常多想要的内容
在前面已经提及了,如何编写hook

  1. 函数hook公式(新建变量,重写函数,伪造指纹(原型链))
  2. 属性hook公式(新建变量既操作的对象属性,通过defineProty,编写hook)

在这里插入图片描述

六、验证码实现原理

1、基本原理

所有验证码都是基于以下原理,验证码本质上就是交互过程与模拟过程

  • 交互过程:可以机器学习方式实现等等
  • 模拟过程:如果难一点纯走协议,就需要逆向js等等

在这里插入图片描述

2、交互验证过程举例(ds8)

比如这是一个验证码
在这里插入图片描述

利用fiddler抓包工具

在这里插入图片描述

通过base64解密,验证码图是在img中的链接中加密请求

在这里插入图片描述
并且请求服务端,响应后设置了一个cookie

在这里插入图片描述

那么经过人为点击处理完毕验证码,会携带上面的cookie,以及下面的图片点击的坐标,请求点击后的接口,那么服务端就会校验,成功的话会返回一个成功的cookie(此时会删除之前的cookie)或者其它参数,表示用户通过,前端js缓存的内容可能会存在校验

在这里插入图片描述

在这里插入图片描述

这个时候就会成功获得数据
在这里插入图片描述

市面一线的验证码,都会将请求的参数进行加密,不可能像上面的的案例看到数字,后端会去再将加密的解码。

3、一线验证码

在这里插入图片描述

捕获了如下请求

在这里插入图片描述
在用户操作成功后,再请求一个接口,返回了token,通过这个token,当前页面,会将这个token会传向后端就会二次验证,整个过程就是如此

在这里插入图片描述

4、解决方案

  • 机器学习处理验证码
  • 得到加密参数
  • 通过session保持会话请求

补充session和cookie的关系:

首先cookie是服务端识别客户的唯一标识的依据,客户在访问网站时候,服务端为了记住这个客户,会在服务端按照它的规则制作一个cookie数据,会将这个cookie数据保留在服务端一段时间,同时会给客户的一份它自己保留,这样就无需每次都要登录来认证自己了。

先来了解几个概念。

1、无状态的HTTP协议:

协议是指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规则,超文本传输协议(HTTP)是一种通信协议,它允许将超文本标记语言(HTML)文档从Web服务器传送到客户端的浏览器。

2、HTTP协议是无状态的协议。
一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这
就意味着服务器无法从连接上跟踪会话。
3、会话(Session)跟踪:

会话,指用户登录网站后的一系列动作,比如浏览商品添加到购物车并购买。会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术

是Cookie与Session。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定

4. 从爬虫(验证码)角度来看,是以set-cookie建立了连接(以抓包情况演示验证码) 【当然了,不一定是以set-cookie的形式,还有可能是以接口API形式返回,反正无论如何,必须让服务器给你标记一下】

七、js逆向核心-扣代码-补环境-jsRPC

抠代码的三个阶段:

A.  缺啥补啥,稳扎稳打

B.  见文知义,化繁为简

C.  了然于胸,如履平地

1、扣代码优缺点

优点:

  1. 执行效率高
  2. 并发能力强
  3. 能感受到进度(抠出一行是一行)
  4. 只要有耐心,笨办法也能成大事

缺点:

  1. 比较吃经验,只有勤学苦练才能更快
  2. 若想精通则对js基础要求较高(尤其是对于浏览器API的掌握程度)
  3. 网站即使微调,js可能就会失效
  4. 做不到完全还原浏览器的某些值,对风控响应不够及时。

2、补环境优缺点

优点:

  1. 复用性强、开发速度快
  2. 有现成的库可供调用(如 jsdom)
  3. 简单网站,相对于抠代码,对熟练度要求更低
  4. 仅需对服务器的混淆代码做少量处理即可。

缺点:

  1. 占用资源大,计算速度可能慢
  2. 若想高并发可能需要开发多种浏览器环境,增加时间成本
  3. 对于极复杂的网站,可能更靠玄学。无法感受到进度的变化
  4. 若想精通则对需对node指纹和浏览器API都足够精通

3、jsRPC

JavaScript RPC 的简单实现过程是:

在客户端JavaScript脚本中,将要调用的服务端PHP函数名和函数参数(本地的JavaScript变量值)作为要传输的数据,通过Ajax传输到服务端,同时,Ajax设置一个回调函数,以便使用服务端函数的返回结果。在服务端PHP脚本中,接收Ajax传输的数据,从中取出要执行的函数名和函数参数。然后执行指定的函数,并将执行函数的返回值作为传输的数据,直接输出到浏览器,以此作为响应AJax的请求。客户端的Ajax在接受服务端的响应后,把返回的数据传递给AJax的回调函数。到此完成了一个RPC的流程。

八、扣代码实战

st2,bs2

1、cookie参数加密入口捕获(st2)

直接请求这个网址,返回的是script脚本

在这里插入图片描述

写一个hook,捕获cookie

Object.defineProperty(document,'cookie',{
    set:function(val){
    debugger;
    return val
}    
} )

在这里插入图片描述
过debugger

在这里插入图片描述hook到cookie

在这里插入图片描述

查看右边堆栈,定位到了代码

在这里插入图片描述
核心步骤:扣代码,复制代码

 document[_$ob('0x35')] = a[_$ob('0x47')](a[_$ob('0x1')](a['NpWYd'](a['gpbdE'](a[_$ob('0x5e')](a[_$ob('0x2')](a[_$ob('0x48')], Math[_$ob('0x1c')](a[_$ob('0x11')](c, 0x3e8))), '~'), token), '|'), md), a['zQTqr']);

核心步骤:定义一个变量去接收,创建一个test.js文件存放代码

 var cookie  = a[_$ob('0x47')](a[_$ob('0x1')](a['NpWYd'](a['gpbdE'](a[_$ob('0x5e')](a[_$ob('0x2')](a[_$ob('0x48')], Math[_$ob('0x1c')](a[_$ob('0x11')](c, 0x3e8))), '~'), token), '|'), md), a['zQTqr']);
扣代码,就是缺啥补啥

引入眼帘的是a,是一个对象,那么还是不知道a是什么,继续向上看a

在这里插入图片描述
搜索var a ,定位当定义a的方法,( 可以其它方法搜索,查找,能定位到就是好方法)

在这里插入图片描述
将这一段复制到test.js

在这里插入图片描述
现在查看 a 里面缺什么(采用深度优先,需要解决a及其相关,再考虑广度优先),现在解决_$ob

在这里插入图片描述
鼠标放置上面,点击进入

在这里插入图片描述

定位到此处,复制到test.js

在这里插入图片描述
可以看到_$oa是啥不知道,那么需要重复上面的步骤,定位复制
在这里插入图片描述
_$oa是一个数组

在这里插入图片描述
搜索_$oa,在上面可以看到,是将_$oa进行数组移位生成的

在这里插入图片描述
复制_$oa,分为静态,跟动态方式

静态(直接复制数组):

在这里插入图片描述

动态(复制逻辑代码):

在这里插入图片描述

到这一步感觉上是都扣代码完成了,那么可以直接运行脚本,发现c没有定义

在这里插入图片描述

定位到了c,并将其复制test.js

在这里插入图片描述

再次运行,发现token没有定义,复制粘贴,一运行发现window没有定义,这是因为node.js没有

在这里插入图片描述
定义window

在这里插入图片描述
再次运行,不难发现,window中没有btoa,即每页base64方法

在这里插入图片描述
base64个人是建议手写出来,但是注意是否被魔改(没有魔改),安装nodejs中btoa包

npm install btoa

也可以pycharm手动安装

在这里插入图片描述

导入包

在这里插入图片描述

再次运行 发现md没有定义

在这里插入图片描述
继续复制md

在这里插入图片描述
再运行,hex_md5 没有定义

在这里插入图片描述
继续找

在这里插入图片描述
点击后,发现是引入的第三方库

在这里插入图片描述
可以复制整个粘贴进去,但也扣需要的

在这里插入图片描述

继续扣~~~

在这里插入图片描述
继续

在这里插入图片描述
继续

在这里插入图片描述

继续

在这里插入图片描述
继续

在这里插入图片描述

继续~。。。

在这里插入图片描述
再次运行

在这里插入图片描述
实际上这些都要

在这里插入图片描述
再运行~~~~(QAQ 痛苦~~)

在这里插入图片描述
扣完再运行

在这里插入图片描述

继续扣,最后运行,不报错!!!nice

在这里插入图片描述

打印一下cookie看看,逻辑完成

在这里插入图片描述

但是还不够,希望的是,python去调用cookie,写一个python脚本,调用js,运行代码,成功打印页面html,而并非是js代码~~~,芜湖~~~通过!!!!

在这里插入图片描述

2、cookie参数(bs2)(浏览器指纹检测与格式化检测)

  1. 格式化检测
  2. 内存溢出

猿人学大赛第二题


注入控制台hook脚本

Object.defineProperty(document,'cookie',{
    set:function(val){
    debugger;
    return val
}    
} )

然后就是看堆栈,扣代码~~~省略步骤说明!!!!

在这里插入图片描述

通过堆栈确定是这些

在这里插入图片描述

查找 _0xe54e90,可以看到,这个变量是由_0x2b293a定义而成

在这里插入图片描述
继续扣
在这里插入图片描述
补完上面代码,一运行,缺少,继续找

在这里插入图片描述
省略说明。。。。
在这里插入图片描述
在这里插入图片描述

最后补完后,一运行,报错

在这里插入图片描述
将代码复制到控制台(检测是否浏览器指纹检测)

在这里插入图片描述
错误发现跟本地运行一样的错误,得出结论(格式化检测,并不是指纹检测)

在这里插入图片描述
将代码复制继续排查是否内存泄漏,不过现在,添加个debugger语句

在这里插入图片描述

回车运行后,F11调试,找到内存溢出的地方,可以看到疯狂的在这运行,进入死循环

在这里插入图片描述

进入死循环原因是,这个分支判断,进行调用了setcookie方法

在这里插入图片描述

最简单的方式,是直接修改这个,但是,可能会产生一些问题,可能会影响后续,分支判断

在这里插入图片描述

继续往上找,不能发现是一个正则处理方法,利用这个方法,test方法调用toString方法
在这里插入图片描述
那么手动修改removeCookie,实际上是检测这个有没有被格式化,将其手动调整不要格式化

在这里插入图片描述
此时运行还是错误状态,继续在console。调试,又进入循环,

在这里插入图片描述
实际上这是一个数组移位问题

在这里插入图片描述

跳过这个,不然F11半天

在这里插入图片描述

接着F11调试的时候,浏览器卡死,内存溢出!!!!!!!!!!!!

在这里插入图片描述
对应在此处打上debugger;
在这里插入图片描述
可以看到,又有格式化检测,并且RegExp

在这里插入图片描述
处理正则匹配这个函数。去除格式化

在这里插入图片描述

再次运行,发现终于没有卡死了,出现了未定,未定义好解决呀。。继续扣代码

在这里插入图片描述
继续运行

在这里插入图片描述
进入
在这里插入图片描述

一运行还是进入了执行状态,卡死,没有出来
在这里插入图片描述

去掉debugger,浏览器又出现了卡死,在下面地方继续debugger;找出卡死原因,即调用这个函数地方上面打上debugger

在这里插入图片描述
而后在这里触发了卡死

在这里插入图片描述
删除上一个debugger后,在卡死上方继续debugger,发现这里一运行就灰色卡死(缩小了范围)

在这里插入图片描述

后面步骤省略,都是重复性,利用debugger缩小方位,扣代码

唯一提及的 global,看到这个就要想到是否重写了函数,实际的确重写了函数

  • navigator 未定义,将其置空 这是一个浏览器指纹
    在这里插入图片描述

  • 而后就是,最后打印cookie的时候,会发现console.log方法实际上已经 被重写,利用hook方法重写打印即可

在这里插入图片描述

七、总结

1、如何编写hook函数(一般hook、对象属性hook)
2、油猴脚本使用方式
3、扣JavaScript代码流程
4、逐步利用debugger;去缩小出现内存溢出地方
5、浏览器指纹置空
6、global关键字,要思考是否内置方法被重写


补环境、jsRPC之后文章写

bs(1、2、5、6、9)

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐