返回顶部
首页 > 资讯 > 前端开发 > JavaScript >详解JavaScript常用的Hook脚本
  • 797
分享到

详解JavaScript常用的Hook脚本

2024-04-02 19:04:59 797人浏览 独家记忆
摘要

本文Hook脚本 来自 包子 页面最早加载代码Hook时机 在source里 用dom事件断点的script断点然后刷新网页,就会断在第一个js标签,这时候就可以注入代码进行hook

本文Hook脚本 来自 包子

页面最早加载代码Hook时机

  • 在source里 用dom事件断点的script断点
  • 然后刷新网页,就会断在第一个js标签,这时候就可以注入代码进行hook

监听 键盘 与 鼠标 事件

// 判断是否按下F12  onkeydown事件


// F12的键码为 123,可以直接全局搜索 keyCode == 123, == 123 ,keyCode
document.onkeydown = function() {
    if (window.event && window.event.keyCode == 123) {
        // 改变键码
        event.keyCode = 0;
        event.returnValue = false;
        // 监听到F12被按下直接关闭窗口
        window.close();
        window.location = "about:blank";
    }
}
;
// 监听鼠标右键是否被按下方法 1, oncontextmenu事件
document.oncontextmenu = function () { return false; };
// 监听鼠标右键是否被按下方法 2,onmousedown事件
document.onmousedown = function(evt){
    // button属性是2 就代表是鼠标右键 
    if(evt.button == 2){
        alert('监听到鼠标右键被按下')
        evt.preventDefault() // 该方法将通知 WEB 浏览器不要执行与事件关联的默认动作
        return false;
// 监听用户工具栏调起开发者工具,判断浏览器的可视高度和宽度是否有改变,有改变则处理,
// 判断是否开了开发者工具不太合理。
var h = window.innerHeight, w = window.innerWidth;
window.onresize = function(){
    alert('改变了窗口高度')
// hook代码
(function() {
    //严谨模式 检查所有错误
    'use strict';
    // hook 鼠标选择
    Object.defineProperty(document, 'onselectstart', {
		set: function(val) {
			console.log('Hook捕获到选中设置->', val);
			return val;
		}
      });
	// hook 鼠标右键
	Object.defineProperty(document,'oncontextmenu',{
		set:function(evt){
			console.log("检测到右键点击");
			return evt
	});
})();

webpack hook 半自动扣

//在加载器后面下断点  执行下面代码
// 这里的f 替换成需要导出的函数名
window.zhiyuan = f;
window.wbpk_ = "";
window.isz = false;
f = function(r){
	if(window.isz)
	{
        // e[r]里的e 是加载器里的call那里
		window.wbpk_ = window.wbpk_ + r.toString()+":"+(e[r]+"")+ ",";
	}
	return window.zhiyuan(r);
}

//在你要的方法加载前下断点 执行 window.isz=true
//在你要的方法运行后代码处下断点  执行 window.wbpk_  拿到所有代码  注意后面有个逗号
function o(t) {
    if (n[t])
        return n[t].exports;
    var i = n[t] = {
        i: t,
        l: !1,
        exports: {}
    };
    console.log("被调用的 >>> ", e[t].toString());
    //  这里进行拼接,bb变量需要在全局定义一下 
    // t 是模块名, e[t] 是模块对应的函数, 也就是key:value形式
    bb += `"${t}":${e[t].toString()},`
    return e[t].call(i.exports, i, i.exports, o),
    i.l = !0,
    i.exports
bz = o;

如果只是调用模块,不用模块里面的方法, 那么直接获取调用模块的时候所有加载过的模块,进行拼接

document下的createElement()方法的hook,查看创建了什么元素

(function() {
    'use strict'
   var _createElement = document.createElement.bind(document);
   document.createElement = function(elm){
   // 这里做判断 是否创建了script这个元素    
   if(elm == 'body'){
        debugger;
   }
    return _createElement(elm);
}
})();

之前我不知道我用的是 var _createElement = document.createElement 导致一直报错 Uncaught TypeError: Illegal invocation
原来是需要绑定一下对象 var _createElement = document.createElement.bind(document);

headers hook 当header中包含Authorization时,则插入断点


var code = function(){
var org = window.XMLHttpRequest.prototype.setRequestHeader;
window.XMLHttpRequest.prototype.setRequestHeader = function(key,value){
    if(key=='Authorization'){
        debugger;
    }
    return org.apply(this,arguments);
}
}
var script = document.createElement('script');
script.textContent = '(' + code + ')()';
(document.head||document.documentElement).appendChild(script);
script.parentnode.removeChild(script);

请求hook 当请求的url里包含MmEwMD时,则插入断点

var code = function(){
var open = window.XMLHttpRequest.prototype.open;
window.XMLHttpRequest.prototype.open = function (method, url, async){
    if (url.indexOf("MmEwMD")>-1){
        debugger;
    }
    return open.apply(this, arguments);
};
}
var script = document.createElement('script');
script.textContent = '(' + code + ')()';
(document.head||document.documentElement).appendChild(script);
script.parentNode.removeChild(script);

docuemnt.getElementById以及value属性的hook

// docuemnt.getElementById 以及value属性的hook,可以参考完成innerhtml的hook
document.getElementById = function(id) {
    var value = document.querySelector('#' + id).value;
    console.log('DOM操作 id: ', id)
    try {
        Object.defineProperty(document.querySelector('#'+ id), 'value', {
            get: function() {
                console.log('getting -', id, 'value -', value);
                return value;
            },
            set: function(val) {
                console.log('setting -', id, 'value -', val)
                value = val;
            }
        })
    } catch (e) {
        console.log('---------华丽的分割线--------')
    }
    return document.querySelector('#' + id);
}

过debugger 阿布牛逼


function Closure(injectFunction) {
    return function() {
        if (!arguments.length)
            return injectFunction.apply(this, arguments)
        arguments[arguments.length - 1] = arguments[arguments.length - 1].replace(/debugger/g, "");
        return injectFunction.apply(this, arguments)
    }
}
var oldFunctionConstructor = window.Function.prototype.constructor;
window.Function.prototype.constructor = Closure(oldFunctionConstructor)
//fix native function
window.Function.prototype.constructor.toString = oldFunctionConstructor.toString.bind(oldFunctionConstructor);
var oldFunction = Function;
window.Function = Closure(oldFunction)
window.Function.toString = oldFunction.toString.bind(oldFunction);
var oldEval = eval;
window.eval = Closure(oldEval)
window.eval.toString = oldEval.toString.bind(oldEval);
// hook GeneratorFunction
var oldGeneratorFunctionConstructor = Object.getPrototypeOf(function*() {}).constructor
var newGeneratorFunctionConstructor = Closure(oldGeneratorFunctionConstructor)
newGeneratorFunctionConstructor.toString = oldGeneratorFunctionConstructor.toString.bind(oldGeneratorFunctionConstructor);
Object.defineProperty(oldGeneratorFunctionConstructor.prototype, "constructor", {
    value: newGeneratorFunctionConstructor,
    writable: false,
    configurable: true
})
// hook Async Function
var oldAsyncFunctionConstructor = Object.getPrototypeOf(async function() {}).constructor
var newAsyncFunctionConstructor = Closure(oldAsyncFunctionConstructor)
newAsyncFunctionConstructor.toString = oldAsyncFunctionConstructor.toString.bind(oldAsyncFunctionConstructor);
Object.defineProperty(oldAsyncFunctionConstructor.prototype, "constructor", {
    value: newAsyncFunctionConstructor,
// hook dom
var oldSetAttribute = window.Element.prototype.setAttribute;
window.Element.prototype.setAttribute = function(name, value) {
    if (typeof value == "string")
        value = value.replace(/debugger/g, "")
    // 向上调用
    oldSetAttribute.call(this, name, value)
;
var oldContentWindow = Object.getOwnPropertyDescriptor(HTMLIFrameElement.prototype, "contentWindow").get
Object.defineProperty(window.HTMLIFrameElement.prototype, "contentWindow", {
    get() {
        var newV = oldContentWindow.call(this)
        if (!newV.inject) {
            newV.inject = true;
            core.call(newV, globalConfig, newV);
        }
        return newV

过debugger—1 constructor 构造器构造出来的

var _constructor = constructor;
Function.prototype.constructor = function(s) {
    if (s == "debugger") {
        console.log(s);
        return null;
    }
    return _constructor(s);
}

过debugger—2 eval的

(function() {
    'use strict';
    var eval_ = window.eval;
    window.eval = function(x) {
        eval_(x.replace("debugger;", "  ; "));
    }
    ;
    window.eval.toString = eval_.toString;
}
)();

JSON HOOK

var my_stringify = JSON.stringify;
JSON.stringify = function (params) {
    //这里可以添加其他逻辑比如 debugger
    console.log("json_stringify params:",params);
    return my_stringify(params);
};
var my_parse = JSON.parse;
JSON.parse = function (params) {
    //这里可以添加其他逻辑比如 debugger
    console.log("json_parse params:",params);
    return my_parse(params);
};

对象属性hook 属性自定义

(function(){
    // 严格模式,检查所有错误
    'use strict'
    // document 为要hook的对象 ,属性是cookie
    Object.defineProperty(document,'cookie',{
        // hook set方法也就是赋值的方法,get就是获取的方法
        set: function(val){
            // 这样就可以快速给下面这个代码行下断点,从而快速定位设置cookie的代码
            debugger;  // 在此处自动断下
            console.log('Hook捕获到set-cookie ->',val);
            return val;
        }
    })
})();

cookies - 1 (不是万能的 有些时候hook不到 自己插入debugger)

var cookie_cache = document.cookie;
Object.defineProperty(document, 'cookie', {
    get: function() {
        console.log('Getting cookie');
        return cookie_cache;
    },
    set: function(val) {
        console.log("Seting cookie",val);
        var cookie = val.split(";")[0];
        var ncookie = cookie.split("=");
        var flag = false;
        var cache = cookie_cache.split("; ");
        cache = cache.map(function(a){
            if (a.split("=")[0] === ncookie[0]){
                flag = true;
                return cookie;
            }
            return a;
        })
    }
})

cookies - 2

var code = function(){
    var org = document.cookie.__lookupSetter__('cookie');
    document.__defineSetter__("cookie",function(cookie){
        if(cookie.indexOf('TSdc75a61a')>-1){
            debugger;
        }
        org = cookie;
    });
    document.__defineGetter__("cookie",function(){return org;});
}
var script = document.createElement('script');
script.textContent = '(' + code + ')()';
(document.head||document.documentElement).appendChild(script);
script.parentNode.removeChild(script);

// 当cookie中匹配到了 TSdc75a61a, 则插入断点。

window attr


// 定义hook属性
var window_flag_1 = "_t";
var window_flag_2 = "ccc";
var key_value_map = {};
var window_value = window[window_flag_1];
// hook
Object.defineProperty(window, window_flag_1, {
    get: function(){
        console.log("Getting",window,window_flag_1,"=",window_value);
        //debugger
        return window_value
    },
    set: function(val) {
        console.log("Setting",window, window_flag_1, "=",val);
        window_value = val;
        key_value_map[window[window_flag_1]] = window_flag_1;
        set_obj_attr(window[window_flag_1],window_flag_2);
});
function set_obj_attr(obj,attr){
    var obj_attr_value = obj[attr];
    Object.defineProperty(obj,attr, {
        get: function() {
            console.log("Getting", key_value_map[obj],attr, "=", obj_attr_value);
            //debugger
            return obj_attr_value;
        },
        set: function(val){
            console.log("Setting", key_value_map[obj], attr, "=", val);
            obj_attr_value = val;
    });
}

eval/Function

window.__cr_eval = window.eval;
var myeval = function(src) {
    // src就是eval运行后 最终返回的值
    console.log(src);
    console.log("========= eval end ===========");
    return window.__cr_eval;
}
var _myeval = myeval.bind(null);
_myeval.toString = window.__cr_eval.toString;
Object.defineProperty(window, 'eval',{value: _myeval});
window._cr_fun = window.Function
var myfun = function(){
    var args = Array.prototype.slice.call(arguments, 0, -1).join(","), src = arguments[arguments.lenght -1];
    console.log("======== Function end =============");
    return window._cr_fun.apply(this, arguments)
myfun.toString = function() {return window._cr_fun + ""} //小花招,这里防止代码里检测原生函数
Object.defineProperty(window, "Function",{value: myfun})

eval 取返回值

_eval = eval;
eval = (res)=>{
    res1 = res // 返回值
    return _eval(res)
}
eval(xxxxxxxxx)

eval proxy代理 https://segmentfault.com/a/1190000025154230

// 代理eval
eval = new Proxy(eval,{
    // 如果代理的是函数 查看调用 就用apply属性
    // 第二个参数是prop 这里用不上 因为是属性,eval只是个函数 所以prop为undefind 这里设置了下划线 ——
    apply: (target,_,arg)=>{
        // target 是被代理的函数或对象名称,当前是[Function: eval]
        // arg是传进来的参数,返回的是个列表
        console.log(arg[0])
    }
})

//  eval执行的时候就会被代理拦截
// 传入的如果是字符串 那么只会返回字符串,这里是匿名函数 直接执行 return了内容
eval(
    (function(){return "我是包子 自己执行了"})()
)
// 结果 : 我是包子 自己执行了

websocket hook

 // 1、webcoket 一般都是json数据格式传输,那么发生之前需要JSON.stringify  
var my_stringify = JSON.stringify;
JSON.stringify = function (params) {
    //这里可以添加其他逻辑比如 debugger
    console.log("json_stringify params:",params);
    return my_stringify(params);
};

var my_parse = JSON.parse;
JSON.parse = function (params) {
    console.log("json_parse params:",params);
    return my_parse(params);
// 2  webScoket 绑定在windows对象,上,根据浏览器的不同,websokcet名字可能不一样 
//chrome window.WebSocket  firfox window.MozWebSocket;
window._WebSocket = window.WebSocket;
// hook send
window._WebSocket.prototype.send = function (data) {
    console.info("Hook WebSocket", data);
    return this.send(data)
}
Object.defineProperty(window, "WebSocket",{value: WebSocket})

hook 正则 —— 1

(function () {
    var _RegExp = RegExp;
    RegExp = function (pattern, modifiers) {
        console.log("Some codes are setting regexp");
        debugger;
        if (modifiers) {
            return _RegExp(pattern, modifiers);
        } else {
            return _RegExp(pattern);
        }
    };
    RegExp.toString = function () {
        return "function setInterval() { [native code] }"
    };
})();

hook 正则 2 加在sojson头部过字符串格式化检测

(function() {
    var _RegExp = RegExp;
    RegExp = function(pattern, modifiers) {
        if (pattern == decodeURIComponent("%5Cw%2B%20*%5C(%5C)%20*%7B%5Cw%2B%20*%5B'%7C%22%5D.%2B%5B'%7C%22%5D%3B%3F%20*%7D") || pattern == decodeURIComponent("function%20*%5C(%20*%5C)") || pattern == decodeURIComponent("%5C%2B%5C%2B%20*(%3F%3A_0x(%3F%3A%5Ba-f0-9%5D)%7B4%2C6%7D%7C(%3F%3A%5Cb%7C%5Cd)%5Ba-z0-9%5D%7B1%2C4%7D(%3F%3A%5Cb%7C%5Cd))") || pattern == decodeURIComponent("(%5C%5C%5Bx%7Cu%5D(%5Cw)%7B2%2C4%7D)%2B")) {
            pattern = '.*?';
            console.log("发现sojson检测特征,已帮您处理。")
        }
        if (modifiers) {
            console.log("疑似最后一个检测...已帮您处理。")
            console.log("已通过全部检测,请手动处理debugger后尽情调试吧!")
            return _RegExp(pattern, modifiers);
        } else {
            return _RegExp(pattern);
        }
    }
    ;
    RegExp.toString = function() {
        return _RegExp.toString();
    }
    ;
}
)();

hook canvas (定位图片生成的地方)

(function() {
    'use strict';
    let create_element = document.createElement.bind(doument);

    document.createElement = function (_element) {
        console.log("create_element:",_element);
        if (_element === "canvas") {
            debugger;
        }
        return create_element(_element);
    }
})();

setInterval 定时器

(function() {
    setInterval_ = setInterval;
    console.log("原函数已被重命名为setInterval_")
    setInterval = function() {}
    ;
    setInterval.toString = function() {
        console.log("有函数正在检测setInterval是否被hook");
        return setInterval_.toString();
    }
    ;
}
)();

setInterval 循环清除定时器

for(var i = 0; i < 9999999; i++) window.clearInterval(i)

console.log 检测例子 (不让你输出调试)

var oldConsole = ["debug", "error", "info", "log", "warn", "dir", "dirxml", "table", "trace", "group", "groupCollapsed", "groupEnd", "clear", "count", "countReset", "assert", "profile", "profileEnd", "time", "timeLog", "timeEnd", "timeStamp", "context", "memory"].map(key=>{
    var old = console[key];
    console[key] = function() {}
    ;
    console[key].toString = old.toString.bind(old)
    return old;
}
)

检测函数是否被hook例子

if (window.eval == 'native code') {
    console.log('发现eval函数被hook了 开始死循环');
}

到此这篇关于javascript常用的Hook脚本的文章就介绍到这了,更多相关js hook脚本内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 详解JavaScript常用的Hook脚本

本文链接: https://lsjlt.com/news/143392.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 详解JavaScript常用的Hook脚本
    本文Hook脚本 来自 包子 页面最早加载代码Hook时机 在source里 用dom事件断点的script断点然后刷新网页,就会断在第一个js标签,这时候就可以注入代码进行hook...
    99+
    2024-04-02
  • React Hook用法示例详解(6个常见hook)
    1、useState:让函数式组件拥有状态 用法示例: // 计数器 import { useState } from 'react' const Test = () =>...
    99+
    2024-04-02
  • 详解JavaScript中的before-after-hook钩子函数
    目录before-after-hook1.单独的钩子2.Hook collectionbefore-after-hook 最近看别人的代码,接触到一个插件,before-after-...
    99+
    2022-12-15
    JavaScript before-after-hook钩子函数 JavaScript before-after-hook JavaScript 钩子函数
  • shell脚本--sed的用法详解
    sed在处理文本时是逐行读取文件内容,读到匹配的行就根据指令做操作,不匹配就跳过。 sed是linux下一款功能强大的非交互流式文本编辑器,可以对文本文件进行增、删、改、查等操作,支持按行、按字段、按正则匹配文本内容,灵...
    99+
    2022-06-04
    shell --sed
  • Python写脚本常用模块OS基础用法详解
    收集了一些关于OS库的用法,整理归纳一下,方便使用 import os # 系统操作 print(os.sep) # 获取当前系统的路径分隔符 print(os.n...
    99+
    2024-04-02
  • PostgreSQL 常用脚本
    数据定义 数据库 -- 创建数据库 -- database_name,数据库名称 -- database_user,用户名 CREATE DATABASE database_name WITH OWNER = database_...
    99+
    2015-03-18
    PostgreSQL 常用脚本
  • MySQL常用脚本
    🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚 🌟推荐给...
    99+
    2023-10-18
    adb android MySQL oracle sqlserver sql
  • Linux 常用脚本
    以下是几个 Linux 常用脚本示例: 自动备份脚本 这个脚本用于定期备份指定目录中的文件,并将备份文件保存到另一个目录中。 #!/bin/bashbackup_dir="/home/user/backup/"source_dir="/ho...
    99+
    2023-08-19
    linux 运维 服务器
  • Shell 脚本详解
    简介 shell :蛋、壳。shell脚本是在操作系统外,可以直接调用系统内核命令的一个脚本语言。 shell脚本可以分为两大类组成: 1.命令行 (系统命令行)2.脚本语法 (编程语言的基本语法) 命令行:可以直接和系统内核进行交换使用 ...
    99+
    2023-08-19
    linux bash 服务器
  • ORACLE 常用脚本(3)
    用户的管理一、ORACLE的安全域 1、TABLESPACE QUOTAS:表空间的使用定额 2、DEFAULT TABLESPACE:默认表空间 3、TEMPORARY TABLESPACE:指定临时表空间。 4、ACCOUNT LOCK...
    99+
    2023-01-31
    脚本 常用 ORACLE
  • python常用的备份脚本
    脚本介绍:1)备份源目录的文件2)目标文件以tar 和bzip2的方式压缩之后放在当前日期文件夹下4)备份文件以时间注释和执行脚本的用户命名3)主要用到了时间模块,系统模块,和getpass模块4)source 可以修改为想备份的目录,因为...
    99+
    2023-01-31
    脚本 备份 常用
  • linux shell脚本详解
    shell 1. 基础 # shell的执行方式:- 路径方式 :必须赋予权限- source 立即执行,不需要权限- bash 执行新建一个文件,扩展名为sh(sh代表shell),输入一些代码:...
    99+
    2023-09-08
    linux bash 运维
  • 详解Jmeter中的BeanShell脚本
    在利用jmeter进行接口测试或者性能测试的时候,我们需要处理一些复杂的请求,此时就需要利用beanshell脚本了,BeanShell是一种完全符合Java语法规范的脚本语言,并且...
    99+
    2024-04-02
  • shell脚本中常见的一些特殊符号和作用详解
    在编写Shell脚本时,我们需要会用到各种各样的特殊符号,通过这些特殊符号可以使我们编写的代码更加简洁和高效,这里给大家汇总下: 1、{} 大括号: 用法一:通配符扩展 eg: ls my_{finger...
    99+
    2022-06-04
    详解 脚本 常见
  • shell脚本之sed详细用法详解
    目录sed的作用sed使用方法介绍命令行格式举例说明对文件进行增、删、改、查操作增加文件内容对文件进行搜索替换操作其他命令其他选项sed结合正则使用补充扩展总结总结sed的作用 sed是Stream Editor(流编辑...
    99+
    2022-07-05
    shell脚本 sed shell sed命令详解 sed命令详解
  • 常见的Python脚本
    1、冒泡排序 lis = [56,12,1,8,354,10,100,34,56,7,23,456,234,-58] def sortport(): for i in range(len(lis)-1): fo...
    99+
    2023-01-30
    脚本 常见 Python
  • 详解JavaScript数组的常用方法
    目录数组的常用方法pop()unshift()shift()slice()splice()数组元素去重concat()join()reverse()sort()总...
    99+
    2024-04-02
  • MHA常用脚本简介
    master_ip_failover 常见的HA环境下,大多是情况会给master分配一个虚拟IP,如果master宕机,HA软件像一个Pacemaker将虚拟IP转移到备用的master上. ...
    99+
    2024-04-02
  • 50个常用Python脚本
    50个常用Python脚本的代码示例: 复制文件和目录 import shutilshutil.copy2('source_file', 'destination')shutil.copytree('...
    99+
    2023-09-01
    python excel 开发语言
  • RMAN常用脚本是怎样的
    这期内容当中小编将会给大家带来有关RMAN常用脚本是怎样的,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。 在学习了rman后自我感觉比较好用...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作