// ==UserScript== // @name 逆向脚本工具 // @license false // @namespace https://bbs.tampermonkey.net.cn/ // @version 1.0.0 // @description 逆向脚本工具js逆向 // @author manji // @require https://scriptcat.org/lib/637/1.3.0/ajaxHooker.js // @require https://scriptcat.org/lib/721/1.0.1/gmCookie.js // @require https://scriptcat.org/lib/513/2.1.0/ElementGetter.js // @require https://fastapi.work321.cn/apps1/js/package/JsBarcode.all.min.js // @require https://fastapi.work321.cn/apps1/js/pingduoduo/res_anti-content.js // @match https://* // @grant GM_xmlhttpRequest // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @grant GM_listValues // @grant GM_cookie // @run-at document-start // @connect pinduoduo.com // ==/UserScript== /* ==UserConfig== hook配置: header_name: title: Header Name description: 请输入需要hook的Header名称 type: text default: "X-Requested-With" json_stringify操作: title: JSON Stringify description: 是否启用JSON Stringify的hook操作 type: switch default: false json_parse操作: title: JSON Parse description: 是否启用JSON Parse的hook操作 type: switch default: false javascript_eval: title: Javascript Eval description: 是否启用Javascript Eval的hook操作 type: switch default: false function_hook: title: Function Hook description: 是否启用Function Hook的hook操作 type: switch default: false url_hook: title: URL Hook description: 是否启用URL Hook的hook操作 type: text default: cookie_hook: title: Cookie Hook description: 是否启用Cookie Hook的hook操作 type: text default: ==/UserConfig== */ // 配置参数中的字符串获取模式是小写的,如果比较的时候要把比较对象也转成小写 .toLowerCase() (function () { // hook教程:https://mp.weixin.qq.com/s/E99i02-2ZzkIBH1mcX8q_A // Cookie Hook 用于定位 Cookie 中关键参数生成位置, // 以下代码演示了当 Cookie 中匹配到了 __dfp 关键字, 则插入断点: cookie_hook = GM_getValue('hook配置.cookie_hook',''); if(cookie_hook){ cookie_name = cookie_hook.toString().trim(); const origDescriptor = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie') || Object.getOwnPropertyDescriptor(document.__proto__.constructor.prototype, 'cookie'); const originalGetter = origDescriptor.get; const originalSetter = origDescriptor.set; Object.defineProperty(document, 'cookie', { configurable: false, enumerable: true, get: function() { return originalGetter.call(document); }, set: function(val) { if (val.toLowerCase().includes(cookie_name.toLowerCase())) { debugger; } console.log('Set Cookie:', val); return originalSetter.call(document, val); } }); }; // URL Hook 用于定位请求 URL 中关键参数生成位置, // 以下代码演示了当请求的 URL 里包含 login 关键字时,则插入断点 url_hook = GM_getValue('hook配置.url_hook',''); console.log('URL的Hook操作:',url_hook); if(url_hook){ url_hook = url_hook.toString().trim().toLowerCase(); var open = window.XMLHttpRequest.prototype.open; window.XMLHttpRequest.prototype.open = function (method, url, async) { if (url.toLowerCase().indexOf(url_hook) != 1) { debugger; } return open.apply(this, arguments); }; }; // function_hook 以下代码执行后,所有的函数操作都会在控制台打印输出将要执行的 JS 源码: function_hook = GM_getValue('hook配置.function_hook','') console.log('function的hook操作:',function_hook); if(function_hook==true){ // 保存原始方法 window.__cr_fun = window.Function; // 重写 function var myfun = function() { var args = Array.prototype.slice.call(arguments, 0, -1).join(","), src = arguments[arguments.length - 1]; console.log(src); console.log("=============== Function end ==============="); debugger; returnwindow.__cr_fun.apply(this, arguments); } // 屏蔽js中对原生函数native属性的检测 myfun.toString = function() { returnwindow.__cr_fun + "" } Object.defineProperty(window, 'Function', { value: myfun }); }; // JavaScript eval() 函数的作用是计算 JavaScript 字符串,并把它作为 脚本代码来执行。 // 如果参数是一个表达式,eval() 函数将执行表达式。 // 如果参数是 Javascript 语句,eval() 将执行 Javascript 语句,经常被用来动态执行 JS。 // 以下代码执行后,之后所有的 eval() 操作都会在控制台打印输出将要执行的 JS 源码: javascript_eval = GM_getValue('hook配置.javascript_eval','') console.log('javascript_eval的hook操作:',javascript_eval); if(javascript_eval == true){ // 保存原始方法 window.__cr_eval = window.eval; // 重写 eval var myeval = function(src) { console.log(src); console.log("=============== eval end ==============="); debugger; returnwindow.__cr_eval(src); } // 屏蔽 JS 中对原生函数 native 属性的检测 var _myeval = myeval.bind(null); _myeval.toString = window.__cr_eval.toString; Object.defineProperty(window, 'eval', { value: _myeval }); }; // JSON.parse() 方法用于将一个 JSON 字符串转换为对象,在某些站点的加密过程中可能会遇到, // 以下代码演示了遇到 JSON.parse() 时,则插入断点: json_pars = GM_getValue('hook配置.json_parse操作',''); console.log('json_pars的hook操作:',json_pars); if(json_pars == true){ var parse = JSON.parse; JSON.parse = function(params) { console.log("Hook JSON.parse ——> ", params); debugger; return parse(params); } }; // JSON.stringify() 方法用于将 JavaScript 值转换为 JSON 字符串,在某些站点的加密过程中可能会遇到, // 以下代码演示了遇到 JSON.stringify() 时,则插入断点 json_stringify = GM_getValue('hook配置.json_stringify操作',''); console.log('json_stringify的hook操作:',json_stringify); if(json_stringify == true){ var stringify = JSON.stringify; JSON.stringify = function(params) { console.log("Hook JSON.stringify ——> ", params); debugger; return stringify(params); } }; // Header Hook 用于定位 Header 中关键参数生成位置 // headers_hook = GM_getValue('hook配置.headers_hook','').toString().trim(); header_name = GM_getValue('hook配置.header_name','') console.log("header需要hook的字段名称:",header_name); if( header_name){ header_name = header_name.toString().trim().toLowerCase(); var org = window.XMLHttpRequest.prototype.setRequestHeader; window.XMLHttpRequest.prototype.setRequestHeader = function (key, value) { if (key.toLowerCase() == header_name) {debugger;}; // if(key.indexOf(header_name) != 1){debugger;}; console.log("header_name:",key,"-->>","value:",value); return org.apply(this, arguments); }; } })()