美文网首页
Webpack打包后逆向分析

Webpack打包后逆向分析

作者: D_8270 | 来源:发表于2020-10-29 12:28 被阅读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模块
    

    相关文章

      网友评论

          本文标题:Webpack打包后逆向分析

          本文链接:https://www.haomeiwen.com/subject/jhekvktx.html