├── .gitignore ├── README.md ├── img ├── screenshot1.png └── screenshot2.png ├── package-lock.json ├── package.json ├── src ├── ESPManager.ts ├── ESPView.ts ├── ESPaint.ts ├── Logger.ts ├── Offset.ts ├── index.ts └── utils.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /dist -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Frida Unity ESP Manager 2 | 3 | This is a NodeJS project for Frida to draw ESP Line and Box on a game using Canvas. 4 | 5 | Made for unity games but can be used for any game with some modifications. 6 | 7 | This should be used only for prototyping and testing purposes. 8 | 9 | Tested on [The Walking Zombie 2](https://play.google.com/store/apps/details?id=com.aldagames.zombieshooter) game. 10 | 11 | ## Known Issues 12 | 13 | - Screen touch response are impacted when ESP refresh rate is high. 14 | 15 | ## Screenshots 16 | 17 | ![screenshot](/img/screenshot1.png) 18 | ![screenshot](/img/screenshot2.png) 19 | 20 | ## Credits 21 | 22 | - [Make Esp For Unity Games, C++](https://platinmods.com/threads/make-esp-for-unity-games-c.160962/) This project is based on this post. 23 | -------------------------------------------------------------------------------- /img/screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maarsalien/frida-unity-esp-manager/fbe3d175756a8c710238452dadc5ad88af6add29/img/screenshot1.png -------------------------------------------------------------------------------- /img/screenshot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maarsalien/frida-unity-esp-manager/fbe3d175756a8c710238452dadc5ad88af6add29/img/screenshot2.png -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frida-esp-manager", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "frida-esp-manager", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "@types/frida-gum": "^18.4.1", 13 | "frida-compile": "^16.3.0", 14 | "typescript": "^5.1.6" 15 | } 16 | }, 17 | "node_modules/@frida/assert": { 18 | "version": "3.0.2", 19 | "resolved": "https://registry.npmjs.org/@frida/assert/-/assert-3.0.2.tgz", 20 | "integrity": "sha512-JXJq5SbXGrM5EkjrZKfRmB29zOoEOix02NC6A5TSJ+C1GE/X051EinJJsuOO2pEOx7KZwpvAHvS0WXW0+levKg==", 21 | "dev": true 22 | }, 23 | "node_modules/@frida/base64-js": { 24 | "version": "2.0.3", 25 | "resolved": "https://registry.npmjs.org/@frida/base64-js/-/base64-js-2.0.3.tgz", 26 | "integrity": "sha512-2w0F+1TynOTCZ/v7du9LdHPWwq0lJhazjo2fF9upMyQmA1zHetT14fLuQ1v/6T0qPgyeEGkiSrybstU8EsgeUA==", 27 | "dev": true, 28 | "funding": [ 29 | { 30 | "type": "github", 31 | "url": "https://github.com/sponsors/feross" 32 | }, 33 | { 34 | "type": "patreon", 35 | "url": "https://www.patreon.com/feross" 36 | }, 37 | { 38 | "type": "consulting", 39 | "url": "https://feross.org/support" 40 | } 41 | ] 42 | }, 43 | "node_modules/@frida/buffer": { 44 | "version": "7.0.4", 45 | "resolved": "https://registry.npmjs.org/@frida/buffer/-/buffer-7.0.4.tgz", 46 | "integrity": "sha512-RxQ1lZRRiCJj7nhcCiD8xeJx0NsLpGGnjqsmTg7jShGmbnVFMN5W7+J+3gqdPSQhc/IxNBIWc6zRXVp4+qnYHg==", 47 | "dev": true, 48 | "funding": [ 49 | { 50 | "type": "github", 51 | "url": "https://github.com/sponsors/feross" 52 | }, 53 | { 54 | "type": "patreon", 55 | "url": "https://www.patreon.com/feross" 56 | }, 57 | { 58 | "type": "consulting", 59 | "url": "https://feross.org/support" 60 | } 61 | ], 62 | "dependencies": { 63 | "base64-js": "^1.5.1", 64 | "ieee754": "^1.2.1" 65 | } 66 | }, 67 | "node_modules/@frida/crosspath": { 68 | "version": "3.0.0", 69 | "resolved": "https://registry.npmjs.org/@frida/crosspath/-/crosspath-3.0.0.tgz", 70 | "integrity": "sha512-bNdO1spIPD2P40XtK89N49oZpJhstdlnkJZcD4yJ17jrdkm9Ctu0sd9MIEX6Z8Tm8ydhVJBAOMEKl9/R27onAQ==", 71 | "dev": true, 72 | "dependencies": { 73 | "@types/node": "^17.0.36" 74 | }, 75 | "engines": { 76 | "node": ">=14.9.0" 77 | } 78 | }, 79 | "node_modules/@frida/diagnostics_channel": { 80 | "version": "1.0.0", 81 | "resolved": "https://registry.npmjs.org/@frida/diagnostics_channel/-/diagnostics_channel-1.0.0.tgz", 82 | "integrity": "sha512-mYX1jp/5Bpk24tHArJNx65iCk7qSuV8YJkdU0gFNVtJUXxfV8BG5WuPa4mL+ynxsbWWpsg/cwKZbLAepYKTdQQ==", 83 | "dev": true 84 | }, 85 | "node_modules/@frida/events": { 86 | "version": "4.0.4", 87 | "resolved": "https://registry.npmjs.org/@frida/events/-/events-4.0.4.tgz", 88 | "integrity": "sha512-qJVQ6VWHf9sjUKuiJzoCAC00frbpcwxeYfvQ+PP9LU/d70j+QvjWgYe98Qa3ekLaBU6r/AvWm8ThKCDUCLWrQQ==", 89 | "dev": true, 90 | "engines": { 91 | "node": ">=0.8.x" 92 | } 93 | }, 94 | "node_modules/@frida/http": { 95 | "version": "4.0.2", 96 | "resolved": "https://registry.npmjs.org/@frida/http/-/http-4.0.2.tgz", 97 | "integrity": "sha512-cvkc7ex7GmVXVOWqtjXKBWUUbYEBgpNRKZbEEoMeI8KiIs8zejKwg+N7rx7296Ao+EP3+xcUr4wBVr3xLaUVfQ==", 98 | "dev": true, 99 | "dependencies": { 100 | "http-parser-js": "^0.5.3" 101 | } 102 | }, 103 | "node_modules/@frida/http-parser-js": { 104 | "version": "1.0.0", 105 | "resolved": "https://registry.npmjs.org/@frida/http-parser-js/-/http-parser-js-1.0.0.tgz", 106 | "integrity": "sha512-2nMrNXt/OeTlWbqnE8AH4Sfz4I2+BGoN206dzKEyC/g2svtn83Xu+zuv/V3TkwrA27s26Mcy84ZwsXeNlqNxUQ==", 107 | "dev": true 108 | }, 109 | "node_modules/@frida/https": { 110 | "version": "1.0.0", 111 | "resolved": "https://registry.npmjs.org/@frida/https/-/https-1.0.0.tgz", 112 | "integrity": "sha512-OiqQ6qsALcWOktRLq07oJ0i6sH8eX6MXb/MdZS1qVKDRf6wchH4Pjn6fiLB+pt/OlYbggk+DOfpHwSdjTwuHMQ==", 113 | "dev": true 114 | }, 115 | "node_modules/@frida/ieee754": { 116 | "version": "2.0.2", 117 | "resolved": "https://registry.npmjs.org/@frida/ieee754/-/ieee754-2.0.2.tgz", 118 | "integrity": "sha512-wlcUebnne4ENN7GDr5pTH598ZDLMVOsh0FjenxeVOe6u7ewZkz9gGRnLnZKJAm9kl5G6XhdxhI0cSXVQK/rQUw==", 119 | "dev": true, 120 | "funding": [ 121 | { 122 | "type": "github", 123 | "url": "https://github.com/sponsors/feross" 124 | }, 125 | { 126 | "type": "patreon", 127 | "url": "https://www.patreon.com/feross" 128 | }, 129 | { 130 | "type": "consulting", 131 | "url": "https://feross.org/support" 132 | } 133 | ] 134 | }, 135 | "node_modules/@frida/net": { 136 | "version": "4.0.2", 137 | "resolved": "https://registry.npmjs.org/@frida/net/-/net-4.0.2.tgz", 138 | "integrity": "sha512-qQRe7hQ+ZfCcG/SE3P1TRqQ9bmuK/T7wPCYaT4z56rBPWAxsaQbQHpX4fR6OrFaSDr7X0xJLsTbdIp9hGhhLZg==", 139 | "dev": true 140 | }, 141 | "node_modules/@frida/os": { 142 | "version": "1.0.2", 143 | "resolved": "https://registry.npmjs.org/@frida/os/-/os-1.0.2.tgz", 144 | "integrity": "sha512-3ISAiGNiyIya3QN2EHBCz1wqP0enTdSxP99wUeroeh8+AQRmgoOr/5TRnrVry8pe378anay3fmV/tdUMMSkehQ==", 145 | "dev": true 146 | }, 147 | "node_modules/@frida/path": { 148 | "version": "2.0.3", 149 | "resolved": "https://registry.npmjs.org/@frida/path/-/path-2.0.3.tgz", 150 | "integrity": "sha512-2RQy36QatoC846fzBhBhV8sXMsSOBGoYvwTHeaE1zUdz7F4RNScP4QEekTTooBYWYX/XjiF36KQpYAzc9OYFtg==", 151 | "dev": true 152 | }, 153 | "node_modules/@frida/process": { 154 | "version": "1.2.1", 155 | "resolved": "https://registry.npmjs.org/@frida/process/-/process-1.2.1.tgz", 156 | "integrity": "sha512-nvCu22DstFW2ttGFtOKekHM7vnjbZm+XgtvavOt427GNT6uV7k0JYK9tnMbcLMRWv57DG6udAmuJlWs8Paq1ag==", 157 | "dev": true 158 | }, 159 | "node_modules/@frida/punycode": { 160 | "version": "3.0.0", 161 | "resolved": "https://registry.npmjs.org/@frida/punycode/-/punycode-3.0.0.tgz", 162 | "integrity": "sha512-XVSDY2KamDs1D5/fTVgHcOSNxdU4kTboxzqJMBbTjcQC7XScIT9c0EfbwKCq7Kci6gWQdsHSCr7lU+9Oc4KAdg==", 163 | "dev": true 164 | }, 165 | "node_modules/@frida/querystring": { 166 | "version": "1.0.0", 167 | "resolved": "https://registry.npmjs.org/@frida/querystring/-/querystring-1.0.0.tgz", 168 | "integrity": "sha512-15m1fOZPmoO/vWlgPJrG/J9/BJDz6a2/JpVGpS8ynNzo+fBhTznaStX5nHxUs24mVTqh/OqLo0EiYJM5WWHXxg==", 169 | "dev": true 170 | }, 171 | "node_modules/@frida/readable-stream": { 172 | "version": "4.1.3", 173 | "resolved": "https://registry.npmjs.org/@frida/readable-stream/-/readable-stream-4.1.3.tgz", 174 | "integrity": "sha512-ntGUFmi+CryRGRJIK13a/VST2Ad19uivbln8Xd92vKPAARq+6vMIASDyZIqyl5BLRccfiyCHdYgrgQ6RI5rUig==", 175 | "dev": true 176 | }, 177 | "node_modules/@frida/reserved-words": { 178 | "version": "1.0.0", 179 | "resolved": "https://registry.npmjs.org/@frida/reserved-words/-/reserved-words-1.0.0.tgz", 180 | "integrity": "sha512-2yG/XxJlsGlk/mm6eZTb4OAaQEhkTI2qaFfZFtAsrA/XuCpuMWkS4y/guyBlsRu4hAuhK2HPmNM8+OLLK1zM9Q==", 181 | "dev": true 182 | }, 183 | "node_modules/@frida/stream": { 184 | "version": "1.0.2", 185 | "resolved": "https://registry.npmjs.org/@frida/stream/-/stream-1.0.2.tgz", 186 | "integrity": "sha512-4OuaC1ztmEKgTq3WeBhsy8Oq+AwW9n9cYnvLklcC9jwD93AEwgbWpecLlxJCVuALvTMdhKPg0nQVfyGYP/i9Bw==", 187 | "dev": true, 188 | "dependencies": { 189 | "@frida/readable-stream": "^4.1.3" 190 | } 191 | }, 192 | "node_modules/@frida/string_decoder": { 193 | "version": "2.0.0", 194 | "resolved": "https://registry.npmjs.org/@frida/string_decoder/-/string_decoder-2.0.0.tgz", 195 | "integrity": "sha512-in371tYZMHQiW9HF5MS3JDw6Ao6tyBoq34UWy2rzOswYyMG1rpizh85ofi/yVkxDiaqybEZefxzkVittpPGT6g==", 196 | "dev": true 197 | }, 198 | "node_modules/@frida/terser": { 199 | "version": "1.0.0", 200 | "resolved": "https://registry.npmjs.org/@frida/terser/-/terser-1.0.0.tgz", 201 | "integrity": "sha512-59h9WuNzD1Rx/zwoWqQ/FW/4Y/Q3R91Eng2hEwdHapqiTDvtKbZ08F6CynCR7ZVinrh4tLYsF46AtVPTz1ys9g==", 202 | "dev": true, 203 | "dependencies": { 204 | "@jridgewell/source-map": "^0.3.2", 205 | "acorn": "^8.5.0", 206 | "commander": "^2.20.0", 207 | "source-map-support": "~0.5.20" 208 | }, 209 | "bin": { 210 | "terser": "bin/terser" 211 | }, 212 | "engines": { 213 | "node": ">=10" 214 | } 215 | }, 216 | "node_modules/@frida/terser/node_modules/commander": { 217 | "version": "2.20.3", 218 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", 219 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", 220 | "dev": true 221 | }, 222 | "node_modules/@frida/timers": { 223 | "version": "3.0.0", 224 | "resolved": "https://registry.npmjs.org/@frida/timers/-/timers-3.0.0.tgz", 225 | "integrity": "sha512-3b+0igv10aT8TMxefrTAd06rActqbxJLY2Xkkq9vYcPBffB/yHszl0NYIp/5ko8WC3ecDYPU6bQiY6fjs72zTA==", 226 | "dev": true 227 | }, 228 | "node_modules/@frida/tty": { 229 | "version": "1.0.0", 230 | "resolved": "https://registry.npmjs.org/@frida/tty/-/tty-1.0.0.tgz", 231 | "integrity": "sha512-p/kjLnKYxEAB1MdYP8+5rKv9CsHzyA+0jg9BcGETzjQVKHHcroHDULRxDYUh+DC7qs6cpX8QdDQh9E+a6ydgsQ==", 232 | "dev": true 233 | }, 234 | "node_modules/@frida/url": { 235 | "version": "1.0.2", 236 | "resolved": "https://registry.npmjs.org/@frida/url/-/url-1.0.2.tgz", 237 | "integrity": "sha512-ZKunbKJHMr8w2Eb/5K1avy0MzK1B998S17wYXNv3RmzBGxMm8S5T0F3qEpRxkU7/72P8m4izyQU87fWl+FjQsQ==", 238 | "dev": true, 239 | "dependencies": { 240 | "@frida/punycode": "^3.0.0", 241 | "@frida/querystring": "^1.0.0" 242 | } 243 | }, 244 | "node_modules/@frida/util": { 245 | "version": "1.0.3", 246 | "resolved": "https://registry.npmjs.org/@frida/util/-/util-1.0.3.tgz", 247 | "integrity": "sha512-htcG3uDiRXv89ERVNNYhfase39kJ2X75ZARfrYcYEtJLFEsSk0nemM1YnEIR4CjrHvdvkWHrwgKkS+acOyoNEg==", 248 | "dev": true 249 | }, 250 | "node_modules/@frida/vm": { 251 | "version": "2.0.0", 252 | "resolved": "https://registry.npmjs.org/@frida/vm/-/vm-2.0.0.tgz", 253 | "integrity": "sha512-7fsjLWscZT5odNIBtg6qbLNI+vAk1xmii6H5W2kaYkMYt0vRohQEcDSUWacA+eaWlu5SvMjZI82Yibj/3G9pJw==", 254 | "dev": true 255 | }, 256 | "node_modules/@jridgewell/gen-mapping": { 257 | "version": "0.3.3", 258 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", 259 | "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", 260 | "dev": true, 261 | "dependencies": { 262 | "@jridgewell/set-array": "^1.0.1", 263 | "@jridgewell/sourcemap-codec": "^1.4.10", 264 | "@jridgewell/trace-mapping": "^0.3.9" 265 | }, 266 | "engines": { 267 | "node": ">=6.0.0" 268 | } 269 | }, 270 | "node_modules/@jridgewell/resolve-uri": { 271 | "version": "3.1.0", 272 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", 273 | "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", 274 | "dev": true, 275 | "engines": { 276 | "node": ">=6.0.0" 277 | } 278 | }, 279 | "node_modules/@jridgewell/set-array": { 280 | "version": "1.1.2", 281 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", 282 | "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", 283 | "dev": true, 284 | "engines": { 285 | "node": ">=6.0.0" 286 | } 287 | }, 288 | "node_modules/@jridgewell/source-map": { 289 | "version": "0.3.5", 290 | "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", 291 | "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", 292 | "dev": true, 293 | "dependencies": { 294 | "@jridgewell/gen-mapping": "^0.3.0", 295 | "@jridgewell/trace-mapping": "^0.3.9" 296 | } 297 | }, 298 | "node_modules/@jridgewell/sourcemap-codec": { 299 | "version": "1.4.15", 300 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", 301 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", 302 | "dev": true 303 | }, 304 | "node_modules/@jridgewell/trace-mapping": { 305 | "version": "0.3.18", 306 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", 307 | "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", 308 | "dev": true, 309 | "dependencies": { 310 | "@jridgewell/resolve-uri": "3.1.0", 311 | "@jridgewell/sourcemap-codec": "1.4.14" 312 | } 313 | }, 314 | "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { 315 | "version": "1.4.14", 316 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", 317 | "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", 318 | "dev": true 319 | }, 320 | "node_modules/@types/frida-gum": { 321 | "version": "18.4.1", 322 | "resolved": "https://registry.npmjs.org/@types/frida-gum/-/frida-gum-18.4.1.tgz", 323 | "integrity": "sha512-81WHL19NhJoNaDapWJ9WV2XQLAsN17CXKs5aVbvwGaz8vXoT0rzUHQbOBcbH0CuJxA33KOmD8AWnf7USxo9ZXw==", 324 | "dev": true 325 | }, 326 | "node_modules/@types/node": { 327 | "version": "17.0.45", 328 | "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", 329 | "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", 330 | "dev": true 331 | }, 332 | "node_modules/acorn": { 333 | "version": "8.10.0", 334 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", 335 | "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", 336 | "dev": true, 337 | "bin": { 338 | "acorn": "bin/acorn" 339 | }, 340 | "engines": { 341 | "node": ">=0.4.0" 342 | } 343 | }, 344 | "node_modules/base64-js": { 345 | "version": "1.5.1", 346 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 347 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", 348 | "dev": true, 349 | "funding": [ 350 | { 351 | "type": "github", 352 | "url": "https://github.com/sponsors/feross" 353 | }, 354 | { 355 | "type": "patreon", 356 | "url": "https://www.patreon.com/feross" 357 | }, 358 | { 359 | "type": "consulting", 360 | "url": "https://feross.org/support" 361 | } 362 | ] 363 | }, 364 | "node_modules/buffer-from": { 365 | "version": "1.1.2", 366 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", 367 | "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", 368 | "dev": true 369 | }, 370 | "node_modules/commander": { 371 | "version": "9.5.0", 372 | "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", 373 | "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", 374 | "dev": true, 375 | "engines": { 376 | "node": "^12.20.0 || >=14" 377 | } 378 | }, 379 | "node_modules/frida-compile": { 380 | "version": "16.3.0", 381 | "resolved": "https://registry.npmjs.org/frida-compile/-/frida-compile-16.3.0.tgz", 382 | "integrity": "sha512-WpnvUzQtWnc8xPnFmmYCajJKzyKQLM/QEOvasgFYTjaXNfDJHjrHIDxgx/ZXSNidmxK3FZofs+LsuGMq9wEqqA==", 383 | "dev": true, 384 | "dependencies": { 385 | "@frida/assert": "^3.0.1", 386 | "@frida/base64-js": "^2.0.3", 387 | "@frida/buffer": "^7.0.4", 388 | "@frida/crosspath": "^3.0.0", 389 | "@frida/diagnostics_channel": "^1.0.0", 390 | "@frida/events": "^4.0.4", 391 | "@frida/http": "^4.0.2", 392 | "@frida/http-parser-js": "^1.0.0", 393 | "@frida/https": "^1.0.0", 394 | "@frida/ieee754": "^2.0.2", 395 | "@frida/net": "^4.0.1", 396 | "@frida/os": "^1.0.0", 397 | "@frida/path": "^2.0.3", 398 | "@frida/process": "^1.2.1", 399 | "@frida/punycode": "^3.0.0", 400 | "@frida/querystring": "^1.0.0", 401 | "@frida/readable-stream": "^4.1.3", 402 | "@frida/reserved-words": "^1.0.0", 403 | "@frida/stream": "^1.0.2", 404 | "@frida/string_decoder": "^2.0.0", 405 | "@frida/terser": "^1.0.0", 406 | "@frida/timers": "^3.0.0", 407 | "@frida/tty": "^1.0.0", 408 | "@frida/url": "^1.0.2", 409 | "@frida/util": "^1.0.3", 410 | "@frida/vm": "^2.0.0", 411 | "commander": "^9.4.0", 412 | "frida-fs": "^5.2.3", 413 | "typed-emitter": "^2.1.0" 414 | }, 415 | "bin": { 416 | "frida-compile": "dist/cli.js" 417 | } 418 | }, 419 | "node_modules/frida-fs": { 420 | "version": "5.2.5", 421 | "resolved": "https://registry.npmjs.org/frida-fs/-/frida-fs-5.2.5.tgz", 422 | "integrity": "sha512-Eyb4OqUlcv1/Eq7Q+B9IZmYZIgIM2YjqDojrjmAGzPSSXBuUKwSkuObQcQ8Dup9JTOMIUcSII9/I8DaTe6LFKw==", 423 | "dev": true 424 | }, 425 | "node_modules/http-parser-js": { 426 | "version": "0.5.8", 427 | "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", 428 | "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", 429 | "dev": true 430 | }, 431 | "node_modules/ieee754": { 432 | "version": "1.2.1", 433 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", 434 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", 435 | "dev": true, 436 | "funding": [ 437 | { 438 | "type": "github", 439 | "url": "https://github.com/sponsors/feross" 440 | }, 441 | { 442 | "type": "patreon", 443 | "url": "https://www.patreon.com/feross" 444 | }, 445 | { 446 | "type": "consulting", 447 | "url": "https://feross.org/support" 448 | } 449 | ] 450 | }, 451 | "node_modules/rxjs": { 452 | "version": "7.8.1", 453 | "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", 454 | "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", 455 | "dev": true, 456 | "optional": true, 457 | "dependencies": { 458 | "tslib": "^2.1.0" 459 | } 460 | }, 461 | "node_modules/source-map": { 462 | "version": "0.6.1", 463 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 464 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 465 | "dev": true, 466 | "engines": { 467 | "node": ">=0.10.0" 468 | } 469 | }, 470 | "node_modules/source-map-support": { 471 | "version": "0.5.21", 472 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", 473 | "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", 474 | "dev": true, 475 | "dependencies": { 476 | "buffer-from": "^1.0.0", 477 | "source-map": "^0.6.0" 478 | } 479 | }, 480 | "node_modules/tslib": { 481 | "version": "2.6.1", 482 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", 483 | "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==", 484 | "dev": true, 485 | "optional": true 486 | }, 487 | "node_modules/typed-emitter": { 488 | "version": "2.1.0", 489 | "resolved": "https://registry.npmjs.org/typed-emitter/-/typed-emitter-2.1.0.tgz", 490 | "integrity": "sha512-g/KzbYKbH5C2vPkaXGu8DJlHrGKHLsM25Zg9WuC9pMGfuvT+X25tZQWo5fK1BjBm8+UrVE9LDCvaY0CQk+fXDA==", 491 | "dev": true, 492 | "optionalDependencies": { 493 | "rxjs": "*" 494 | } 495 | }, 496 | "node_modules/typescript": { 497 | "version": "5.1.6", 498 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", 499 | "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", 500 | "dev": true, 501 | "bin": { 502 | "tsc": "bin/tsc", 503 | "tsserver": "bin/tsserver" 504 | }, 505 | "engines": { 506 | "node": ">=14.17" 507 | } 508 | } 509 | }, 510 | "dependencies": { 511 | "@frida/assert": { 512 | "version": "3.0.2", 513 | "resolved": "https://registry.npmjs.org/@frida/assert/-/assert-3.0.2.tgz", 514 | "integrity": "sha512-JXJq5SbXGrM5EkjrZKfRmB29zOoEOix02NC6A5TSJ+C1GE/X051EinJJsuOO2pEOx7KZwpvAHvS0WXW0+levKg==", 515 | "dev": true 516 | }, 517 | "@frida/base64-js": { 518 | "version": "2.0.3", 519 | "resolved": "https://registry.npmjs.org/@frida/base64-js/-/base64-js-2.0.3.tgz", 520 | "integrity": "sha512-2w0F+1TynOTCZ/v7du9LdHPWwq0lJhazjo2fF9upMyQmA1zHetT14fLuQ1v/6T0qPgyeEGkiSrybstU8EsgeUA==", 521 | "dev": true 522 | }, 523 | "@frida/buffer": { 524 | "version": "7.0.4", 525 | "resolved": "https://registry.npmjs.org/@frida/buffer/-/buffer-7.0.4.tgz", 526 | "integrity": "sha512-RxQ1lZRRiCJj7nhcCiD8xeJx0NsLpGGnjqsmTg7jShGmbnVFMN5W7+J+3gqdPSQhc/IxNBIWc6zRXVp4+qnYHg==", 527 | "dev": true, 528 | "requires": { 529 | "base64-js": "^1.5.1", 530 | "ieee754": "^1.2.1" 531 | } 532 | }, 533 | "@frida/crosspath": { 534 | "version": "3.0.0", 535 | "resolved": "https://registry.npmjs.org/@frida/crosspath/-/crosspath-3.0.0.tgz", 536 | "integrity": "sha512-bNdO1spIPD2P40XtK89N49oZpJhstdlnkJZcD4yJ17jrdkm9Ctu0sd9MIEX6Z8Tm8ydhVJBAOMEKl9/R27onAQ==", 537 | "dev": true, 538 | "requires": { 539 | "@types/node": "^17.0.36" 540 | } 541 | }, 542 | "@frida/diagnostics_channel": { 543 | "version": "1.0.0", 544 | "resolved": "https://registry.npmjs.org/@frida/diagnostics_channel/-/diagnostics_channel-1.0.0.tgz", 545 | "integrity": "sha512-mYX1jp/5Bpk24tHArJNx65iCk7qSuV8YJkdU0gFNVtJUXxfV8BG5WuPa4mL+ynxsbWWpsg/cwKZbLAepYKTdQQ==", 546 | "dev": true 547 | }, 548 | "@frida/events": { 549 | "version": "4.0.4", 550 | "resolved": "https://registry.npmjs.org/@frida/events/-/events-4.0.4.tgz", 551 | "integrity": "sha512-qJVQ6VWHf9sjUKuiJzoCAC00frbpcwxeYfvQ+PP9LU/d70j+QvjWgYe98Qa3ekLaBU6r/AvWm8ThKCDUCLWrQQ==", 552 | "dev": true 553 | }, 554 | "@frida/http": { 555 | "version": "4.0.2", 556 | "resolved": "https://registry.npmjs.org/@frida/http/-/http-4.0.2.tgz", 557 | "integrity": "sha512-cvkc7ex7GmVXVOWqtjXKBWUUbYEBgpNRKZbEEoMeI8KiIs8zejKwg+N7rx7296Ao+EP3+xcUr4wBVr3xLaUVfQ==", 558 | "dev": true, 559 | "requires": { 560 | "http-parser-js": "^0.5.3" 561 | } 562 | }, 563 | "@frida/http-parser-js": { 564 | "version": "1.0.0", 565 | "resolved": "https://registry.npmjs.org/@frida/http-parser-js/-/http-parser-js-1.0.0.tgz", 566 | "integrity": "sha512-2nMrNXt/OeTlWbqnE8AH4Sfz4I2+BGoN206dzKEyC/g2svtn83Xu+zuv/V3TkwrA27s26Mcy84ZwsXeNlqNxUQ==", 567 | "dev": true 568 | }, 569 | "@frida/https": { 570 | "version": "1.0.0", 571 | "resolved": "https://registry.npmjs.org/@frida/https/-/https-1.0.0.tgz", 572 | "integrity": "sha512-OiqQ6qsALcWOktRLq07oJ0i6sH8eX6MXb/MdZS1qVKDRf6wchH4Pjn6fiLB+pt/OlYbggk+DOfpHwSdjTwuHMQ==", 573 | "dev": true 574 | }, 575 | "@frida/ieee754": { 576 | "version": "2.0.2", 577 | "resolved": "https://registry.npmjs.org/@frida/ieee754/-/ieee754-2.0.2.tgz", 578 | "integrity": "sha512-wlcUebnne4ENN7GDr5pTH598ZDLMVOsh0FjenxeVOe6u7ewZkz9gGRnLnZKJAm9kl5G6XhdxhI0cSXVQK/rQUw==", 579 | "dev": true 580 | }, 581 | "@frida/net": { 582 | "version": "4.0.2", 583 | "resolved": "https://registry.npmjs.org/@frida/net/-/net-4.0.2.tgz", 584 | "integrity": "sha512-qQRe7hQ+ZfCcG/SE3P1TRqQ9bmuK/T7wPCYaT4z56rBPWAxsaQbQHpX4fR6OrFaSDr7X0xJLsTbdIp9hGhhLZg==", 585 | "dev": true 586 | }, 587 | "@frida/os": { 588 | "version": "1.0.2", 589 | "resolved": "https://registry.npmjs.org/@frida/os/-/os-1.0.2.tgz", 590 | "integrity": "sha512-3ISAiGNiyIya3QN2EHBCz1wqP0enTdSxP99wUeroeh8+AQRmgoOr/5TRnrVry8pe378anay3fmV/tdUMMSkehQ==", 591 | "dev": true 592 | }, 593 | "@frida/path": { 594 | "version": "2.0.3", 595 | "resolved": "https://registry.npmjs.org/@frida/path/-/path-2.0.3.tgz", 596 | "integrity": "sha512-2RQy36QatoC846fzBhBhV8sXMsSOBGoYvwTHeaE1zUdz7F4RNScP4QEekTTooBYWYX/XjiF36KQpYAzc9OYFtg==", 597 | "dev": true 598 | }, 599 | "@frida/process": { 600 | "version": "1.2.1", 601 | "resolved": "https://registry.npmjs.org/@frida/process/-/process-1.2.1.tgz", 602 | "integrity": "sha512-nvCu22DstFW2ttGFtOKekHM7vnjbZm+XgtvavOt427GNT6uV7k0JYK9tnMbcLMRWv57DG6udAmuJlWs8Paq1ag==", 603 | "dev": true 604 | }, 605 | "@frida/punycode": { 606 | "version": "3.0.0", 607 | "resolved": "https://registry.npmjs.org/@frida/punycode/-/punycode-3.0.0.tgz", 608 | "integrity": "sha512-XVSDY2KamDs1D5/fTVgHcOSNxdU4kTboxzqJMBbTjcQC7XScIT9c0EfbwKCq7Kci6gWQdsHSCr7lU+9Oc4KAdg==", 609 | "dev": true 610 | }, 611 | "@frida/querystring": { 612 | "version": "1.0.0", 613 | "resolved": "https://registry.npmjs.org/@frida/querystring/-/querystring-1.0.0.tgz", 614 | "integrity": "sha512-15m1fOZPmoO/vWlgPJrG/J9/BJDz6a2/JpVGpS8ynNzo+fBhTznaStX5nHxUs24mVTqh/OqLo0EiYJM5WWHXxg==", 615 | "dev": true 616 | }, 617 | "@frida/readable-stream": { 618 | "version": "4.1.3", 619 | "resolved": "https://registry.npmjs.org/@frida/readable-stream/-/readable-stream-4.1.3.tgz", 620 | "integrity": "sha512-ntGUFmi+CryRGRJIK13a/VST2Ad19uivbln8Xd92vKPAARq+6vMIASDyZIqyl5BLRccfiyCHdYgrgQ6RI5rUig==", 621 | "dev": true 622 | }, 623 | "@frida/reserved-words": { 624 | "version": "1.0.0", 625 | "resolved": "https://registry.npmjs.org/@frida/reserved-words/-/reserved-words-1.0.0.tgz", 626 | "integrity": "sha512-2yG/XxJlsGlk/mm6eZTb4OAaQEhkTI2qaFfZFtAsrA/XuCpuMWkS4y/guyBlsRu4hAuhK2HPmNM8+OLLK1zM9Q==", 627 | "dev": true 628 | }, 629 | "@frida/stream": { 630 | "version": "1.0.2", 631 | "resolved": "https://registry.npmjs.org/@frida/stream/-/stream-1.0.2.tgz", 632 | "integrity": "sha512-4OuaC1ztmEKgTq3WeBhsy8Oq+AwW9n9cYnvLklcC9jwD93AEwgbWpecLlxJCVuALvTMdhKPg0nQVfyGYP/i9Bw==", 633 | "dev": true, 634 | "requires": { 635 | "@frida/readable-stream": "^4.1.3" 636 | } 637 | }, 638 | "@frida/string_decoder": { 639 | "version": "2.0.0", 640 | "resolved": "https://registry.npmjs.org/@frida/string_decoder/-/string_decoder-2.0.0.tgz", 641 | "integrity": "sha512-in371tYZMHQiW9HF5MS3JDw6Ao6tyBoq34UWy2rzOswYyMG1rpizh85ofi/yVkxDiaqybEZefxzkVittpPGT6g==", 642 | "dev": true 643 | }, 644 | "@frida/terser": { 645 | "version": "1.0.0", 646 | "resolved": "https://registry.npmjs.org/@frida/terser/-/terser-1.0.0.tgz", 647 | "integrity": "sha512-59h9WuNzD1Rx/zwoWqQ/FW/4Y/Q3R91Eng2hEwdHapqiTDvtKbZ08F6CynCR7ZVinrh4tLYsF46AtVPTz1ys9g==", 648 | "dev": true, 649 | "requires": { 650 | "@jridgewell/source-map": "^0.3.2", 651 | "acorn": "^8.5.0", 652 | "commander": "^2.20.0", 653 | "source-map-support": "~0.5.20" 654 | }, 655 | "dependencies": { 656 | "commander": { 657 | "version": "2.20.3", 658 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", 659 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", 660 | "dev": true 661 | } 662 | } 663 | }, 664 | "@frida/timers": { 665 | "version": "3.0.0", 666 | "resolved": "https://registry.npmjs.org/@frida/timers/-/timers-3.0.0.tgz", 667 | "integrity": "sha512-3b+0igv10aT8TMxefrTAd06rActqbxJLY2Xkkq9vYcPBffB/yHszl0NYIp/5ko8WC3ecDYPU6bQiY6fjs72zTA==", 668 | "dev": true 669 | }, 670 | "@frida/tty": { 671 | "version": "1.0.0", 672 | "resolved": "https://registry.npmjs.org/@frida/tty/-/tty-1.0.0.tgz", 673 | "integrity": "sha512-p/kjLnKYxEAB1MdYP8+5rKv9CsHzyA+0jg9BcGETzjQVKHHcroHDULRxDYUh+DC7qs6cpX8QdDQh9E+a6ydgsQ==", 674 | "dev": true 675 | }, 676 | "@frida/url": { 677 | "version": "1.0.2", 678 | "resolved": "https://registry.npmjs.org/@frida/url/-/url-1.0.2.tgz", 679 | "integrity": "sha512-ZKunbKJHMr8w2Eb/5K1avy0MzK1B998S17wYXNv3RmzBGxMm8S5T0F3qEpRxkU7/72P8m4izyQU87fWl+FjQsQ==", 680 | "dev": true, 681 | "requires": { 682 | "@frida/punycode": "^3.0.0", 683 | "@frida/querystring": "^1.0.0" 684 | } 685 | }, 686 | "@frida/util": { 687 | "version": "1.0.3", 688 | "resolved": "https://registry.npmjs.org/@frida/util/-/util-1.0.3.tgz", 689 | "integrity": "sha512-htcG3uDiRXv89ERVNNYhfase39kJ2X75ZARfrYcYEtJLFEsSk0nemM1YnEIR4CjrHvdvkWHrwgKkS+acOyoNEg==", 690 | "dev": true 691 | }, 692 | "@frida/vm": { 693 | "version": "2.0.0", 694 | "resolved": "https://registry.npmjs.org/@frida/vm/-/vm-2.0.0.tgz", 695 | "integrity": "sha512-7fsjLWscZT5odNIBtg6qbLNI+vAk1xmii6H5W2kaYkMYt0vRohQEcDSUWacA+eaWlu5SvMjZI82Yibj/3G9pJw==", 696 | "dev": true 697 | }, 698 | "@jridgewell/gen-mapping": { 699 | "version": "0.3.3", 700 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", 701 | "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", 702 | "dev": true, 703 | "requires": { 704 | "@jridgewell/set-array": "^1.0.1", 705 | "@jridgewell/sourcemap-codec": "^1.4.10", 706 | "@jridgewell/trace-mapping": "^0.3.9" 707 | } 708 | }, 709 | "@jridgewell/resolve-uri": { 710 | "version": "3.1.0", 711 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", 712 | "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", 713 | "dev": true 714 | }, 715 | "@jridgewell/set-array": { 716 | "version": "1.1.2", 717 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", 718 | "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", 719 | "dev": true 720 | }, 721 | "@jridgewell/source-map": { 722 | "version": "0.3.5", 723 | "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", 724 | "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", 725 | "dev": true, 726 | "requires": { 727 | "@jridgewell/gen-mapping": "^0.3.0", 728 | "@jridgewell/trace-mapping": "^0.3.9" 729 | } 730 | }, 731 | "@jridgewell/sourcemap-codec": { 732 | "version": "1.4.15", 733 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", 734 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", 735 | "dev": true 736 | }, 737 | "@jridgewell/trace-mapping": { 738 | "version": "0.3.18", 739 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", 740 | "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", 741 | "dev": true, 742 | "requires": { 743 | "@jridgewell/resolve-uri": "3.1.0", 744 | "@jridgewell/sourcemap-codec": "1.4.14" 745 | }, 746 | "dependencies": { 747 | "@jridgewell/sourcemap-codec": { 748 | "version": "1.4.14", 749 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", 750 | "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", 751 | "dev": true 752 | } 753 | } 754 | }, 755 | "@types/frida-gum": { 756 | "version": "18.4.1", 757 | "resolved": "https://registry.npmjs.org/@types/frida-gum/-/frida-gum-18.4.1.tgz", 758 | "integrity": "sha512-81WHL19NhJoNaDapWJ9WV2XQLAsN17CXKs5aVbvwGaz8vXoT0rzUHQbOBcbH0CuJxA33KOmD8AWnf7USxo9ZXw==", 759 | "dev": true 760 | }, 761 | "@types/node": { 762 | "version": "17.0.45", 763 | "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", 764 | "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", 765 | "dev": true 766 | }, 767 | "acorn": { 768 | "version": "8.10.0", 769 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", 770 | "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", 771 | "dev": true 772 | }, 773 | "base64-js": { 774 | "version": "1.5.1", 775 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 776 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", 777 | "dev": true 778 | }, 779 | "buffer-from": { 780 | "version": "1.1.2", 781 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", 782 | "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", 783 | "dev": true 784 | }, 785 | "commander": { 786 | "version": "9.5.0", 787 | "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", 788 | "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", 789 | "dev": true 790 | }, 791 | "frida-compile": { 792 | "version": "16.3.0", 793 | "resolved": "https://registry.npmjs.org/frida-compile/-/frida-compile-16.3.0.tgz", 794 | "integrity": "sha512-WpnvUzQtWnc8xPnFmmYCajJKzyKQLM/QEOvasgFYTjaXNfDJHjrHIDxgx/ZXSNidmxK3FZofs+LsuGMq9wEqqA==", 795 | "dev": true, 796 | "requires": { 797 | "@frida/assert": "^3.0.1", 798 | "@frida/base64-js": "^2.0.3", 799 | "@frida/buffer": "^7.0.4", 800 | "@frida/crosspath": "^3.0.0", 801 | "@frida/diagnostics_channel": "^1.0.0", 802 | "@frida/events": "^4.0.4", 803 | "@frida/http": "^4.0.2", 804 | "@frida/http-parser-js": "^1.0.0", 805 | "@frida/https": "^1.0.0", 806 | "@frida/ieee754": "^2.0.2", 807 | "@frida/net": "^4.0.1", 808 | "@frida/os": "^1.0.0", 809 | "@frida/path": "^2.0.3", 810 | "@frida/process": "^1.2.1", 811 | "@frida/punycode": "^3.0.0", 812 | "@frida/querystring": "^1.0.0", 813 | "@frida/readable-stream": "^4.1.3", 814 | "@frida/reserved-words": "^1.0.0", 815 | "@frida/stream": "^1.0.2", 816 | "@frida/string_decoder": "^2.0.0", 817 | "@frida/terser": "^1.0.0", 818 | "@frida/timers": "^3.0.0", 819 | "@frida/tty": "^1.0.0", 820 | "@frida/url": "^1.0.2", 821 | "@frida/util": "^1.0.3", 822 | "@frida/vm": "^2.0.0", 823 | "commander": "^9.4.0", 824 | "frida-fs": "^5.2.3", 825 | "typed-emitter": "^2.1.0" 826 | } 827 | }, 828 | "frida-fs": { 829 | "version": "5.2.5", 830 | "resolved": "https://registry.npmjs.org/frida-fs/-/frida-fs-5.2.5.tgz", 831 | "integrity": "sha512-Eyb4OqUlcv1/Eq7Q+B9IZmYZIgIM2YjqDojrjmAGzPSSXBuUKwSkuObQcQ8Dup9JTOMIUcSII9/I8DaTe6LFKw==", 832 | "dev": true 833 | }, 834 | "http-parser-js": { 835 | "version": "0.5.8", 836 | "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", 837 | "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", 838 | "dev": true 839 | }, 840 | "ieee754": { 841 | "version": "1.2.1", 842 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", 843 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", 844 | "dev": true 845 | }, 846 | "rxjs": { 847 | "version": "7.8.1", 848 | "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", 849 | "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", 850 | "dev": true, 851 | "optional": true, 852 | "requires": { 853 | "tslib": "^2.1.0" 854 | } 855 | }, 856 | "source-map": { 857 | "version": "0.6.1", 858 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 859 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 860 | "dev": true 861 | }, 862 | "source-map-support": { 863 | "version": "0.5.21", 864 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", 865 | "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", 866 | "dev": true, 867 | "requires": { 868 | "buffer-from": "^1.0.0", 869 | "source-map": "^0.6.0" 870 | } 871 | }, 872 | "tslib": { 873 | "version": "2.6.1", 874 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", 875 | "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==", 876 | "dev": true, 877 | "optional": true 878 | }, 879 | "typed-emitter": { 880 | "version": "2.1.0", 881 | "resolved": "https://registry.npmjs.org/typed-emitter/-/typed-emitter-2.1.0.tgz", 882 | "integrity": "sha512-g/KzbYKbH5C2vPkaXGu8DJlHrGKHLsM25Zg9WuC9pMGfuvT+X25tZQWo5fK1BjBm8+UrVE9LDCvaY0CQk+fXDA==", 883 | "dev": true, 884 | "requires": { 885 | "rxjs": "*" 886 | } 887 | }, 888 | "typescript": { 889 | "version": "5.1.6", 890 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", 891 | "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", 892 | "dev": true 893 | } 894 | } 895 | } 896 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frida-unity-esp-manager", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "spawn": "frida -U -f com.aldagames.zombieshooter -l dist/agent.js --auto-reload --kill-on-exit", 8 | "watch": "frida-compile src/index.ts -o dist/agent.js -w", 9 | "build": "frida-compile src/index.ts -o dist/agent.js -c" 10 | }, 11 | "prettier": { 12 | "printWidth": 120, 13 | "tabWidth": 2, 14 | "useTabs": false, 15 | "semi": true, 16 | "singleQuote": true, 17 | "trailingComma": "all", 18 | "bracketSpacing": true, 19 | "arrowParens": "always", 20 | "endOfLine": "lf" 21 | }, 22 | "keywords": [], 23 | "author": "", 24 | "license": "ISC", 25 | "devDependencies": { 26 | "@types/frida-gum": "^18.4.1", 27 | "frida-compile": "^16.3.0", 28 | "typescript": "^5.1.6" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/ESPManager.ts: -------------------------------------------------------------------------------- 1 | export default class ESPManager { 2 | public static readonly MIN_AUTO_CLEAN_INTERVAL = 500; 3 | public static readonly DEFAULT_AUTO_CLEAN_INTERVAL = 1000; 4 | private _enemies: NativePointer[] = []; 5 | private autoCleanInterval: number; 6 | private autoCleanIntervalId: NodeJS.Timer | undefined; 7 | 8 | public constructor(isAutoClean = true, autoCleanInterval = ESPManager.DEFAULT_AUTO_CLEAN_INTERVAL) { 9 | this.autoCleanInterval = autoCleanInterval; 10 | if (isAutoClean) this.startAutoClean(); 11 | } 12 | 13 | private set enemies(value: NativePointer[]) { 14 | this._enemies = value; 15 | } 16 | 17 | public get enemies() { 18 | return this._enemies; 19 | } 20 | 21 | public getAutoCleanInterval() { 22 | return this.autoCleanInterval; 23 | } 24 | 25 | public setAutoCleanInterval(intval: number): void { 26 | this.autoCleanInterval = Math.max(intval, ESPManager.MIN_AUTO_CLEAN_INTERVAL); 27 | } 28 | 29 | public isAutoCleanEnabled(): boolean { 30 | return this.autoCleanIntervalId !== undefined; 31 | } 32 | 33 | public startAutoClean(): void { 34 | if (this.isAutoCleanEnabled()) return; 35 | this.autoCleanIntervalId = setInterval(() => this.cleanEnemies(), this.autoCleanInterval); 36 | } 37 | 38 | public stopAutoClean(): void { 39 | if (!this.isAutoCleanEnabled()) return; 40 | clearInterval(this.autoCleanIntervalId); 41 | this.autoCleanIntervalId = undefined; 42 | } 43 | 44 | public isEnemyPresent(enemy: NativePointer): boolean { 45 | return this.enemies.find((e) => e.equals(enemy)) !== undefined; 46 | } 47 | 48 | public tryAddEnemy(enemy: NativePointer): boolean { 49 | if (enemy.isNull() || this.isEnemyPresent(enemy)) return false; 50 | this.enemies.push(enemy); 51 | return true; 52 | } 53 | 54 | public tryRemoveEnemy(enemy: NativePointer): void { 55 | this.enemies = this.enemies.filter((e) => !e.equals(enemy)); 56 | } 57 | 58 | public getEnemiesCount(): number { 59 | return this.enemies.length; 60 | } 61 | 62 | public cleanEnemies(): void { 63 | this.enemies = this.enemies.filter((e) => !e.isNull()); 64 | } 65 | 66 | public reset(): void { 67 | this.enemies = []; 68 | } 69 | 70 | public at(index: number): NativePointer | undefined { 71 | return this.enemies[index]; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/ESPView.ts: -------------------------------------------------------------------------------- 1 | Java.perform(() => { 2 | const View = Java.use('android.view.View'); 3 | const Color = Java.use('android.graphics.Color'); 4 | const PorterDuff$Mode = Java.use('android.graphics.PorterDuff$Mode'); 5 | 6 | Java.registerClass({ 7 | name: 'com.maars.ESPView', 8 | superClass: View, 9 | methods: { 10 | $init: [ 11 | { 12 | returnType: 'void', 13 | argumentTypes: ['android.content.Context'], 14 | implementation(context: Java.Wrapper) { 15 | this.$super.$init(context); 16 | this.setFocusable(false); 17 | this.setLayerType(View.LAYER_TYPE_SOFTWARE.value, null); 18 | this.setBackgroundColor(Color.TRANSPARENT.value); 19 | }, 20 | }, 21 | ], 22 | clearCanvas: [ 23 | { 24 | returnType: 'void', 25 | argumentTypes: ['android.graphics.Canvas'], 26 | implementation(canvas: Java.Wrapper) { 27 | canvas.drawColor(Color.TRANSPARENT.value, PorterDuff$Mode.CLEAR.value); 28 | }, 29 | }, 30 | ], 31 | }, 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /src/ESPaint.ts: -------------------------------------------------------------------------------- 1 | type JW = Java.Wrapper; 2 | 3 | abstract class ESPaint { 4 | public static TextPaint: JW; 5 | public static StrokePaint: JW; 6 | public static FilledPaint: JW; 7 | public static textSize = 20; 8 | 9 | public static init() { 10 | Java.perform(() => { 11 | const Paint = Java.use('android.graphics.Paint'); 12 | const Color = Java.use('android.graphics.Color'); 13 | const Paint$Style = Java.use('android.graphics.Paint$Style'); 14 | const Paint$Align = Java.use('android.graphics.Paint$Align'); 15 | 16 | ESPaint.TextPaint = Paint.$new(); 17 | ESPaint.TextPaint.setStyle(Paint$Style.FILL_AND_STROKE.value); 18 | ESPaint.TextPaint.setAntiAlias(true); 19 | ESPaint.TextPaint.setColor(Color.rgb(255, 0, 255)); 20 | ESPaint.TextPaint.setTextAlign(Paint$Align.CENTER.value); 21 | ESPaint.TextPaint.setStrokeWidth(1.1); 22 | ESPaint.TextPaint.setTextSize(ESPaint.textSize); 23 | 24 | ESPaint.StrokePaint = Paint.$new(); 25 | ESPaint.StrokePaint.setStrokeWidth(3); 26 | ESPaint.StrokePaint.setStyle(Paint$Style.STROKE.value); 27 | ESPaint.StrokePaint.setAntiAlias(true); 28 | ESPaint.StrokePaint.setColor(Color.rgb(255, 255, 255)); 29 | 30 | ESPaint.FilledPaint = Paint.$new(); 31 | ESPaint.FilledPaint.setStyle(Paint$Style.FILL.value); 32 | ESPaint.FilledPaint.setAntiAlias(true); 33 | ESPaint.StrokePaint.setStrokeWidth(3); 34 | ESPaint.FilledPaint.setColor(Color.rgb(255, 0, 255)); 35 | }); 36 | } 37 | } 38 | 39 | ESPaint.init(); 40 | 41 | export default ESPaint; 42 | -------------------------------------------------------------------------------- /src/Logger.ts: -------------------------------------------------------------------------------- 1 | export class Logger { 2 | private loggin = false; 3 | private showTimer = false; 4 | 5 | constructor(loggin = false) { 6 | this.loggin = loggin; 7 | } 8 | 9 | private getTime(): string { 10 | const date = new Date(); 11 | const time = [date.getHours(), date.getMinutes(), date.getSeconds()] 12 | .map((v) => v.toString().padStart(2, '0')) 13 | .join(':'); 14 | 15 | return time; 16 | } 17 | 18 | get isLoggin(): boolean { 19 | return this.loggin; 20 | } 21 | 22 | get isShowTime(): boolean { 23 | return this.showTimer; 24 | } 25 | 26 | private display(...args: any[]): void { 27 | if (!this.loggin) return; 28 | const time = this.showTimer ? `\x1b[36m[${this.getTime()}]\x1b[0m` : ''; 29 | time ? console.log(`${time}`, ...args) : console.log(...args); 30 | } 31 | 32 | public setLoggin(loggin: boolean): this { 33 | this.loggin = loggin; 34 | return this; 35 | } 36 | 37 | public setShowTime(show: boolean): this { 38 | this.showTimer = show; 39 | return this; 40 | } 41 | 42 | public log(...args: any[]): this { 43 | this.display(...args); 44 | return this; 45 | } 46 | } 47 | 48 | const logger = new Logger(true).setShowTime(true); 49 | const log = logger.log.bind(logger); 50 | 51 | export { log }; 52 | -------------------------------------------------------------------------------- /src/Offset.ts: -------------------------------------------------------------------------------- 1 | export default abstract class OFS { 2 | public static readonly CEnemyBase = { 3 | Update: 0x117f0c4, 4 | get_MaxHealth: 0x11806a4, 5 | get_HealthPercentage: 0x11806ac, 6 | }; 7 | 8 | public static readonly Vector3 = { 9 | ctor: 0x22ed584, 10 | }; 11 | 12 | public static readonly Component = { 13 | get_transform: 0x164b0bc, 14 | }; 15 | 16 | public static readonly Camera = { 17 | get_main: 0x1647024, 18 | WorldToScreenPoint_Injected: 0x16469e4, 19 | }; 20 | 21 | public static readonly Transform = { 22 | get_position_Injected: 0x22e7cb0, 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import './ESPView.js'; 2 | import ESPaint from './ESPaint.js'; 3 | import ESPManager from './ESPManager.js'; 4 | import OFS from './Offset.js'; 5 | import { getActivity, getScreenResolution, ensureModulesInitialized, sleep } from './utils.js'; 6 | import { log } from './Logger.js'; 7 | 8 | const modulesList = ['libil2cpp.so', 'libunity.so', 'libmain.so']; 9 | 10 | const APP_MAIN_ACTIVITY = 'com.unity3d.player.UnityPlayerActivity'; 11 | const MILLISECONDS_IN_ONE_SECOND = 1000; 12 | const ESP_FPS = 30; 13 | const ESP_REFRESH_RATE = MILLISECONDS_IN_ONE_SECOND / ESP_FPS; 14 | 15 | let il2cpp = null as unknown as NativePointer; 16 | const espManager = new ESPManager(); 17 | 18 | Java.perform(async () => { 19 | await sleep(2000); 20 | await ensureModulesInitialized(...modulesList); 21 | il2cpp = Module.findBaseAddress('libil2cpp.so') as NativePointer; 22 | main().catch((e) => console.error(e)); 23 | }); 24 | 25 | async function main() { 26 | let espBox = true; 27 | let isEspLine = true; 28 | // let espHealth = false; 29 | // let espName = false; 30 | let espPlayerCount = true; 31 | let isEspEnabled = true; 32 | 33 | const ESPView = Java.use('com.maars.ESPView'); 34 | 35 | const MainActivity = await getActivity(APP_MAIN_ACTIVITY); 36 | if (!MainActivity) throw new Error('MainActivity not found!'); 37 | 38 | // const [SCREEN_WIDTH, SCREEN_HEIGHT] = getScreenResolution(); 39 | 40 | const espView = ESPView.$new(MainActivity); 41 | const rootView = Java.cast(MainActivity.getWindow().getDecorView().getRootView(), Java.use('android.view.ViewGroup')); 42 | 43 | Java.scheduleOnMainThread(() => { 44 | rootView.addView(espView); 45 | espView.postInvalidate(); 46 | }); 47 | 48 | setInterval(() => espView.postInvalidate(), ESP_REFRESH_RATE); 49 | 50 | /* 51 | * Hooks 52 | */ 53 | Interceptor.attach(il2cpp.add(OFS.CEnemyBase.Update), { 54 | onEnter(args) { 55 | espManager.tryAddEnemy(args[0]); 56 | }, 57 | }); 58 | 59 | const position = Vector3(); 60 | const screenPoint = Vector3(); 61 | 62 | espView.onDraw.implementation = function (canvas: Java.Wrapper) { 63 | // espView.clearCanvas(canvas); 64 | canvas.drawText('moded with frida', 80, 20, ESPaint.TextPaint); 65 | 66 | if (!isEspEnabled) return this.onDraw(canvas); 67 | 68 | for (let i = 1; i < espManager.getEnemiesCount(); i++) { 69 | const enemy = espManager.enemies[i]; 70 | 71 | if (enemy.isNull() || IsPlayerDead(enemy)) { 72 | espManager.tryRemoveEnemy(enemy); 73 | continue; 74 | } 75 | 76 | get_position_Injected(get_transform(enemy), position); 77 | WorldToScreenPoint_Injected(get_camera(), position, 2, screenPoint); 78 | 79 | const pos = { 80 | x: screenPoint.add(0x0).readFloat(), 81 | y: screenPoint.add(0x4).readFloat(), 82 | z: screenPoint.add(0x8).readFloat(), 83 | }; 84 | 85 | if (pos.z < 1.0) continue; 86 | 87 | const canvasWidth = canvas.getWidth(); 88 | const canvasHeight = canvas.getHeight(); 89 | 90 | if (espPlayerCount) { 91 | const point = { x: canvasWidth / 2, y: 20 }; 92 | canvas.drawText(espManager.getEnemiesCount().toString(), point.x, point.y, ESPaint.TextPaint); 93 | } 94 | 95 | if (espBox) { 96 | const boxWidth = 100; 97 | const boxHeight = 200; 98 | const boxFrom = { 99 | x: canvasWidth - (canvasWidth - pos.x) - boxWidth / 2, 100 | y: canvasHeight - pos.y - boxHeight, 101 | }; 102 | const boxTo = { x: boxFrom.x + boxWidth, y: boxFrom.y + boxHeight }; 103 | canvas.drawRect(boxFrom.x, boxFrom.y, boxTo.x, boxTo.y, ESPaint.StrokePaint); 104 | } 105 | 106 | if (isEspLine) { 107 | const drawFrom = { x: canvasWidth / 2, y: 40 }; 108 | const drawTo = { 109 | x: canvasWidth - (canvasWidth - pos.x) + 5, 110 | y: canvasHeight - pos.y - 50.0, 111 | }; 112 | canvas.drawLine(drawFrom.x, drawFrom.y, drawTo.x, drawTo.y, ESPaint.StrokePaint); 113 | canvas.drawCircle(drawFrom.x, drawFrom.y, 5, ESPaint.FilledPaint); 114 | canvas.drawCircle(drawTo.x, drawTo.y, 5, ESPaint.FilledPaint); 115 | } 116 | } 117 | 118 | // this.onDraw(canvas); 119 | }; 120 | } 121 | 122 | function Vector3(x = 0, y = 0, z = 0) { 123 | const vector = Memory.alloc(0xc); 124 | new NativeFunction(il2cpp.add(OFS.Vector3.ctor), 'pointer', ['pointer', 'float', 'float', 'float'])(vector, x, y, z); 125 | return vector; 126 | } 127 | 128 | function WorldToScreenPoint_Injected(camera: NativePointer, position: NativePointer, eye: number, out: NativePointer) { 129 | new NativeFunction(il2cpp.add(OFS.Camera.WorldToScreenPoint_Injected), 'pointer', [ 130 | 'pointer', 131 | 'pointer', 132 | 'int', 133 | 'pointer', 134 | ])(camera, position, eye, out); 135 | } 136 | 137 | function get_position_Injected(transform: NativePointer, out: NativePointer) { 138 | new NativeFunction(il2cpp.add(OFS.Transform.get_position_Injected), 'pointer', ['pointer', 'pointer'])( 139 | transform, 140 | out, 141 | ); 142 | } 143 | 144 | function get_transform(player: NativePointer) { 145 | return new NativeFunction(il2cpp.add(OFS.Component.get_transform), 'pointer', ['pointer'])(player); 146 | } 147 | 148 | function get_camera() { 149 | return new NativeFunction(il2cpp.add(OFS.Camera.get_main), 'pointer', [])(); 150 | } 151 | 152 | function GetHealth(player: NativePointer) { 153 | return new NativeFunction(il2cpp.add(OFS.CEnemyBase.get_HealthPercentage), 'float', ['pointer'])(player); 154 | } 155 | 156 | function IsPlayerDead(player: NativePointer): boolean { 157 | return GetHealth(player) <= 0; 158 | } 159 | -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | import { log } from './Logger.js'; 2 | 3 | export function sleep(ms: number): Promise { 4 | return new Promise((resolve) => setTimeout(resolve, ms)); 5 | } 6 | 7 | export function getScreenResolution(): [number, number] { 8 | const context = Java.use('android.app.ActivityThread').currentApplication().getApplicationContext(); 9 | const display = context.getResources().getDisplayMetrics(); 10 | 11 | return [display.widthPixels.value, display.heightPixels.value]; 12 | } 13 | 14 | export async function getActivity(activityName: string) { 15 | let activity: Java.Wrapper | undefined; 16 | 17 | Java.choose(activityName, { 18 | onMatch(instance) { 19 | activity = instance; 20 | }, 21 | onComplete() {}, 22 | }); 23 | 24 | return activity; 25 | } 26 | 27 | export async function ensureModulesInitialized(...modules: string[]) { 28 | while (modules.length > 0) { 29 | const md = modules.pop(); 30 | if (!md) return; 31 | 32 | if (!Module.findBaseAddress(md)) { 33 | log(`Waiting for ${md} to be initialized...`); 34 | await sleep(100); 35 | modules.push(md); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "ESNext" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, 15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ 18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ 22 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ 26 | 27 | /* Modules */ 28 | "module": "ESNext" /* Specify what module code is generated. */, 29 | "rootDir": "./src" /* Specify the root folder within your source files. */, 30 | // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ 31 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 32 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 33 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 34 | "typeRoots": [ 35 | "./src/types", 36 | "./node_modules/@types" 37 | ] /* Specify multiple folders that act like './node_modules/@types'. */, 38 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 39 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 40 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ 41 | // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ 42 | // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ 43 | // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ 44 | // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ 45 | // "resolveJsonModule": true, /* Enable importing .json files. */ 46 | // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ 47 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 48 | 49 | /* JavaScript Support */ 50 | "allowJs": false /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */, 51 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 52 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 53 | 54 | /* Emit */ 55 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 56 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 57 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 58 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 59 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 60 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ 61 | "outDir": "./dist" /* Specify an output folder for all emitted files. */, 62 | "removeComments": true /* Disable emitting comments. */, 63 | "noEmit": true /* Disable emitting files from a compilation. */, 64 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 65 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 66 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 67 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 68 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 69 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 70 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 71 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 72 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 73 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 74 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 75 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 76 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 77 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 78 | 79 | /* Interop Constraints */ 80 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 81 | // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ 82 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 83 | "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, 84 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 85 | "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, 86 | 87 | /* Type Checking */ 88 | "strict": true /* Enable all strict type-checking options. */, 89 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 90 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ 91 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 92 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 93 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 94 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ 95 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 96 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 97 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 98 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 99 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 100 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 101 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 102 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 103 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 104 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 105 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 106 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 107 | 108 | /* Completeness */ 109 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 110 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 111 | }, 112 | "include": ["src/**/*"] 113 | } 114 | --------------------------------------------------------------------------------