[JS reverse hundred examples] actual combat of non Iife rewriting of a music network’s separated webpack

Time:2022-1-10

WeChat official account: brother K crawler, QQ exchange group: 808574309, keep sharing crawler advance, JS/ Android reverse technology dry cargo!

statement

All contents in this article are for learning and communication only. The packet capturing content, sensitive website and data interface have been desensitized. It is strictly prohibited to use them for commercial and illegal purposes, otherwise all the consequences have nothing to do with the author. If there is infringement, please contact me and delete them immediately!

Reverse target

  • Objective: kW music search parameters
  • Home page:aHR0cDovL3d3dy5rdXdvLmNuLw==
  • Interface:aHR0cDovL3d3dy5rdXdvLmNuL2FwaS93d3cvc2VhcmNoL3NlYXJjaE11c2ljQnlrZXlXb3Jk
  • Reverse parameters: query string parameters:reqId: 15c31270-32e8-11ec-a637-0b779ce474e4

The reverse goal of this time is to search for a parameter reqid of the interface. Note that this parameter is not necessary. The main purpose of this paper is to introduce the separated webpack, that is, how to rewrite the webpack when the module loader and each module are not in the same JS file, And how to rewrite the webpack through non Iife (immediate call function expression, self executing function). This article is an extension of previous articles:

Reverse process

Packet capture analysis

Go to the search page, search the song casually, and grab the package to the interface classaHR0cDovL3d3dy5rdXdvLmNuL2FwaS93d3cvc2VhcmNoL3NlYXJjaE11c2ljQnlrZXlXb3Jk, get request, query string parameters have a reqid encryption parameter, as shown in the following figure:

[JS reverse hundred examples] actual combat of non Iife rewriting of a music network's separated webpack

Parameter inversion

Directly search reqid globally, only in app 4eedc3a. JS file contains four results, as shown in the following figure:

[JS reverse hundred examples] actual combat of non Iife rewriting of a music network's separated webpack

Obviouslyt.data.reqId = randt.data.reqId = nIt’s suspicious. If you try to bury breakpoints in these two places, you will find that you can’t refresh the web page or search again. Let’s observe these two places,randnDefinition statement ofvar r = c()();var n = c()();All byc()()After that, we try to bury breakpoints in these two locations and search again. We can find that the breakpoints are successfully broken, andc()()The value of is exactly the value of reqid, as shown in the following figure:

[JS reverse hundred examples] actual combat of non Iife rewriting of a music network's separated webpack

Continue to look up and see how C comes from. You can see the logic:

var l = n(109)
  , c = n.n(l)
var r = c()();

Burying breakpoints for debugging, you can see that n is actually runtime d5e801d. JS, as shown in the following figure:

[JS reverse hundred examples] actual combat of non Iife rewriting of a music network's separated webpack

Look at thisfunction d(n){}, the return statement uses.callGrammar, there areexportsKeyword, through the introduction of brother K’s previous articles, it is easy to know that this is a webpack module loader, soeAll modules are included, as shown in the figure below:

[JS reverse hundred examples] actual combat of non Iife rewriting of a music network's separated webpack

Let’s take another lookn(109), click to enter this function. You can find that the functions before and after are separated by commas. Draw to the end of this file and you can see]Symbol, which indicates that all modules of the webpack are encapsulated in an array, so this 109 means that this function is the 109th function, as shown in the following figure:

[JS reverse hundred examples] actual combat of non Iife rewriting of a music network's separated webpack

I want to see othersc = n.n(l)Statement, checkedn.nClick and you will find that you also come to the module loader, so when you deduct the code, you willd.nJust buckle it down.

[JS reverse hundred examples] actual combat of non Iife rewriting of a music network's separated webpack

So to summarize the logic, the statementl = n(109), using the module loader, the 109th function is loaded, and the return value is assigned tol, thenc = n.n(l)Calling the module loadernMethod, the return value is assigned toc, and then executec()()You get the value of reqid.

Webpack rewrite

In the previous articles of brother K, we have introduced the rewriting method of webpack. In this case, brother K will introduce three methods, which can also be divided into two methods. One is Iife (immediate call function expression and self-executing function), but the passed parameters, that is, the format of the module, are divided into array and dictionary. The second is non Iife, which is a more conventional rewriting method, It seems easier to understand. PS: the complete code is not very good-looking. You can use tools such as vscode to fold all the codes. You can clearly see the different structures of the codes under different rewriting methods.

Through the previous analysis, we know that the module loader is usedd.n, the actual debugging also usedd.dandd.o, so they all have to buckle down together.

In the module part, we already know that the module 109 has been called, while observing the code of 109, we found that modules 202 and 203 have also been called, so we need to copy these three modules. When copying, we first run the breakpoint to the module loader, becauseeAll modules are stored, so we can call them directly in the consolee[109]e[202]e[203]Output and click to jump to the position of the original function, and then copy down, as shown in the following figure:

[JS reverse hundred examples] actual combat of non Iife rewriting of a music network's separated webpack

Iife pass through array

Brother K has introduced the rewriting method of Iife in previous articles. Similarly, we first define a global variable, such asvar kuwo;, and then export the module loaderkuwo = dThen, the array composed of 109, 202 and 203 is passed into Iife, so it is no longer the 109th, 202 and 203 modules, but the 0, 1 and 2 modules. Therefore, when calling the module, the corresponding 109, 202 and 203 should also be changed to 0, 1 and 2. The complete code is as follows:

var kuwo;

!function (e){
    var t = {};

    function d(n) {
        if (t[n]) return t[n].exports;
        var r = t[n] = {
            i: n,
            l: !1,
            exports: {}
        };
        return e[n].call(r.exports, r, r.exports, d),
            r.l = !0,
            r.exports
    }

    d.n = function (e) {
        var n = e && e.__esModule ?
            function () {
                return e.default
            } :
            function () {
                return e
            };
        return d.d(n, "a", n),
            n
    },
    d.d = function (e, n, r) {
            d.o(e, n) || Object.defineProperty(e, n, {
                enumerable: !0,
                get: r
            })
        },
    d.o = function (object, e) {
            return Object.prototype.hasOwnProperty.call(object, e)
        }

    kuwo = d
}([
    function (t, e, n) {
        var r, o, l = n(1),
            c = n(2),
            h = 0,
            d = 0;
        t.exports = function (t, e, n) {
            var i = e && n || 0,
                b = e || [],
                f = (t = t || {}).node || r,
                v = void 0 !== t.clockseq ? t.clockseq : o;
            if (null == f || null == v) {
                var m = l();
                null == f && (f = r = [1 | m[0], m[1], m[2], m[3], m[4], m[5]]),
                null == v && (v = o = 16383 & (m[6] << 8 | m[7]))
            }
            var y = void 0 !== t.msecs ? t.msecs : (new Date).getTime(),
                w = void 0 !== t.nsecs ? t.nsecs : d + 1,
                dt = y - h + (w - d) / 1e4;
            if (dt < 0 && void 0 === t.clockseq && (v = v + 1 & 16383), (dt < 0 || y > h) && void 0 === t.nsecs && (w = 0), w >= 1e4) throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");
            h = y,
                d = w,
                o = v;
            var x = (1e4 * (268435455 & (y += 122192928e5)) + w) % 4294967296;
            b[i++] = x >>> 24 & 255,
                b[i++] = x >>> 16 & 255,
                b[i++] = x >>> 8 & 255,
                b[i++] = 255 & x;
            var _ = y / 4294967296 * 1e4 & 268435455;
            b[i++] = _ >>> 8 & 255,
                b[i++] = 255 & _,
                b[i++] = _ >>> 24 & 15 | 16,
                b[i++] = _ >>> 16 & 255,
                b[i++] = v >>> 8 | 128,
                b[i++] = 255 & v;
            for (var A = 0; A < 6; ++A) b[i + A] = f[A];
            return e || c(b)
        }
    },
    function (t, e) {
        var n = "undefined" != typeof crypto && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || "undefined" != typeof msCrypto && "function" == typeof window.msCrypto.getRandomValues && msCrypto.getRandomValues.bind(msCrypto);
        if (n) {
            var r = new Uint8Array(16);
            t.exports = function () {
                return n(r),
                    r
            }
        } else {
            var o = new Array(16);
            t.exports = function () {
                for (var t, i = 0; i < 16; i++) 0 == (3 & i) && (t = 4294967296 * Math.random()),
                    o[i] = t >>> ((3 & i) << 3) & 255;
                return o
            }
        }
    },
    function (t, e) {
        for (var n = [], i = 0; i < 256; ++i) n[i] = (i + 256).toString(16).substr(1);
        t.exports = function (t, e) {
            var i = e || 0,
                r = n;
            return [r[t[i++]], r[t[i++]], r[t[i++]], r[t[i++]], "-", r[t[i++]], r[t[i++]], "-", r[t[i++]], r[t[i++]], "-", r[t[i++]], r[t[i++]], "-", r[t[i++]], r[t[i++]], r[t[i++]], r[t[i++]], r[t[i++]], r[t[i++]]].join("")
        }
    }
])

function getReqId() {
    var l = kuwo(0),
        c = kuwo.n(l),
        r = c()()
    return r
}

// console.log(getReqId())

Iife dictionary

For the same Iife, we pass the dictionary composed of 109, 202 and 203 modules into Iife, and the keys are named 109, 202 and 203 in turn. The value is the corresponding function. Then we can directly take the key name when calling the corresponding function, for examplevar c = n(203)It should be noted here that if the function name is not a number, it should be quoted when calling, for example, the function name isf203, the calling statement should bevar c = n("f203"), the complete code is as follows:

var kuwo;

!function(e) {
    var t = {};

    function d(n) {
        if (t[n]) return t[n].exports;
        var r = t[n] = {
            i: n,
            l: !1,
            exports: {}
        };
        return e[n].call(r.exports, r, r.exports, d),
        r.l = !0,
        r.exports
    }

    d.n = function(e) {
        var n = e && e.__esModule ?
        function() {
            return e.
        default
        }:
        function() {
            return e
        };
        return d.d(n, "a", n),
        n
    },
    d.d = function(e, n, r) {
        d.o(e, n) || Object.defineProperty(e, n, {
            enumerable: !0,
            get: r
        })
    },
    d.o = function(object, e) {
        return Object.prototype.hasOwnProperty.call(object, e)
    }

    kuwo = d
} ({
    109 : function(t, e, n) {
        var r, o, l = n(202),
        c = n(203),
        h = 0,
        d = 0;
        t.exports = function(t, e, n) {
            var i = e && n || 0,
            b = e || [],
            f = (t = t || {}).node || r,
            v = void 0 !== t.clockseq ? t.clockseq: o;
            if (null == f || null == v) {
                var m = l();
                null == f && (f = r = [1 | m[0], m[1], m[2], m[3], m[4], m[5]]),
                null == v && (v = o = 16383 & (m[6] << 8 | m[7]))
            }
            var y = void 0 !== t.msecs ? t.msecs: (new Date).getTime(),
            w = void 0 !== t.nsecs ? t.nsecs: d + 1,
            dt = y - h + (w - d) / 1e4;
            if (dt < 0 && void 0 === t.clockseq && (v = v + 1 & 16383), (dt < 0 || y > h) && void 0 === t.nsecs && (w = 0), w >= 1e4) throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");
            h = y,
            d = w,
            o = v;
            var x = (1e4 * (268435455 & (y += 122192928e5)) + w) % 4294967296;
            b[i++] = x >>> 24 & 255,
            b[i++] = x >>> 16 & 255,
            b[i++] = x >>> 8 & 255,
            b[i++] = 255 & x;
            var _ = y / 4294967296 * 1e4 & 268435455;
            b[i++] = _ >>> 8 & 255,
            b[i++] = 255 & _,
            b[i++] = _ >>> 24 & 15 | 16,
            b[i++] = _ >>> 16 & 255,
            b[i++] = v >>> 8 | 128,
            b[i++] = 255 & v;
            for (var A = 0; A < 6; ++A) b[i + A] = f[A];
            return e || c(b)
        }
    },
    202 : function(t, e) {
        var n = "undefined" != typeof crypto && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || "undefined" != typeof msCrypto && "function" == typeof window.msCrypto.getRandomValues && msCrypto.getRandomValues.bind(msCrypto);
        if (n) {
            var r = new Uint8Array(16);
            t.exports = function() {
                return n(r),
                r
            }  
        } else {
            var o = new Array(16);
            t.exports = function() {
                for (var t, i = 0; i < 16; i++) 0 == (3 & i) && (t = 4294967296 * Math.random()),
                o[i] = t >>> ((3 & i) << 3) & 255;
                return o
            }
        }
    },
    203 : function(t, e) {
        for (var n = [], i = 0; i < 256; ++i) n[i] = (i + 256).toString(16).substr(1);
        t.exports = function(t, e) {
            var i = e || 0,
            r = n;
            return [r[t[i++]], r[t[i++]], r[t[i++]], r[t[i++]], "-", r[t[i++]], r[t[i++]], "-", r[t[i++]], r[t[i++]], "-", r[t[i++]], r[t[i++]], "-", r[t[i++]], r[t[i++]], r[t[i++]], r[t[i++]], r[t[i++]], r[t[i++]]].join("")
        }
    }
})

function getReqId() {
    var l = kuwo(109),
    c = kuwo.n(l),
    r = c()()
    return r
}

// console.log(getReqId())

Non Iife routine override

Through the previous analysis, we already know that in the module loader of webpack,eContains all modules, then defines global variables to export the module loader, and then calls it in turneIn fact, the modules inside can also not use Iife. Just like our regular function calls, first define the three modules used directly outside, then package the three modules into a dictionary or array, and assign the dictionary or array toe, and then the original module loaderfunction d(n){}Also take it out directly, parametersnIndicates to calleWhich function inside can be passed in the corresponding name or subscript. The complete code is as follows:

var f109 = function(t, e, n) {
    var r, o, l = n(1),
    c = n(2),
    h = 0,
    d = 0;
    t.exports = function(t, e, n) {
        var i = e && n || 0,
        b = e || [],
        f = (t = t || {}).node || r,
        v = void 0 !== t.clockseq ? t.clockseq: o;
        if (null == f || null == v) {
            var m = l();
            null == f && (f = r = [1 | m[0], m[1], m[2], m[3], m[4], m[5]]),
            null == v && (v = o = 16383 & (m[6] << 8 | m[7]))
        }
        var y = void 0 !== t.msecs ? t.msecs: (new Date).getTime(),
        w = void 0 !== t.nsecs ? t.nsecs: d + 1,
        dt = y - h + (w - d) / 1e4;
        if (dt < 0 && void 0 === t.clockseq && (v = v + 1 & 16383), (dt < 0 || y > h) && void 0 === t.nsecs && (w = 0), w >= 1e4) throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");
        h = y,
        d = w,
        o = v;
        var x = (1e4 * (268435455 & (y += 122192928e5)) + w) % 4294967296;
        b[i++] = x >>> 24 & 255,
        b[i++] = x >>> 16 & 255,
        b[i++] = x >>> 8 & 255,
        b[i++] = 255 & x;
        var _ = y / 4294967296 * 1e4 & 268435455;
        b[i++] = _ >>> 8 & 255,
        b[i++] = 255 & _,
        b[i++] = _ >>> 24 & 15 | 16,
        b[i++] = _ >>> 16 & 255,
        b[i++] = v >>> 8 | 128,
        b[i++] = 255 & v;
        for (var A = 0; A < 6; ++A) b[i + A] = f[A];
        return e || c(b)
    }
};
var f202 = function(t, e) {
    var n = "undefined" != typeof crypto && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || "undefined" != typeof msCrypto && "function" == typeof window.msCrypto.getRandomValues && msCrypto.getRandomValues.bind(msCrypto);
    if (n) {
        var r = new Uint8Array(16);
        t.exports = function() {
            return n(r),
            r
        }
    } else {
        var o = new Array(16);
        t.exports = function() {
            for (var t, i = 0; i < 16; i++) 0 == (3 & i) && (t = 4294967296 * Math.random()),
            o[i] = t >>> ((3 & i) << 3) & 255;
            return o
        }
    }
};
var f203 = function(t, e) {
    for (var n = [], i = 0; i < 256; ++i) n[i] = (i + 256).toString(16).substr(1);
    t.exports = function(t, e) {
        var i = e || 0,
        r = n;
        return [r[t[i++]], r[t[i++]], r[t[i++]], r[t[i++]], "-", r[t[i++]], r[t[i++]], "-", r[t[i++]], r[t[i++]], "-", r[t[i++]], r[t[i++]], "-", r[t[i++]], r[t[i++]], r[t[i++]], r[t[i++]], r[t[i++]], r[t[i++]]].join("")
    }
};

var e = [f109, f202, f203];

function d(n) {
    var t = {};
    if (t[n]) return t[n].exports;
    var r = t[n] = {
        i: n,
        l: !1,
        exports: {}
    };
    return e[n].call(r.exports, r, r.exports, d),
    r.l = !0,
    r.exports
}

d.n = function(e) {
    var n = e && e.__esModule ?
    function() {
        return e.
    default
    }:
    function() {
        return e
    };
    return d.d(n, "a", n),
    n
},
d.d = function(e, n, r) {
    d.o(e, n) || Object.defineProperty(e, n, {
        enumerable: !0,
        get: r
    })
},
d.o = function(object, e) {
    return Object.prototype.hasOwnProperty.call(object, e)
};

function getReqId() {
    var l = d(0),
        c = d.n(l),
        r = c()()
    return r
}

// console.log(getReqId())

[JS reverse hundred examples] actual combat of non Iife rewriting of a music network's separated webpack