webpack原理和逆向实战

news2024/9/29 5:30:40

文章目录

      • 什么是webpack
      • webpack基本原理
      • webpack代码分析
      • webpack代码抠取
      • webpack全模块自吐
      • webpack自动扣取
      • 总结

什么是webpack

webpack是一个现代 JavaScript 应用程序的静态模块打包器(module bundler),负责分析翻译压缩打包代码。

在这里插入图片描述

上面的官网的一张示例图。

webpack基本原理

首先我们来把两个最简单的js文件合并成一个,第一个JS文件代码如下:

var dt = require('./work.js')

第二个JS文件代码如下:

CryptoJS = require("crypto-js")
document.write('hello')

具体的合并过程我们不关注,各位有兴趣可以自行研究一下。代码很简单,只是引入一下CryptoJS库,我们看看webpack为了引入这个库,会生成什么样的代码。

下面是生成代码的部分粘贴

function (t) {
    var e = {};

    function r(i) {
        if (e[i]) return e[i].exports;
        var n = e[i] = {i: i, l: !1, exports: {}};
        return t[i].call(n.exports, n, n.exports, r), n.l = !0, n.exports
    }
    ...
    }, r.p = "", r(r.s = 10)
}([
	function (t, e, r) {},
	function (t, e, r) {},
	function (t, e, r) {},
	function (t, e, r) {},
    ......
    }(r(0), r(3), r(4), r(2), r(1))
}]);

上面的webpack代码,我经过了大量的删减,只保留了框架部分,看懂了这个框架的运行流程,就明白了webpack的原理。

接下来对webpack执行流程进行分析

在这里插入图片描述

首先是一个自执行函数,这个函数比较大,是整个webpack的入口。自执行函数传入了一个参数t

在这里插入图片描述

这个t是一个函数数组

在这里插入图片描述

继续往下走,定义了一个空对象e和一个函数r。

在这里插入图片描述

然后接下来的执行流都是一些赋值操作,这个不需要关心

在这里插入图片描述

一直到这个位置,前面都是一系列的赋值操作。而这里调用的函数r,传入了参数10。

这个r函数是我们要分析的重点,我们继续跟进
在这里插入图片描述

首先会判断当前e[i]的值是否为空,不为空的话就直接返回了。当前我们的e对象是一个空对象

在这里插入图片描述

接着往e[i]里面加入了一个对象
在这里插入图片描述

这个对象有三个元素,分别是exports,i和l。

在这里插入图片描述

接着执行了t[i]函数,并且把this指向改成了n.exports,这里直接步过这个函数,看看函数执行完成之后e[i]对象的内容。
在这里插入图片描述

执行完成之后,我们再来看下e[i]的值,可以看到此时exports里面已经被填充了一堆函数

CryptoJS = require("crypto-js")
document.write('hello')

我们合并的源码实际上是包含了CryptoJS库

在这里插入图片描述

这个exports里面也包含了Crypto对象。

那么整个webpack实际上就是一个以加载器为核心的,以加载器的某一个模块为入口(代码里是r(10)),分模块打包,最终返回exports进行调用的一种打包工具

也就是说r函数实际上就是一个加载器,把所有需要的模块全部加载进来,这样就能让后面的代码进行调用。

那么下面这段代码我们就能够理解了

//webpack函数入口 自执行函数
function (t) {
    var e = {};
	//webpack加载器
    function r(i) {
        if (e[i]) return e[i].exports;
        var n = e[i] = {i: i, l: !1, exports: {}};
        return t[i].call(n.exports, n, n.exports, r), n.l = !0, n.exports
    }
    ...
    }, r.p = "", r(r.s = 10)
}([
    //函数数组
	function (t, e, r) {},
	function (t, e, r) {},
	function (t, e, r) {},
	function (t, e, r) {},
    ......
    }(r(0), r(3), r(4), r(2), r(1))
}]);

webpack代码扣取的时候,需要把整个加载器的代码都拿到本地,然后通过调用加载器函数r(10)得到需要的模块对象。

webpack代码分析

示例网站是这个

https://open.babytree.com/default#/login

在这里插入图片描述

先抓一个登陆的包,这个包里面有两个字段,分别是sign和password,如果想要搞定这个登陆接口的话,就必须对这两个参数进行逆向分析。
在这里插入图片描述

通过搜索password关键词,可以定位到这个位置,password和加密后的数值也都符合预期,那么接下来就要进入到handleEncryptValue函数进行分析
在这里插入图片描述

进去以后,这里调用了Object函数,通过控制台可以看到函数原型,继续往里跟
在这里插入图片描述

这里关注两个地方

var o = n(409);
t.a = function(e) {
    var t = new o.JSEncrypt;
    return t.setPublicKey("-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2qC67Y3KF6mupPBsnsoIqEM1dfohMkMI4Rxj60Ae3MOT+Ch3vPZwCj4P5vVw+sVuRv0N94MqraNxLBlQfyeIf2Vu1KOdHD+gFfWneSrNM7Cs4b7Cn+ctCf9tJ239IrLilfsasV6iWc7kDHGIwInMJ9XqqTZTBnWP07SCQYf8J3mL/vw/PY1klBknwh8oLuJi8+BfAS1KPgMuK60NxTAMny+9h9Dno1kVGeLa0Osm4TkVWK9Uyx0XbbV0IfrnbpT/0FUxC6X+K+gHsWzmywrC7145+Bgz0lQo2kRTy551RcyMStlT41poc6ASn8mzCMD4u4MyNU+V0srtFBD8fdwZZwIDAQAB-----END PUBLIC KEY-----"),
        t.encrypt(e)
}

function(e)是关键参数的加密函数,而这里是通过o.JSEncrypt来进行调用的,而这个o是var o = n(409);

这是不是就有点像我们之前分析的加载器函数r10。这种就是典型的webpack调用模块的方式。特征如下:

r(10)
n(409)

在这里插入图片描述

这里的o已经是一个完成了加载过程的对象,可以直接进行调用。接下来就要对webpack代码进行扣取了。

webpack代码抠取

在这里插入图片描述

首先我们在这个加载器函数下断,并刷新网页,然后跟进去这个函数里面
在这里插入图片描述

可以看到这个代码跟我们之前分析的webpack代码几乎一样
在这里插入图片描述

我们需要复制下整个加载器函数,然后构造一个自执行函数,把这个加载器放进自执行函数里面

var Func;

//自执行函数
!function (e)
{
    var n={};
    function i(t) {
        if (n[t])
            return n[t].exports;
        var r = n[t] = {
            i: t,
            l: !1,
            exports: {}
        };
        return e[t].call(r.exports, r, r.exports, i),
        r.l = !0,
        r.exports
    }
    //提供给外部调用
    Func=i;
}({
   //这里放需要的模块函数 
})

接着我们需要去找到需要加载的模块
在这里插入图片描述

执行到下面这个位置,然后输入想要的e[409]就可以在控制台拿到需要的模块函数,然后右键->Show function definition

如果想要拿到所有的模块,可以在这个位置打一个日志断点或者是Hook,让他打印出所有的t和e[t],这样就可以拿到所有的模块。
在这里插入图片描述

就可以跳转到这个函数位置,然后粘贴到代码里面。最近一步,我们来编写调用代码

//补一下缺的环境
var navigator={}
var window=global

//调用
var o = Func(409);
 function Crypt(e) {
    var t = new o.JSEncrypt;
    return t.setPublicKey("-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2qC67Y3KF6mupPBsnsoIqEM1dfohMkMI4Rxj60Ae3MOT+Ch3vPZwCj4P5vVw+sVuRv0N94MqraNxLBlQfyeIf2Vu1KOdHD+gFfWneSrNM7Cs4b7Cn+ctCf9tJ239IrLilfsasV6iWc7kDHGIwInMJ9XqqTZTBnWP07SCQYf8J3mL/vw/PY1klBknwh8oLuJi8+BfAS1KPgMuK60NxTAMny+9h9Dno1kVGeLa0Osm4TkVWK9Uyx0XbbV0IfrnbpT/0FUxC6X+K+gHsWzmywrC7145+Bgz0lQo2kRTy551RcyMStlT41poc6ASn8mzCMD4u4MyNU+V0srtFBD8fdwZZwIDAQAB-----END PUBLIC KEY-----"),
        t.encrypt(e)
}
console.log(Crypt('123456'))

在这里插入图片描述

然后查看运行结果,测试应该没问题,到这里这个webpack就扣取完成了。

webpack全模块自吐

我们现在只扣取了一个模块的代码,假如说如果想要把所有的模块函数全部扣下来,就可以用下面的方法。
在这里插入图片描述

先在加载器调用的前后各打一个断点
在这里插入图片描述

然后在控制台定义一个变量
在这里插入图片描述

进到函数里面,在第一行打一个日志断点

window.result = window.result + '"'+ r + '":'+:e[r] +''+','

就可以通过日志的方式拿到所有的模块。

webpack自动扣取

https://gitcode.net/zjq592767809/webpack_ast

推荐一个可以自动扣取webpack的脚本,支持大部分常见的webpack,业内很有名的一个大佬写的,实战的这个网站也可以用webpack直接扣取。

使用方法:

node webpack_mixer.js -l loader.js -m function.js -o webpack_out.js
  • webpack_mixer.js脚本文件
  • -l 加载器的js路径
  • -m 函数模块的js路径
    在这里插入图片描述

脚本运行以后会生成一个JS文件,这个里面的webpack是完整的模块,而不是我们只扣取了一个模块的
在这里插入图片描述

用代码打印一下所有的函数列表,可以看到跟我们自己手动扣的完全不一样
在这里插入图片描述

然后直接调用,可以看到结果也出来了。只能说一个字,牛逼!

总结

最后,总结一下,扣取webpack的步骤如下:

  1. 找到加载器,在调用模块的地方下断点,刷新网页
  2. 构造自执行函数
  3. 找到调用的模块
  4. 编写调用函数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1379218.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

了解及掌握二维数组

第一题: 题目&#xff08;单对角线和&#xff09;&#xff1a; 分析&#xff1a; 用结构体的话&#xff0c;太麻烦了&#xff0c;专业一点&#xff0c;用本该属于它的知识点来解决它。 代码&#xff1a; #include <iostream> using namespace std; int main() { int…

设计模式—行为型模式之状态模式

设计模式—行为型模式之状态模式 状态&#xff08;State&#xff09;模式&#xff1a;对有状态的对象&#xff0c;把复杂的“判断逻辑”提取到不同的状态对象中&#xff0c;允许状态对象在其内部状态发生改变时改变其行为。 状态模式包含以下主要角色&#xff1a; 环境类&am…

如何使用iPad通过Code App+cpolar实现公网地址远程访问vscode

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” 文章目录 1. 在iPad下载Code APP2.安装cpolar内网穿透2.1 cpolar 安装2.2 创建TCP隧道 3. iPad远程vscode4. …

基于多智能体点对点转换的分布式模型预测控制

matlab2020正常运行 基于多智能体点对点转换的分布式模型预测控制资源-CSDN文库

资源三角形

美国哈佛大学的研究小组提出了著名的资源三角形&#xff1a;没有物质&#xff0c;什么也不存在&#xff1b;没有能量&#xff0c;什么也不会发生&#xff1b;没有信息&#xff0c;任何事物都没有意义。物质、能量和信息是相互有区别的&#xff0c;是人类社会赖以生存、发展的三…

7 - MySQL主从同步|主从同步模式

MySQL主从同步&#xff5c;主从同步模式 MySQL主从同步主从同步介绍主从同步工作过程主从同步结构模式配置主从同步一主一从同步结构一主多从同步结构主从从同步结构主主同步结构 主从同步模式主从同步结构模式复制模式 MySQL主从同步 主从同步介绍 存储数据的服务结构 主服务…

数据结构与算法教程,数据结构C语言版教程!(第三部分、栈(Stack)和队列(Queue)详解)五

第三部分、栈(Stack)和队列(Queue)详解 栈和队列&#xff0c;严格意义上来说&#xff0c;也属于线性表&#xff0c;因为它们也都用于存储逻辑关系为 "一对一" 的数据&#xff0c;但由于它们比较特殊&#xff0c;因此将其单独作为一章&#xff0c;做重点讲解。 使用栈…

vscode+opencv基础用法学习1

案例1&#xff1a;读取图片信息 如果是使用云服务器的话&#xff0c;由于图形界面的问题&#xff0c;使用cv::show来显示图片会报错 // 图片的读取和显示 // 导入opencv头文件 #include "opencv2/opencv.hpp" #include <iostream>int main(int argc, char** …

数据仓库 Apache Hive

一、数据分析 1、数据仓库 数据仓库&#xff08;英语&#xff1a;Data Warehouse&#xff0c;简称数仓、DW&#xff09;&#xff0c;是一个用于存储、分析、报告的数据系统。 数据仓库的目的是构建面向分析的集成化数据环境&#xff0c;分析结果为企业提供决策支持&#xff08…

js:使用canvas画一个半圆

背景 需求需要画一个半圆&#xff0c;或者多半圆&#xff0c;其实一下子就能想到 canvas 中的圆弧&#xff0c;核心使用 context.arc context.arc(x,y,r,sAngle,eAngle,counterclockwise)接下来我们看看示例 例一 <!DOCTYPE html> <html lang"en"> &…

机器学习基本算法:算法流程和算法分类

1、算法流程 机器学习的过程是一个完整的项目周期&#xff0c;其中包括数据的采集、数据的特征提取与分类&#xff0c;之后采用何种算法去创建机器学习模型从而获得预测数据。 算法流程 从上图可以看出一个完整的机器学习项目包含以下这些内容&#xff1a; 输入数据&#x…

JAVA毕业设计121—基于Java+Springboot的房屋租赁管理系统(源代码+数据库+9000字文档)

毕设所有选题&#xff1a; https://blog.csdn.net/2303_76227485/article/details/131104075 基于JavaSpringboot的房屋租赁管理系统(源代码数据库9000字文档)121 一、系统介绍 本项目还有ssm版本&#xff0c;分为用户、房东、管理员三种角色 1、用户&#xff1a; 注册、登…

Ubuntu 卸载重装 Nvidia 显卡驱动

问题描述 我使用 airsim 的时候&#xff0c;发现 UE4 没法使用显卡&#xff0c;导致非常卡顿 输入 nvidia-smi 有显卡型号等信息的输出&#xff0c;但是进程 process 里面没有显示 airsim 和其他软件占用显卡情况 因此&#xff0c;我选择了卸载重装 一.卸载旧版本的驱动 …

Komodor:Kubernetes 监控工具全面指南

为了方便起见&#xff0c;Komodor 提供了一个简单的 Web 界面&#xff0c;以帮助您监控 Kubernetes 集群的状态。它拥有付费和免费增值计划&#xff0c;除了在出现问题时通知用户外&#xff0c;还拥有一系列方便的工具&#xff0c;用于跟踪和管理集群中部署的资源的状态。让我们…

Python集合(set)

目录 集合创建集合访问集合向集合中添加和删除元素集合的 交集&#xff0c;并集&#xff0c;差集运算**交集****并集****差集** 集合方法 集合 集合是无序和无索引的集合。在 Python 中&#xff0c;集合用花括号编写。 创建集合 创建集合&#xff1a; thisset {"a"…

RISC-V Bytes: Caller and Callee Saved Registers

原文链接1&#xff1a;https://danielmangum.com/posts/risc-v-bytes-caller-callee-registers/ 原文链接2&#xff1a;https://zhuanlan.zhihu.com/p/77663680 //主要讲栈帧 原文链接3&#xff1a;https://www.jianshu.com/p/b666213cdd8a //主要讲栈帧 This is part of a new…

Ftrans飞驰云联荣获“CSA 2023安全创新奖”

2023年12月21日&#xff0c;第七届云安全联盟大中华区大会在深圳成功举办。会上&#xff0c;CSA大中华区发布了多个研究成果并进行 CSA 2023年度颁奖仪式&#xff0c;Ftrans飞驰云联以其突出的技术创新能力和广泛的市场应用前景&#xff0c;荣获备受瞩目的“CSA 2023安全创新奖…

redis夯实之路-哨兵(Sentinel)机制详解

Sentinel&#xff08;哨兵&#xff09;保证了redis的高可用性&#xff0c;一个Sentinel或多个Sentinel组成的系统监视多个主从服务器&#xff0c;当主服务器下线时&#xff0c;自动将一个从服务器升级为主服务器。 sentinel的主要功能 集群监控&#xff1a;负责监控redis mas…

imgaug库指南(20):从入门到精通的【图像增强】之旅

引言 在深度学习和计算机视觉的世界里&#xff0c;数据是模型训练的基石&#xff0c;其质量与数量直接影响着模型的性能。然而&#xff0c;获取大量高质量的标注数据往往需要耗费大量的时间和资源。正因如此&#xff0c;数据增强技术应运而生&#xff0c;成为了解决这一问题的…

【Python】使用Opencv裁剪指定区域,再重构大小和保存示例

在Python中&#xff0c;使用OpenCV库可以很方便地截取图像的某一区域&#xff0c;然后尺寸重构&#xff0c;最后保存为新的图像文件。以下是一个示例代码&#xff0c;演示如何实现这一操作&#xff1a; import cv2# 读取图像 img cv2.imread(img.jpg)# 定义截取的区域&#x…