js逆向 webpack_Webpack打包后逆向分析

发布于:2023-05-22 ⋅ 阅读:(243) ⋅ 点赞:(0)

webpack对前端js源码进行压缩打包后,一般会生成如下几个文件:

bootstrap.js 入口文件:

(function (modules) { // webpackBootstrap

// install a JSONP callback for chunk loading

var parentJsonpFunction = window["webpackJsonp"];

window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {

// add "moreModules" to the modules object,

// then flag all "chunkIds" as loaded and fire callback

var moduleId, chunkId, i = 0,

resolves = [],

result;

for (; i < chunkIds.length; i++) {

chunkId = chunkIds[i];

if (installedChunks[chunkId]) {

resolves.push(installedChunks[chunkId][0]);

}

installedChunks[chunkId] = 0;

}

/*遍历数组moreModules中的模块(也就是一个一个的函数),只要moreModules含有属性moduleId,则存入全局modules数组中

moduleId就是数组的moreModules数组的下标*/

for (moduleId in moreModules) {

//hasOwnProperty()用来判断一个属性是定义在对象本身而不是继承自原型链。

//Object.prototype.hasOwnProperty 表示Object对象是否含有某个属性,在此处变成moreModules是否含有moduleId属性

if (Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {

modules[moduleId] = moreModules[moduleId];

}

}

if (parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);

while (resolves.length) {

resolves.shift()();

}

if (executeModules) {

for (i = 0; i < executeModules.length; i++) {

result = __webpack_require__(__webpack_require__.s = executeModules[i]);

}

}

return result;

};

// The module cache

var installedModules = {};

// objects to store loaded and loading chunks

var installedChunks = {

8: 0

};

// The require function

function __webpack_require__(moduleId) {

// console.log('zhixing:'+moduleId);

// Check if module is in cache

if (installedModules[moduleId]) {

return installedModules[moduleId].exports;

}

// Create a new module (and put it into the cache)

var module = installedModules[moduleId] = {

i: moduleId,

l: false,

exports: {}

};

// Execute the module function

modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

// Flag the module as loaded

module.l = true;

// Return the exports of the module

return module.exports;

}

/*其他代码*/

})([]);

这是一个自执行函数,当使用webpack对js文件进行功能分割时在window对象会中定义一个webpackJsonp函数,供其他模块调用,第二个参数是一个数组,里面定义大量的函数,第三个参数表示要调用哪个函数。

比如项目中可能会出现main1.js 、main2.js、about.js、download.js等等分功能的js模块文件,每一个js文件中都是类似这样的开头形式:

//第一个参数表示要依赖哪个模块先加载,第二个参数是数组,每个数组元素是一个函数,调用webpackJsonp对第二个参数中的没一个函数注册进上面的modules数组中存储起来

webpackJsonp([7], [

/* 0 */

/***/

(function (module, exports, __webpack_require__) {

var global = __webpack_require__(3);

var core = __webpack_require__(21);

//其他代码

})

]);

//或者第二个参数是一个对象形式:

//这里第三个参数[181]表示要执行modules数组中第181号函数,如果要执行多个函数块,[181,32,78]等等

//__webpack_require__表示要引入哪个函数模块

webpackJsonp([0], {

/***/

181:

/***/

(function (module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", {

value: true

});

var global = __webpack_require__(3);

var core = __webpack_require__(21);

//其他代码 1

var url = new _urlParse2.default(url);

var algo = "sha256";

var digest = "hex";

var hash = (0, _createHmac2.default)(algo, url.href).update(url.query).update(url.hostname).update(url.pathname).digest(digest);

console.log(hash);

global_auth = hash;

})

},[181]);

具体到我们逆向分析的层面,当我们再chrome中调式分析到我们所关注的代码逻辑后,确定其所在哪一个序号模块中,然后修改webpackJsonp的第三个参数就ok了。

比如我这里,我分析到需要计算url的一个加密值,发现它在181号模块中,将 “其他代码 1” 这段代码块单独扣出来,删掉181号模块中其他不相关的逻辑代码,只要保证”其他代码 1“这个代码中引入的函数(如_createHmac2)能正常require进来就行

如何具体到操作层面呢?

这里以python中的pyv8为例讲解(用node执行也是一样),pyv8内嵌了google的V8 js引擎,虽说版本比较老了,但还是能用的。

但是直接在chrome浏览器上分析出来的结果,是不能全部直接丢进pyv8进行执行操作的,因为V8引擎是一个纯js执行环境,它不包含浏览器js环境中的dom window等这些对象,所以要对分析出的js文件进行适当修改。

将所有js文件整合到一个js文件中,注意顺序,首先copy boostrap.js入口文件,然后main1.js、main2.js等所有的模块代码都copy进来,最后才将需要调用的模块引入,并传入需要执行的具体模块序号,如[181],整体js代码形式如下:

var window = []; //V8没有window对象,手动定义一个全局的

var global_auth = ''; //用来接收后面计算出来的url加密值,pyv8可以获取到这个变量的值

//boostrap.js入口文件

(function (modules) { // webpackBootstrap

var parentJsonpFunction = window["webpackJsonp"];

.......

})([]);

//main1.js模块

webpackJsonp([7], [

(function (module, exports, __webpack_require__) {

.......

})

]);

//其他模块

.....

//最后目标代码所在的模块

webpackJsonp([0], {

/***/

181:

/***/

(function (module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", {

value: true

});

var _createClass = function () {

function defineProperties(target, props) {

for (var i = 0; i < props.length; i++) {

var descriptor = props[i];

descriptor.enumerable = descriptor.enumerable || false;

descriptor.configurable = true;

if ("value" in descriptor) descriptor.writable = true;

Object.defineProperty(target, descriptor.key, descriptor);

}

}

return function (Constructor, protoProps, staticProps) {

if (protoProps) defineProperties(Constructor.prototype, protoProps);

if (staticProps) defineProperties(Constructor, staticProps);

return Constructor;

};

}();

var _react = __webpack_require__(2);

var _react2 = _interopRequireDefault(_react);

var _reactStatic = __webpack_require__(119);

var _Meta = __webpack_require__(480);

var _Meta2 = _interopRequireDefault(_Meta);

var _Header = __webpack_require__(481);

var _Header2 = _interopRequireDefault(_Header);

var _Footer = __webpack_require__(482);

var _Footer2 = _interopRequireDefault(_Footer);

var _Thumbnails = __webpack_require__(483);

var _Thumbnails2 = _interopRequireDefault(_Thumbnails);

var _DownloadLink = __webpack_require__(507);

var _DownloadLink2 = _interopRequireDefault(_DownloadLink);

var _fuzzyTile = __webpack_require__(488);

var _fuzzyTile2 = _interopRequireDefault(_fuzzyTile);

var _createHmac = __webpack_require__(508);

var _createHmac2 = _interopRequireDefault(_createHmac);

var _icons = __webpack_require__(475);

var _icons2 = _interopRequireDefault(_icons);

var _urlParse = __webpack_require__(531);

var _urlParse2 = _interopRequireDefault(_urlParse);

var _axios = __webpack_require__(120);

var _axios2 = _interopRequireDefault(_axios);

function _interopRequireDefault(obj) {

return obj && obj.__esModule ? obj : {

default: obj

};

}

url = 'https://www.youtube.com/watch?v=3_VsTMc1auM';

var url = new _urlParse2.default(url);

var algo = "sha256";

var digest = "hex";

var hash = (0, _createHmac2.default)(algo, url.href).update(url.query).update(url.hostname).update(url.pathname).digest(digest);

console.log(hash);

global_auth = hash;

})

},[181]); //执行181模块


网站公告

今日签到

点亮在社区的每一天
去签到