刚学的油猴脚本hook住js

2022年4月30日更新:
有两个个开源的项目可以看看
https://github.com/CC11001100/crawler-js-hook-framework-public
https://github.com/LoseNine/Restore-JS

从公众号妄为写代码的作者那学来的,由公众号菜鸟学Python编程整理。我直接抄过来,顺便解释一下。

首先需要个油猴插件:

  • fq之后,在谷歌浏览器商店就能搜到,油猴的英文名:Tampermonkey
  • 国内网络的话,链接:https://pan.baidu.com/s/15ouGX7WVQ6lZxnfrcrlK6w
    提取码:4xqs
    • 离线安装自己去搜怎么装。如果装失败了,就把Tampermonkey_v4.5.crx的后缀crx改为rar,然后解压,然后找到下图加载已解压的扩展程序选中刚才解压的文件夹就好了。
      image.png

脚本

\color{red}{重点:}脚本内的注释不要删,尤其是@run-at document-start
先上脚本再解释。

// ==UserScript==
// @name         Hook global
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       悦来客栈的老板+妄为写代码+萌木盖
// @include      *
// @grant        none
// @run-at       document-start
// ==/UserScript==

(function() {
    'use strict';
    //全局变量 监控
    var t = window._t;
    var window_flag = '_t';
    var window_value = window[window_flag];
    Object.defineProperty(window, window_flag, {
        get: function() {
            console.log('Getting window._t',window_value);
            return t;
        },
        set: function(val) {
            console.log('Setting window._t', val);
            debugger;
            t = val;
            return t;
        }
    });
})();
  • hook的关键代码:@run-at document-start 意思为脚本将尽快注入。
  • 还一个主要函数是defineProperty他监控函数值,set该值和get该值都会调用这里面的两个方法。
  • 此脚本是针对一号店的登录页面,其他网站需根据想监控的数据改对象名和变量值(看图)


    image.png
  • 改完脚本在油猴插件添加新脚本,并启用就好。

开始用:

新打开一个标签页,按下F12,并在地址栏输入:

https://passport.yhd.com/passport/login_input.do

开始调试

image.png

再之后的调试就不讲了。就是正常的调试流程。如果有人感兴趣,去公众号搜菜鸟学Python编程里的爬虫入门之查找JS入口篇(七) --- 补充

更新:

服务器返回的加密的字符串,解密出来也是字符串。但是字符串取值不那么方便,因此加密前先用 JSON.strify字符化,然后再用 JSON.parse还原。所有遇到返回乱码可hookJSON.parse

var rparse = JSON.parse;
    JSON.parse = function(a) {
        console.log("Detect Json.parse", a);
        return rparse(a);
    }

其他脚本:

摘自https://mp.weixin.qq.com/s/CQlT4GJ2gVnzOww0rE5NRA
笔记一: 蔡老板的入口文章系列 其中一个需要自己完成的hook脚本。

// ==UserScript==
// @name         HOOK 遍历
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  day day up
// @author       FY
// @include      *
// @grant        none
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';
    !function () {
        'use strict';
        var source = ['DeCode','EnCode','decodeData','base64decode','md5','decode','btoa','MD5','RSA','AES','CryptoJS','encrypt','strdecode',"encode",'decodeURIComponent','_t','JSON.stringify','String.fromCharCode','fromCharCode'];
        console.log("开始测试是否有解密函数");
        let realCtx, realName;
        function getRealCtx(ctx, funcName) {
            let parts = funcName.split(".");
            let realCtx = ctx;
            for(let i = 0; i < parts.length - 1; i++) {
                realCtx = realCtx[parts[i]];
            }
            return realCtx;
        }
        function getRealName(funcName) {
            let parts = funcName.split(".");
            return parts[parts.length - 1];
        }
        function test(ctx) {
            for(let i = 0; i < source.length; i++) {
                let f = source[i];
                let realCtx = getRealCtx(ctx, f);
                let realName = getRealName(f);
                let chars = realCtx[realName];
                if (chars != undefined){
                    console.log("发现可疑函数:", f);
                    console.log(chars);
                    console.log("---------------------");
                }else{
                    console.log("未发现:", f);
                }
            }
        }
        test(window);
    }();
})();

开启脚本后找一个网站测试,打开控制台刷新网页后打印如下内容。

image

我们可以看到,脚本检测出了许多疑似加密函数的内容,我们可以把之前遇到过的类似的需要解密的函数写进一个数组里,然后依次查询是否有这样的函数。


笔记二:上一个脚本只是检测是否有加密函数,接下来完善一下,打印出加密函数的返回值,也就是直接hook到结果。

// ==UserScript==
// @name         HOOK ALL end
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  day day up!
// @author       FY
// @include      *
// @grant        none
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';
    var source = ['DeCode','EnCode','decodeData','base64decode','md5','decode','btoa','MD5','RSA','AES','CryptoJS','encrypt','strdecode',"encode",'decodeURIComponent','_t','JSON.stringify','String.fromCharCode','fromCharCode'];
    console.log("开始测试是否有解密函数");
    let realCtx, realName;
    function getRealCtx(ctx, funcName) {
        let parts = funcName.split(".");
        let realCtx = ctx;
        for(let i = 0; i < parts.length - 1; i++) {
            realCtx = realCtx[parts[i]];
        }
        return realCtx;
    }
    function getRealName(funcName) {
        let parts = funcName.split(".");
        return parts[parts.length - 1];
    }
    function hook(ctx, funcName, level, originFunc) {
        ctx[funcName] = function(a){
            console.log("level:" + level + " function:" + funcName,a);
            console.log(originFunc.toString());
            console.log(originFunc.toString);
            debugger;
            return originFunc(a);
        };
    }
    function test(ctx, level) {
        for(let i = 0; i < source.length; i++) {
            let f = source[i];
            let realCtx = getRealCtx(ctx, f);
            let realName = getRealName(f);
            let chars = realCtx[realName];
            hook(realCtx, realName, level, chars);
        }
    }
    test(window, 1);
})();

也是循环遍历 然后打印出函数的定义和返回值。

image.png

笔记三 : 需要更直观的看出加密函数内部调用的函数名。

// ==UserScript==
// @name         HOOK 二层函数名 end
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  day day up!
// @author       FY
// @include      *
// @grant        none
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';
    var source = ['decodeData','base64decode','md5','decode','btoa','MD5','RSA','AES','CryptoJS','encrypt','strdecode',"encode",'decodeURIComponent','_t','JSON.stringify','String.fromCharCode','fromCharCode'];
    console.log("开始测试是否有解密函数");
    let realCtx, realName;
    function getRealCtx(ctx, funcName) {
        let parts = funcName.split(".");
        let realCtx = ctx;
        for(let i = 0; i < parts.length - 1; i++) {
            realCtx = realCtx[parts[i]];
        }
        return realCtx;
    }
    function getRealName(funcName) {
        let parts = funcName.split(".");
        return parts[parts.length - 1];
    }
    function hook(ctx, funcName, level, originFunc) {
        ctx[funcName] = function(a){
            console.log("level:" + level + " function:" + funcName,a);
            let regexp = / [\S]*\(.*\)\;/g;
            let match = originFunc.toString().match(regexp)
            console.log(match);
            debugger;
            return originFunc(a);
        };
    }
    function test(ctx, level) {
        for(let i = 0; i < source.length; i++) {
            let f = source[i];
            let realCtx = getRealCtx(ctx, f);
            let realName = getRealName(f);
            let chars = realCtx[realName];
            hook(realCtx, realName, level, chars);
        }
    }
    test(window, 1);
})();
image

可以看出就是多写了一个正则,匹配出加密函数内部调用的函数名。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容

  • 油猴子是什么? 油猴(Tampermonkey)是浏览器的插件, 油猴子很特别, 它本身是一个无限手套(脚本管理器...
    我腐阅读 87,595评论 1 20
  • 今天八点醒来,磨磨唧唧到八点半,心里纠结起来,起床?算了,已经迟到了。不行,不能因为迟到半小时荒废了一天。这个想法...
    给给阅读 99评论 0 0
  • Certificates(证书) 部分常用证书 开发证书:app development(开发和真机调试,有效期1...
    sunshinfight阅读 1,766评论 0 0
  • 台北来的美式快餐连锁店,外墙大大的标签是带来快乐的一餐大概这意思吧。 两层楼的空间很宽敞,昂贵版的美式快餐连锁。菜...
    约定的梦幻岛阅读 248评论 0 0
  • 第九十二天 刚刚三个月 终于终于终于考试结束了 可以好好的放松好好的写简书了 一年分四季 一季三个月 陪你走过了2...
    uaremybelief阅读 280评论 0 0