Python爬虫之Js逆向案例(8)-某乎x-zst-81之webpack

声明:某乎加密逆向分析仅用于研究和学习,如有侵权,可联系删除

大家好,相信各位童鞋通过上期《Python爬虫之Js逆向案例(7)-知hu最新x-zse-96之rpc方案》这篇文章了解了什么是jsrpc、原理,以及如何使用该方案获取x-zse-96加密!今天案例主角是其兄弟字段x-zst-81,该字段在一个半月前就扣过,这个字段的加密变化似乎不是特别大,所以想了解x-zst-81字段定位详细过程的可前往阅读《Python爬虫之Js逆向案例(4)-zhihu x-zst-81》。该字段的调用过程跟webpack有关,因此选为本节分享的案例内容,也是js逆向必备技能之一,webpack

为了照顾刚入门童鞋,文章每一步的分析过程尽可能的详细(有经验的同学可以选择感兴趣的地方快速浏览)

下面会进行以下几步进行分析(下方演示过程全部使用chrome浏览器);

  1. 什么是webpack?;
  2. 识别webpack产物;
  3. 本案例如何扣webpack代码;
  4. python爬虫结果演示;

一.什么是webpack?

webpack官网中的一句原话是这样说的:

本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack
处理应用程序时,它会递归地构建一个依赖关系图(dependency
graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。

正如上面描述的一样,这个东西就是一款现代化的前端模块打包工具而已!!!

它是打包工具跟我们逆向有什么关系???
有关系呀!这个东西既然是前端打包用的,那有些网站必然会用到这些工具,而且该工具在当前的前端开发过程中,使用率极高,注意是极高哦!!!毫不夸张的说,webpack在目前前端打包工具使用上绝对是NO.1,所以我们在逆向时碰到一个网站使用webpack打包的概率可比买刮刮乐中奖概率大太多,因此,webpack的逆向分析就必须拿出来分析分享一下了!

webpack官网上介绍了那么多东西,对于学习逆向的童鞋来说,我们需要全部都精通吗?

啥?!!!全部都精通?别开玩笑,我们是在学习逆向的技能,又不是为了精通前端打包!

所以,我感觉没必要,对于逆向来说,只需要学会辨别webpack产物、执行webpack模块,足够了!

不扯了!下面开始正题!

二.识别webpack产物

webpack特征还算比较明显,先来看一下大体结构:

!function(e){
	// 内部函数c
    function c(t) {
        if (r[t])
            return r[t].exports;
        var n = r[t] = {
            i: t,
            l: !1,
            exports: {}
        };
        return e[t].call(n.exports, n, n.exports, c),
        n.l = !0,
        n.exports
    }
}(
	// 参数是个对象
    {
        "SXT9":function(){
         	console.log("test")
        }
    }
)

或者:

!function(e){
	// 内部函数c
	function c(t) {
        if (r[t])
            return r[t].exports;
        var n = r[t] = {
            i: t,
            l: !1,
            exports: {}
        };
        return e[t].call(n.exports, n, n.exports, c),
        n.l = !0,
        n.exports
    }
}(
	// 参数是个数组
    [
	    function(){...},
	    function(){...},
	    function(){...},
    ]  
)

我们简单解剖一下上面的特征:

1.自执行函数:

!function(e){}()

2.一个具有callapplyexports的内部函数:

// 函数c可能会是其他的名称a,b,z等等,但是函数内部的结构长得基本都是下面这个样子:
function c(t) {
    if (r[t])
        return r[t].exports;
    var n = r[t] = {
        i: t,
        l: !1,
        exports: {}
    };
    return e[t].call(n.exports, n, n.exports, c),
    n.l = !0,
    n.exports
}

上面这个函数其实是webpack的模块加载器!他的作用就是根据实际需要,把自执行函数里的参数中的模块提取出来,以供后续执行;

至于callapply的作用,可以去MDN上看解释,我就不再复述了。

3. 自执行函数的参数是个数组或对象:

// 自执行函数
!function(e){}(参数)

// 参数类型 对象型
{
	XXXX:function(){}
}
// 参数类型 数组型
[
	function(){...},
	function(){...},
] 

4. 为了拓展其功能,还有一些其他的参数:

Python爬虫之Js逆向案例(8)-某乎x-zst-81之webpack_第1张图片

5. webpackJsonp模块:

Python爬虫之Js逆向案例(8)-某乎x-zst-81之webpack_第2张图片

能辨别上面这些东西,基本上webpack有关的内容就学一半了。是不是很简单!!!

下面内容主要有4个任务

  1. 确定加密函数所在位置;
  2. 扣到加密函数的代码;
  3. 导出加载器到全局变量;
  4. 使用加载器执行加密模块,拿到加密值;

三.本案例如何扣webpack代码

定位代码、扣代码这块在《Python爬虫之Js逆向案例(4)-zhihu x-zst-81》中有详细介绍,这里就不说那么详细了。

1. 扣代码之前需要先定位代码

xZst81字段是由n()函数执行后生成的,如下图:

Python爬虫之Js逆向案例(8)-某乎x-zst-81之webpack_第3张图片

2.扣到加密函数的代码:

观察这个加密后发现,加密函数所处的位置正是在自执行函数的入参模块中,如下图:
Python爬虫之Js逆向案例(8)-某乎x-zst-81之webpack_第4张图片

我们把整个自执行函数全部扣出来,好家伙呀!这个自执行函数有9w多行,,,没办法,模块太多分不清哪些是用不到的,先都抠出来吧!新建一个文件zh_xzst81_rpc.js

注意,这个时候我们不要只扣着一个模块的代码,因为这个模块还依赖其他的模块,只扣这一点无法运行;

高能总结
技巧:如果你此时也是使用了编辑器vscode的话,上面扣到的代码9w多行,太大了,可以把代码块先折叠起来,再根据需要搜索到对应位置。vscode折叠代码块的快捷键:按下command键之后(不松开),再分别按下k0(是零,不是o)。

3. 导出执行器到全局变量:

在自执行函数外定义一个全局变量get_loader,如下图:
Python爬虫之Js逆向案例(8)-某乎x-zst-81之webpack_第5张图片

把加载器在自执行函数体的最下方赋值给全局变量,如下图:

Python爬虫之Js逆向案例(8)-某乎x-zst-81之webpack_第6张图片

继续调试,发现n()函数的实现代码也是在另一个webpack模块的内部,如下图:

Python爬虫之Js逆向案例(8)-某乎x-zst-81之webpack_第7张图片

从上面我们能看到,执行加密的模块跟调用加密的模块不在一个文件里,这该怎么办呢?

不要慌!

此时把webpackJsonp这个文件全部扣出来,放到zh_xzst81_rpc.js文件中即可。细心的小伙伴可能留意到自执行函数体里有一行代码,如下图:

Python爬虫之Js逆向案例(8)-某乎x-zst-81之webpack_第8张图片

也就是说:

自执行函数在运行时,就已经把放在webpackJsonp上全局的模块给加载进去了,后面加载器之行模块的时候就能直接调用,内部怎么运行可以不用管!

到这里,本案例中需要扣的代码就已经扣完了!

4. 使用加载器执行加密模块,拿到加密值

怎么调用这个加密模块呢?

那肯定是先从加密位置所在的上下文模块开始运行了,于是只需要把这块加密相关的模块扣出来,放在zh_xzst81_rpc.js文件最下方,换成我们自定义的全局变量去加载就行了,n换成get_loader,如下图:

Python爬虫之Js逆向案例(8)-某乎x-zst-81之webpack_第9张图片

我们把zh_xzst81_rpc.js文件里的所有代码放到snippet里运行一下试试结果:
Python爬虫之Js逆向案例(8)-某乎x-zst-81之webpack_第10张图片

完美拿到xzst81字段加密值!是不是很开心!

先别开心太早!毕竟运行的是扣出来的代码,还需要验证的!!!

验证:

  1. 先生成xzst81的加密结果;
  2. 拿到xzst81的结果去生成x-zse-96的加密结果;

如下图:
Python爬虫之Js逆向案例(8)-某乎x-zst-81之webpack_第11张图片

四.python爬虫结果演示

把上面两个加密结果用py实现一下,如下图:
Python爬虫之Js逆向案例(8)-某乎x-zst-81之webpack_第12张图片

实际上如果使用rpc的方式,不用扣这么多代码,或者根本不用扣代码,操作可参考这个链接:https://blog.csdn.net/u014644574/article/details/121933772

五.答疑

Q1:x-zst-81相关代码扣出来之后能不能在本地运行?
A1:目前不能。跟x-zse-96字段生成一样,也校验了很多环境,如果童鞋有时间的话,可以去补环境,补全之后应该是可以的。本案例本地不能运行并不代表其他案例不能,下一期会分享一个webpack扣出来之后本地能运行的。

Q2:代码既然不能在本地用,那在爬虫代码里如何使用呢?
A2:可参考《Python爬虫之Js逆向案例(7)-知hu最新x-zse-96之rpc方案》中介绍的方案,结合rpc的方式使用;

Q3:扣出来的代码9W多行,能不能优化呢?
A3:可以优化,优化技巧请留意知识星球!

下期预告,一个webpack扣出来之后本地能直接运行的、相对简单一点的案例!

webpack逆向技能也是学习逆向时的必备技能请务必掌握!!!本案例操作时有疑问,可留言、私信,或者去星球提问一对一指导!


后期会持续分享爬虫案例-100例,不想自己造轮子的同学可加入我的知识星球,有更多技巧、案例注意事项、案例坑点终结、答疑提问特权等你哦!!!

欢迎加入「python、爬虫、逆向Club」知识星球

你可能感兴趣的:(python爬虫,js逆向,python,爬虫,x-zst-81)