• Chrome开发工具与js加密


    Chrome开发工具与js加密

    chrome开发者工具

    • Network

      观察当前数据流的请求情况

      • Search按钮进行关键词的一些搜索
      • Filter按钮进行当前请求的过滤, 屏蔽不必要的请求
      • Preserve log保存当前所有请求日志, 如果不勾选, 刷新页面会丢失历史日志
      • Disable cache关闭浏览器缓存
    • Source

      • debugger console

        • Resume

          恢复

        • Step over

          直接执行当前函数

        • Step into

          进入当前函数

        • Step out

          跳出当前函数

        • Step

          直接进入下一个局部函数内部, 比较少用

        • Deactive breakpoint

          禁止debugger模式下的所有断点

        • Pause on exceptions

          在所有抛出异常点的位置暂停, 比较少用

    • Watch

      监控变量值的变化

    • Breakpoints

      断点

    • Scope

      作用域

      • Global

        全局变量

      • Local

        局部变量

      • Closure

        闭包(自由变量)

    • Call Stack

      调用栈, 用来了解当前结果产生所经历的函数调用过程.

      我们在Call Stack上跳转函数的时候, 可以看到堆栈环境, 但是当前堆栈环境不一定准确.

    • XHR/fetch Breakpoints

      监听请求中的关键字, 在请求发送前暂停

    • DOM Breakpoints

      监听DOM的变化

    • Global Listeners

      全局监听器

    • Event Listeners Breakpoints

      事件监听器

      • Mouse
      • Keyboard

    分析流程

    • 分析要抓取的数据来自哪个请求
      • 尽量使用Fiddler, Charles抓包工具, chrome开发者工具也可以, 但是分析起来没有抓包工具方便
    • 观察请求的组成
      • headers尽量拼全, 之后再逐步减少不必要的字段

    还原被混淆的变量名

    • eval

      eval可以将字符串转换为可执行语句

      eval('n("0x155", "uYFB")')
      
      • 1
    • 通过正则还远混淆的代码

      const n = require('./anti_confuse.js').n
      
      restoreJs =  function(jsContent){
          // 使用正则表达式匹配所有混淆函数
          let matchArray = jsContent.match(/n\("[^\"]+", "[^\"]+"\)/g)
          for(let i=0; i
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

JS模块的导入和导出

  • 导出模块exports

    module.exports = {
        n: d
    }
    
    • 1
    • 2
    • 3
  • 导入模块require

    const anti_confuse = require('./anti_confuse.js');
    const n = anti_confuse.n
    
    • 1
    • 2

JS文件的写入和写出

  • 导入文件处理模块

    const file = require("fs");
    
    • 1
  • 文件读取

    readFileSync返回的是二进制数组, 需要调用toString来转变为字符串

    let jsContent = file.readFileSync("./react_pdd_20210513.js").toString();
    
    • 1
  • 文件写入

    let newJsContent = restoreJs(jsContent)
    file.writeFile(
        "react_pdd_20210513.restore.js",  // 文件名
        newJsContent,                     // 写入内容
        {encoding: "utf-8", flag: "w"},   // 参数
        function (e){
            if (e){
                console.log("文件写入失败")
            }else{
                console.log("文件写入成功")
            }
        }
    )
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
  • 三元运算符

    true?console.log("true"): console.log("false")
    
    • 1

加密流程

我们定位到了加密函数, 调用后产生了加密结果anti_content, 接下来就是要找齐加密所需要的参数和加密的具体函数

  • 将多个参数加密成多个小数组, 最终合并为大数组

    a = (t = [])[K].apply(t, [s[o](), Wt[o](), pt[o](), mt[o](), vt[o](), bt[o](), gt[o](), kt[o](), _t[o](), yt[o](), wt[o]()].concat(function(t) {
                                        if (Array.isArray(t)) {
                                            for (var n = 0, e = Array(t.length); n < t.length; n++)
                                                e[n] = t[n];
                                            return e
                                        }
                                        return Array.from(t)
                                    }(Ct[o]()), [St[o](), Ot[o](), Rt[o](), Pt[o](), jt[o](), Dt[o]()]));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • 生成了大数组a的长度为16的二进制信息u

    for (var u = a[E][g](2)[p](""), f = 0; r["ZIIDs"](u[E], 16); f += 1)
    	u[r["XjWuA"]]("0");
    u = u[x]("");
    
    • 1
    • 2
    • 3
  • 通过u生成了W参数列表中的l

    l[H](et[k](u[O](0, 8), 2), et[k](u[O](8, 16), 2))
    
    • 1
  • 合并了al

    a = [][K]([3], [1, 0, 0], l, a);
    
    • 1
  • 压缩了大数组a

    h = i['deflate'](a)
    
    • 1
  • hUint8Array中的元素值转变为String, 产生了W

    W = [][b]["call"](h, (function(t) {
                                            return String[S](t)
                                        }
                                    ));
    
    • 1
    • 2
    • 3
    • 4
  • W通过encode函数加密Wtt后的结果和定值0ap相加生成了anti_content

    r["yrFVy"](r["ZRscj"], c[r["wSNTe"]](r["yrFVy"](W[x](""), tt[x]("")), c["budget"]))
    
    • 1
    • tt是验证函数dtAt是否被修改的字段.
  • 相关阅读:
    【算法入门与九月打卡】—— 第五天
    HTML学生作业网页:使用HTML+CSS技术实现传统文化网页设计题材-西安事变历史纪念馆 10页 带视频 带音乐
    计算机的分类
    五、Nginx 配置 https
    C2基础设施威胁情报对抗策略
    【毕业设计】机器学习的溢油特征提取与识别
    springboot前后端时间类型传输
    PyCharm中环境变量与系统不相通问题
    基于微信小程序的食堂窗口自助点餐系统设计与实现-计算机毕业设计源码和lw文档
    [免费专栏] Android安全之ZIP文件目录遍历漏洞
  • 原文地址:https://blog.csdn.net/m0_57713054/article/details/128070624