├── LICENSE ├── README.md ├── include └── js-hooker.js └── pics └── preview.jpg /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 DosX 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JS-Hooker 2 | 3 | ![preview](pics/preview.jpg) 4 | 5 | **[js-hooker.js](https://github.com/DosX-dev/js-hooker/blob/main/include/js-hooker.js)** is a JavaScript module designed for reverse engineering and debugging. It provides a straightforward way to monitor and log external calls made within an application, helping you understand function usage and behavior. 6 | 7 | --- 8 | 9 | **Features** 10 | 11 | * 🚀 **Real-Time Function Call Monitoring** 12 | * 🔍 **Native and Code Call Differentiation** 13 | * ⚙️ **Customizable Scope** 14 | * 📋 **Readable Console Output** 15 | * 🌐 **Flexible Environment Support** 16 | 17 | --- 18 | 19 | ## 📖 Usage 20 | 21 | > [!IMPORTANT] 22 | > The module only tracks existing (already declared) functions. New ones will be ignored. Connect it only after initialization. 23 | 24 | 1. **Load the Module**: 25 | Include the script in HTML file like this: 26 | ```html 27 | 28 | ``` 29 | Or, inject it using: 30 | - A custom browser extension 31 | - Developer tools console 32 | 33 | 2. **Automatic Hooking**: 34 | By default, the script hooks into frequently used objects like: 35 | - `window` 36 | - `navigator` 37 | - `localStorage` 38 | - `sessionStorage` 39 | - `document` 40 | - `history` 41 | 42 | 3. **Custom Hooking**: 43 | To manually hook specific objects or exclude certain functions: 44 | ```javascript 45 | watchAllFunctions(customObject, ["methodToExclude"]); 46 | ``` 47 | 48 | 4. **Console Output**: 49 | When a hooked function is called, you'll see this in the console: 50 | ``` 51 | [N] [CALL CAPTURED]: functionName(arg1, arg2, ...); 52 | ``` 53 | - `[N]`: Native function call 54 | - `[C]`: Code call (custom function defined in the app) 55 | 56 | ## 📊 Sample Output 57 | 58 | #### Native Function Call 59 | ```plaintext 60 | [N] [CALL CAPTURED]: localStorage.getItem("key"); 61 | ``` 62 | 63 | #### Code Call (Custom Function) 64 | ```plaintext 65 | [C] [CALL CAPTURED]: customFunction("test", { "param": true }); 66 | ``` 67 | 68 | ## ⚙️ Advanced Configuration 69 | 70 | **Exclude-list**: To avoid tracking specific functions, add their names to the exclusion list: 71 | ```javascript 72 | watchAllFunctions(window, ["alert"]); 73 | ``` 74 | 75 | ## ⚠️ Limitations 76 | 77 | The `watchAllFunctions` method does not work for non-enumerable functions (e.g., `eval`). In such cases, you should manually apply the hook like this: 78 | ```javascript 79 | // Replace original 'eval' 80 | eval = getHookedFunction(eval); 81 | ``` 82 | 83 | ## 🛠️ Customization 84 | This script is intentionally simple to modify. You can tweak its behavior, such as the logging format, which objects it tracks, or even extend its functionality to match your requirements. 85 | 86 | ## 📜 Disclaimer 87 | This tool is for educational purposes, debugging, and lawful reverse engineering only. Ensure compliance with legal and ethical guidelines while using it. 88 | -------------------------------------------------------------------------------- /include/js-hooker.js: -------------------------------------------------------------------------------- 1 | // Coded by DosX 2 | // We're not like this — life is like this. 3 | 4 | console.clear(); 5 | 6 | console.log(` 7 | __ _____ _____ _ 8 | __| | __|___| | |___ ___| |_ ___ ___ 9 | | | |__ |___| | . | . | '_| -_| _| 10 | |_____|_____| |__|__|___|___|_,_|___|_| 11 | https://github.com/DosX-dev/js-hooker 12 | Coded by DosX 13 | 14 | `); 15 | 16 | 17 | const nativeFunctionCache = {}; 18 | 19 | function watchAllFunctions(obj, exclude = []) { 20 | for (let key in obj) { 21 | if (typeof obj[key] === 'function' && !exclude.includes(key)) { 22 | const originalFunction = obj[key]; 23 | 24 | if (obj[key] === watchAllFunctions || obj[key] === getHookedFunction) { 25 | continue; 26 | } 27 | 28 | obj[key] = getHookedFunction(originalFunction); 29 | } 30 | } 31 | } 32 | 33 | function getHookedFunction(originalFunction) { 34 | return function() { 35 | "[native code]"; 36 | const args = Array.from(arguments).map(arg => { 37 | if (typeof arg === 'string') { 38 | return `"${arg.replace(/"/g, '\\"').replace(/\n/g, '\\n')}"`; 39 | } else if (typeof arg === 'object') { 40 | try { 41 | return JSON.stringify(arg); 42 | } catch (e) { 43 | return '[Circular]'; 44 | } 45 | } else { 46 | return arg; 47 | } 48 | }); 49 | 50 | if (!(originalFunction.name in nativeFunctionCache)) { 51 | nativeFunctionCache[originalFunction.name] = !!originalFunction && (typeof originalFunction).toLowerCase() === 'function' && 52 | (originalFunction === Function.prototype || 53 | /^\s*function\s*(\b[a-z$_][a-z0-9$_]*\b)*\s*\((|([a-z$_][a-z0-9$_]*)(\s*,[a-z$_][a-z0-9$_]*)*)\)\s*{\s*\[native code\]\s*}\s*$/i.test(String(originalFunction))); 54 | } 55 | 56 | const isNativeFunction = nativeFunctionCache[originalFunction.name]; 57 | 58 | console.log( 59 | `%c${isNativeFunction ? '[N]' : '[C]'}%c %c[CALL CAPTURED]%c : ${originalFunction.name}(` + args.join(', ') + ");", 60 | `color: white; background: ${isNativeFunction ? 'red' : 'gray'};`, 61 | 'color: default;', 62 | 'color: white; background: darkorange;', 63 | 'color: default;' 64 | ); 65 | 66 | if (originalFunction) { 67 | return Function.prototype.apply.call(originalFunction, this, arguments); 68 | } 69 | }; 70 | } 71 | 72 | // Change depending on what you need to track. 73 | if (typeof global === 'object') { // Node.js 74 | watchAllFunctions(global); 75 | } else if (typeof window === 'object') { // Browser 76 | watchAllFunctions(window); 77 | watchAllFunctions(navigator); 78 | watchAllFunctions(localStorage); 79 | watchAllFunctions(sessionStorage); 80 | watchAllFunctions(document); 81 | watchAllFunctions(history); 82 | } 83 | 84 | watchAllFunctions(console, ["log"]); // exclude console.log(...) function -------------------------------------------------------------------------------- /pics/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DosX-dev/JS-Hooker/0aa7c914aab3e603780f545dacd24a2c7e35fada/pics/preview.jpg --------------------------------------------------------------------------------