├── .github ├── FUNDING.yml └── workflows │ ├── build.yaml │ ├── clippy_check.yaml │ ├── documentations.yaml │ ├── rustfmt.yaml │ └── test.yaml ├── .gitignore ├── .idea ├── .gitignore ├── misc.xml ├── modules.xml ├── v8_killer.iml └── vcs.xml ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── crates ├── core │ ├── .gitignore │ ├── Cargo.toml │ └── src │ │ ├── config.rs │ │ ├── core.rs │ │ ├── identifier.rs │ │ ├── lib.rs │ │ ├── matcher.rs │ │ ├── pid_span.rs │ │ ├── processor.rs │ │ ├── source.rs │ │ └── v8_sys.rs └── launcher │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ ├── lib.rs │ └── main.rs ├── docs ├── .gitignore ├── Pipfile ├── Pipfile.lock ├── docs │ ├── development.en.md │ ├── development.zh.md │ ├── getting-started.en.md │ ├── getting-started.zh.md │ ├── index.en.md │ └── index.zh.md └── mkdocs.yml └── examples └── configs ├── custom-identifiers.toml └── simple.toml /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | ko_fi: shellwen 2 | -------------------------------------------------------------------------------- /.github/workflows/build.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | paths-ignore: 4 | - 'docs/**' 5 | pull_request: 6 | paths-ignore: 7 | - 'docs/**' 8 | 9 | name: CI 10 | 11 | jobs: 12 | build: 13 | name: build 14 | runs-on: ${{ matrix.os }} 15 | strategy: 16 | matrix: 17 | os: [ ubuntu-latest, windows-latest, macos-latest ] 18 | steps: 19 | - uses: actions/checkout@v4 20 | - uses: dtolnay/rust-toolchain@stable 21 | - uses: Swatinem/rust-cache@v2 22 | - name: Build for Windows/Linux 23 | if: matrix.os == 'ubuntu-latest' || matrix.os == 'windows-latest' 24 | run: cargo build --verbose --release 25 | - name: Build for macOS 26 | if: matrix.os == 'macos-latest' 27 | run: | 28 | rustup target add aarch64-apple-darwin x86_64-apple-darwin 29 | cargo build --verbose --release --target aarch64-apple-darwin 30 | cargo build --verbose --release --target x86_64-apple-darwin 31 | lipo -create -output target/libv8_killer_core.dylib \ 32 | target/aarch64-apple-darwin/release/libv8_killer_core.dylib \ 33 | target/x86_64-apple-darwin/release/libv8_killer_core.dylib 34 | lipo -create -output target/v8_killer_launcher \ 35 | target/aarch64-apple-darwin/release/v8_killer_launcher \ 36 | target/x86_64-apple-darwin/release/v8_killer_launcher 37 | - name: Upload artifact 38 | uses: actions/upload-artifact@v4 39 | with: 40 | name: ${{ matrix.os }}-release 41 | path: | 42 | target/release/v8_killer_core.dll 43 | target/release/v8_killer_launcher.exe 44 | target/release/libv8_killer_core.so 45 | target/release/libv8_killer_launcher.so 46 | target/release/v8_killer_launcher 47 | target/libv8_killer_core.dylib 48 | target/v8_killer_launcher 49 | -------------------------------------------------------------------------------- /.github/workflows/clippy_check.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | paths-ignore: 4 | - 'docs/**' 5 | pull_request: 6 | paths-ignore: 7 | - 'docs/**' 8 | 9 | name: Clippy check 10 | 11 | env: 12 | RUSTFLAGS: "-Dwarnings" 13 | 14 | jobs: 15 | clippy_check: 16 | runs-on: ${{ matrix.os }} 17 | strategy: 18 | matrix: 19 | os: [ ubuntu-latest, windows-latest ] 20 | steps: 21 | - uses: actions/checkout@v4 22 | - uses: dtolnay/rust-toolchain@stable 23 | with: 24 | components: clippy 25 | - uses: Swatinem/rust-cache@v2 26 | - name: Run Clippy 27 | run: cargo clippy --all-targets --all-features -------------------------------------------------------------------------------- /.github/workflows/documentations.yaml: -------------------------------------------------------------------------------- 1 | name: Deploy docs to Pages 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | paths: 7 | - docs/** 8 | workflow_dispatch: 9 | 10 | permissions: 11 | contents: read 12 | pages: write 13 | id-token: write 14 | 15 | concurrency: 16 | group: "pages" 17 | cancel-in-progress: false 18 | 19 | jobs: 20 | deploy: 21 | environment: 22 | name: github-pages 23 | url: ${{ steps.deployment.outputs.page_url }} 24 | runs-on: ubuntu-latest 25 | steps: 26 | - name: Checkout 27 | uses: actions/checkout@v4 28 | - name: Setup Pages 29 | uses: actions/configure-pages@v3 30 | - uses: actions/setup-python@v4 31 | with: 32 | python-version: 3.13 33 | cache: 'pipenv' 34 | cache-dependency-path: 'docs/Pipfile.lock' 35 | - name: Install pipenv 36 | # run: pip install pipenv 37 | run: curl https://raw.githubusercontent.com/pypa/pipenv/master/get-pipenv.py | python 38 | working-directory: './docs' 39 | - name: Run pipenv install --dev 40 | run: pipenv install --dev 41 | working-directory: './docs' 42 | - name: Build docs 43 | run: pipenv run mkdocs build 44 | working-directory: './docs' 45 | - name: Upload artifact 46 | uses: actions/upload-pages-artifact@v2 47 | with: 48 | path: './docs/site' 49 | - name: Deploy to GitHub Pages 50 | id: deployment 51 | uses: actions/deploy-pages@v2 52 | -------------------------------------------------------------------------------- /.github/workflows/rustfmt.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | paths-ignore: 4 | - 'docs/**' 5 | pull_request: 6 | paths-ignore: 7 | - 'docs/**' 8 | 9 | name: Rustfmt 10 | 11 | jobs: 12 | rustfmt: 13 | name: rustfmt 14 | runs-on: ${{ matrix.os }} 15 | strategy: 16 | matrix: 17 | os: [ ubuntu-latest, windows-latest ] 18 | steps: 19 | - uses: actions/checkout@v4 20 | - uses: dtolnay/rust-toolchain@stable 21 | with: 22 | components: rustfmt 23 | - uses: Swatinem/rust-cache@v2 24 | - run: cargo fmt --all -- --check 25 | -------------------------------------------------------------------------------- /.github/workflows/test.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | paths-ignore: 4 | - 'docs/**' 5 | pull_request: 6 | paths-ignore: 7 | - 'docs/**' 8 | 9 | name: Test 10 | 11 | jobs: 12 | test: 13 | runs-on: ${{ matrix.os }} 14 | strategy: 15 | matrix: 16 | os: [ ubuntu-latest, windows-latest, macos-latest ] 17 | steps: 18 | - uses: actions/checkout@v4 19 | - uses: dtolnay/rust-toolchain@stable 20 | - uses: Swatinem/rust-cache@v2 21 | - name: Run non-macOS tests 22 | if: matrix.os != 'macos-latest' 23 | run: cargo test --verbose 24 | 25 | - name: Run macOS tests 26 | if: matrix.os == 'macos-latest' 27 | run: | 28 | rustup target add aarch64-apple-darwin x86_64-apple-darwin 29 | cargo test --verbose --target aarch64-apple-darwin 30 | cargo test --verbose --target x86_64-apple-darwin -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Rust template 2 | # Generated by Cargo 3 | # will have compiled files and executables 4 | debug/ 5 | target/ 6 | 7 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 8 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 9 | # Cargo.lock 10 | 11 | # These are backup files generated by rustfmt 12 | **/*.rs.bk 13 | 14 | # MSVC Windows builds of rustc generate these, which store debugging information 15 | *.pdb 16 | 17 | # Local Scripts 18 | scripts/local/** 19 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # 默认忽略的文件 2 | /shelf/ 3 | /workspace.xml 4 | # 基于编辑器的 HTTP 客户端请求 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | # GitHub Copilot persisted chat sessions 10 | /copilot/chatSessions 11 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/v8_killer.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.24.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler2" 16 | version = "2.0.0" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 19 | 20 | [[package]] 21 | name = "aho-corasick" 22 | version = "1.1.3" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 25 | dependencies = [ 26 | "memchr", 27 | ] 28 | 29 | [[package]] 30 | name = "anstream" 31 | version = "0.6.18" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" 34 | dependencies = [ 35 | "anstyle", 36 | "anstyle-parse", 37 | "anstyle-query", 38 | "anstyle-wincon", 39 | "colorchoice", 40 | "is_terminal_polyfill", 41 | "utf8parse", 42 | ] 43 | 44 | [[package]] 45 | name = "anstyle" 46 | version = "1.0.10" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" 49 | 50 | [[package]] 51 | name = "anstyle-parse" 52 | version = "0.2.6" 53 | source = "registry+https://github.com/rust-lang/crates.io-index" 54 | checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" 55 | dependencies = [ 56 | "utf8parse", 57 | ] 58 | 59 | [[package]] 60 | name = "anstyle-query" 61 | version = "1.1.2" 62 | source = "registry+https://github.com/rust-lang/crates.io-index" 63 | checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" 64 | dependencies = [ 65 | "windows-sys 0.59.0", 66 | ] 67 | 68 | [[package]] 69 | name = "anstyle-wincon" 70 | version = "3.0.7" 71 | source = "registry+https://github.com/rust-lang/crates.io-index" 72 | checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" 73 | dependencies = [ 74 | "anstyle", 75 | "once_cell", 76 | "windows-sys 0.59.0", 77 | ] 78 | 79 | [[package]] 80 | name = "autocfg" 81 | version = "1.4.0" 82 | source = "registry+https://github.com/rust-lang/crates.io-index" 83 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 84 | 85 | [[package]] 86 | name = "backtrace" 87 | version = "0.3.74" 88 | source = "registry+https://github.com/rust-lang/crates.io-index" 89 | checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" 90 | dependencies = [ 91 | "addr2line", 92 | "cfg-if", 93 | "libc", 94 | "miniz_oxide", 95 | "object", 96 | "rustc-demangle", 97 | "windows-targets 0.52.6", 98 | ] 99 | 100 | [[package]] 101 | name = "base64" 102 | version = "0.22.1" 103 | source = "registry+https://github.com/rust-lang/crates.io-index" 104 | checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" 105 | 106 | [[package]] 107 | name = "bindgen" 108 | version = "0.69.5" 109 | source = "registry+https://github.com/rust-lang/crates.io-index" 110 | checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" 111 | dependencies = [ 112 | "bitflags", 113 | "cexpr", 114 | "clang-sys", 115 | "itertools", 116 | "lazy_static", 117 | "lazycell", 118 | "log", 119 | "prettyplease", 120 | "proc-macro2", 121 | "quote", 122 | "regex", 123 | "rustc-hash 1.1.0", 124 | "shlex", 125 | "syn", 126 | "which", 127 | ] 128 | 129 | [[package]] 130 | name = "bitflags" 131 | version = "2.9.0" 132 | source = "registry+https://github.com/rust-lang/crates.io-index" 133 | checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" 134 | 135 | [[package]] 136 | name = "bumpalo" 137 | version = "3.17.0" 138 | source = "registry+https://github.com/rust-lang/crates.io-index" 139 | checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" 140 | 141 | [[package]] 142 | name = "bytes" 143 | version = "1.10.1" 144 | source = "registry+https://github.com/rust-lang/crates.io-index" 145 | checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" 146 | 147 | [[package]] 148 | name = "cc" 149 | version = "1.2.16" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" 152 | dependencies = [ 153 | "shlex", 154 | ] 155 | 156 | [[package]] 157 | name = "cexpr" 158 | version = "0.6.0" 159 | source = "registry+https://github.com/rust-lang/crates.io-index" 160 | checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" 161 | dependencies = [ 162 | "nom", 163 | ] 164 | 165 | [[package]] 166 | name = "cfg-if" 167 | version = "1.0.0" 168 | source = "registry+https://github.com/rust-lang/crates.io-index" 169 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 170 | 171 | [[package]] 172 | name = "cfg_aliases" 173 | version = "0.2.1" 174 | source = "registry+https://github.com/rust-lang/crates.io-index" 175 | checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" 176 | 177 | [[package]] 178 | name = "clang-sys" 179 | version = "1.8.1" 180 | source = "registry+https://github.com/rust-lang/crates.io-index" 181 | checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" 182 | dependencies = [ 183 | "glob", 184 | "libc", 185 | "libloading", 186 | ] 187 | 188 | [[package]] 189 | name = "clap" 190 | version = "4.5.32" 191 | source = "registry+https://github.com/rust-lang/crates.io-index" 192 | checksum = "6088f3ae8c3608d19260cd7445411865a485688711b78b5be70d78cd96136f83" 193 | dependencies = [ 194 | "clap_builder", 195 | "clap_derive", 196 | ] 197 | 198 | [[package]] 199 | name = "clap_builder" 200 | version = "4.5.32" 201 | source = "registry+https://github.com/rust-lang/crates.io-index" 202 | checksum = "22a7ef7f676155edfb82daa97f99441f3ebf4a58d5e32f295a56259f1b6facc8" 203 | dependencies = [ 204 | "anstream", 205 | "anstyle", 206 | "clap_lex", 207 | "strsim", 208 | ] 209 | 210 | [[package]] 211 | name = "clap_derive" 212 | version = "4.5.32" 213 | source = "registry+https://github.com/rust-lang/crates.io-index" 214 | checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" 215 | dependencies = [ 216 | "heck", 217 | "proc-macro2", 218 | "quote", 219 | "syn", 220 | ] 221 | 222 | [[package]] 223 | name = "clap_lex" 224 | version = "0.7.4" 225 | source = "registry+https://github.com/rust-lang/crates.io-index" 226 | checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" 227 | 228 | [[package]] 229 | name = "colorchoice" 230 | version = "1.0.3" 231 | source = "registry+https://github.com/rust-lang/crates.io-index" 232 | checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" 233 | 234 | [[package]] 235 | name = "cstr_core" 236 | version = "0.2.6" 237 | source = "registry+https://github.com/rust-lang/crates.io-index" 238 | checksum = "dd98742e4fdca832d40cab219dc2e3048de17d873248f83f17df47c1bea70956" 239 | dependencies = [ 240 | "cty", 241 | "memchr", 242 | ] 243 | 244 | [[package]] 245 | name = "ctor" 246 | version = "0.4.1" 247 | source = "registry+https://github.com/rust-lang/crates.io-index" 248 | checksum = "07e9666f4a9a948d4f1dff0c08a4512b0f7c86414b23960104c243c10d79f4c3" 249 | dependencies = [ 250 | "ctor-proc-macro", 251 | "dtor", 252 | ] 253 | 254 | [[package]] 255 | name = "ctor-proc-macro" 256 | version = "0.0.5" 257 | source = "registry+https://github.com/rust-lang/crates.io-index" 258 | checksum = "4f211af61d8efdd104f96e57adf5e426ba1bc3ed7a4ead616e15e5881fd79c4d" 259 | 260 | [[package]] 261 | name = "cty" 262 | version = "0.2.2" 263 | source = "registry+https://github.com/rust-lang/crates.io-index" 264 | checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" 265 | 266 | [[package]] 267 | name = "displaydoc" 268 | version = "0.2.5" 269 | source = "registry+https://github.com/rust-lang/crates.io-index" 270 | checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" 271 | dependencies = [ 272 | "proc-macro2", 273 | "quote", 274 | "syn", 275 | ] 276 | 277 | [[package]] 278 | name = "dtor" 279 | version = "0.0.5" 280 | source = "registry+https://github.com/rust-lang/crates.io-index" 281 | checksum = "222ef136a1c687d4aa0395c175f2c4586e379924c352fd02f7870cf7de783c23" 282 | dependencies = [ 283 | "dtor-proc-macro", 284 | ] 285 | 286 | [[package]] 287 | name = "dtor-proc-macro" 288 | version = "0.0.5" 289 | source = "registry+https://github.com/rust-lang/crates.io-index" 290 | checksum = "7454e41ff9012c00d53cf7f475c5e3afa3b91b7c90568495495e8d9bf47a1055" 291 | 292 | [[package]] 293 | name = "either" 294 | version = "1.15.0" 295 | source = "registry+https://github.com/rust-lang/crates.io-index" 296 | checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" 297 | 298 | [[package]] 299 | name = "equivalent" 300 | version = "1.0.2" 301 | source = "registry+https://github.com/rust-lang/crates.io-index" 302 | checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" 303 | 304 | [[package]] 305 | name = "errno" 306 | version = "0.3.10" 307 | source = "registry+https://github.com/rust-lang/crates.io-index" 308 | checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" 309 | dependencies = [ 310 | "libc", 311 | "windows-sys 0.59.0", 312 | ] 313 | 314 | [[package]] 315 | name = "filetime" 316 | version = "0.2.25" 317 | source = "registry+https://github.com/rust-lang/crates.io-index" 318 | checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" 319 | dependencies = [ 320 | "cfg-if", 321 | "libc", 322 | "libredox", 323 | "windows-sys 0.59.0", 324 | ] 325 | 326 | [[package]] 327 | name = "fnv" 328 | version = "1.0.7" 329 | source = "registry+https://github.com/rust-lang/crates.io-index" 330 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 331 | 332 | [[package]] 333 | name = "form_urlencoded" 334 | version = "1.2.1" 335 | source = "registry+https://github.com/rust-lang/crates.io-index" 336 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 337 | dependencies = [ 338 | "percent-encoding", 339 | ] 340 | 341 | [[package]] 342 | name = "frida-build" 343 | version = "0.16.7" 344 | source = "registry+https://github.com/rust-lang/crates.io-index" 345 | checksum = "bf9a92768e4b897939b4319616211de441498c463f8626e6e7e3a54c5d537813" 346 | dependencies = [ 347 | "reqwest", 348 | "tar", 349 | "xz", 350 | ] 351 | 352 | [[package]] 353 | name = "frida-gum" 354 | version = "0.16.7" 355 | source = "registry+https://github.com/rust-lang/crates.io-index" 356 | checksum = "914fed5b7655d0c8ea1c19a68ee62572d7828abe9f08c709c5439cf208488a8d" 357 | dependencies = [ 358 | "cstr_core", 359 | "frida-gum-sys", 360 | "num", 361 | "num-derive", 362 | "num-traits", 363 | "paste", 364 | "spin", 365 | ] 366 | 367 | [[package]] 368 | name = "frida-gum-sys" 369 | version = "0.16.7" 370 | source = "registry+https://github.com/rust-lang/crates.io-index" 371 | checksum = "c80936aa8563701f0a38cd11c95842037fdc4426d2d2f9351659bb0a0c842e3b" 372 | dependencies = [ 373 | "bindgen", 374 | "cc", 375 | "frida-build", 376 | ] 377 | 378 | [[package]] 379 | name = "futures-channel" 380 | version = "0.3.31" 381 | source = "registry+https://github.com/rust-lang/crates.io-index" 382 | checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" 383 | dependencies = [ 384 | "futures-core", 385 | "futures-sink", 386 | ] 387 | 388 | [[package]] 389 | name = "futures-core" 390 | version = "0.3.31" 391 | source = "registry+https://github.com/rust-lang/crates.io-index" 392 | checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 393 | 394 | [[package]] 395 | name = "futures-io" 396 | version = "0.3.31" 397 | source = "registry+https://github.com/rust-lang/crates.io-index" 398 | checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" 399 | 400 | [[package]] 401 | name = "futures-sink" 402 | version = "0.3.31" 403 | source = "registry+https://github.com/rust-lang/crates.io-index" 404 | checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" 405 | 406 | [[package]] 407 | name = "futures-task" 408 | version = "0.3.31" 409 | source = "registry+https://github.com/rust-lang/crates.io-index" 410 | checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 411 | 412 | [[package]] 413 | name = "futures-util" 414 | version = "0.3.31" 415 | source = "registry+https://github.com/rust-lang/crates.io-index" 416 | checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 417 | dependencies = [ 418 | "futures-core", 419 | "futures-io", 420 | "futures-sink", 421 | "futures-task", 422 | "memchr", 423 | "pin-project-lite", 424 | "pin-utils", 425 | "slab", 426 | ] 427 | 428 | [[package]] 429 | name = "getrandom" 430 | version = "0.2.15" 431 | source = "registry+https://github.com/rust-lang/crates.io-index" 432 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" 433 | dependencies = [ 434 | "cfg-if", 435 | "js-sys", 436 | "libc", 437 | "wasi 0.11.0+wasi-snapshot-preview1", 438 | "wasm-bindgen", 439 | ] 440 | 441 | [[package]] 442 | name = "getrandom" 443 | version = "0.3.2" 444 | source = "registry+https://github.com/rust-lang/crates.io-index" 445 | checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" 446 | dependencies = [ 447 | "cfg-if", 448 | "js-sys", 449 | "libc", 450 | "r-efi", 451 | "wasi 0.14.2+wasi-0.2.4", 452 | "wasm-bindgen", 453 | ] 454 | 455 | [[package]] 456 | name = "gimli" 457 | version = "0.31.1" 458 | source = "registry+https://github.com/rust-lang/crates.io-index" 459 | checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" 460 | 461 | [[package]] 462 | name = "glob" 463 | version = "0.3.2" 464 | source = "registry+https://github.com/rust-lang/crates.io-index" 465 | checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" 466 | 467 | [[package]] 468 | name = "hashbrown" 469 | version = "0.15.2" 470 | source = "registry+https://github.com/rust-lang/crates.io-index" 471 | checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" 472 | 473 | [[package]] 474 | name = "heck" 475 | version = "0.5.0" 476 | source = "registry+https://github.com/rust-lang/crates.io-index" 477 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 478 | 479 | [[package]] 480 | name = "home" 481 | version = "0.5.11" 482 | source = "registry+https://github.com/rust-lang/crates.io-index" 483 | checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" 484 | dependencies = [ 485 | "windows-sys 0.59.0", 486 | ] 487 | 488 | [[package]] 489 | name = "http" 490 | version = "1.3.1" 491 | source = "registry+https://github.com/rust-lang/crates.io-index" 492 | checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" 493 | dependencies = [ 494 | "bytes", 495 | "fnv", 496 | "itoa", 497 | ] 498 | 499 | [[package]] 500 | name = "http-body" 501 | version = "1.0.1" 502 | source = "registry+https://github.com/rust-lang/crates.io-index" 503 | checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" 504 | dependencies = [ 505 | "bytes", 506 | "http", 507 | ] 508 | 509 | [[package]] 510 | name = "http-body-util" 511 | version = "0.1.3" 512 | source = "registry+https://github.com/rust-lang/crates.io-index" 513 | checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" 514 | dependencies = [ 515 | "bytes", 516 | "futures-core", 517 | "http", 518 | "http-body", 519 | "pin-project-lite", 520 | ] 521 | 522 | [[package]] 523 | name = "httparse" 524 | version = "1.10.1" 525 | source = "registry+https://github.com/rust-lang/crates.io-index" 526 | checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" 527 | 528 | [[package]] 529 | name = "hyper" 530 | version = "1.6.0" 531 | source = "registry+https://github.com/rust-lang/crates.io-index" 532 | checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" 533 | dependencies = [ 534 | "bytes", 535 | "futures-channel", 536 | "futures-util", 537 | "http", 538 | "http-body", 539 | "httparse", 540 | "itoa", 541 | "pin-project-lite", 542 | "smallvec", 543 | "tokio", 544 | "want", 545 | ] 546 | 547 | [[package]] 548 | name = "hyper-rustls" 549 | version = "0.27.5" 550 | source = "registry+https://github.com/rust-lang/crates.io-index" 551 | checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" 552 | dependencies = [ 553 | "futures-util", 554 | "http", 555 | "hyper", 556 | "hyper-util", 557 | "rustls", 558 | "rustls-pki-types", 559 | "tokio", 560 | "tokio-rustls", 561 | "tower-service", 562 | "webpki-roots", 563 | ] 564 | 565 | [[package]] 566 | name = "hyper-util" 567 | version = "0.1.10" 568 | source = "registry+https://github.com/rust-lang/crates.io-index" 569 | checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" 570 | dependencies = [ 571 | "bytes", 572 | "futures-channel", 573 | "futures-util", 574 | "http", 575 | "http-body", 576 | "hyper", 577 | "pin-project-lite", 578 | "socket2", 579 | "tokio", 580 | "tower-service", 581 | "tracing", 582 | ] 583 | 584 | [[package]] 585 | name = "icu_collections" 586 | version = "1.5.0" 587 | source = "registry+https://github.com/rust-lang/crates.io-index" 588 | checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" 589 | dependencies = [ 590 | "displaydoc", 591 | "yoke", 592 | "zerofrom", 593 | "zerovec", 594 | ] 595 | 596 | [[package]] 597 | name = "icu_locid" 598 | version = "1.5.0" 599 | source = "registry+https://github.com/rust-lang/crates.io-index" 600 | checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" 601 | dependencies = [ 602 | "displaydoc", 603 | "litemap", 604 | "tinystr", 605 | "writeable", 606 | "zerovec", 607 | ] 608 | 609 | [[package]] 610 | name = "icu_locid_transform" 611 | version = "1.5.0" 612 | source = "registry+https://github.com/rust-lang/crates.io-index" 613 | checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" 614 | dependencies = [ 615 | "displaydoc", 616 | "icu_locid", 617 | "icu_locid_transform_data", 618 | "icu_provider", 619 | "tinystr", 620 | "zerovec", 621 | ] 622 | 623 | [[package]] 624 | name = "icu_locid_transform_data" 625 | version = "1.5.0" 626 | source = "registry+https://github.com/rust-lang/crates.io-index" 627 | checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" 628 | 629 | [[package]] 630 | name = "icu_normalizer" 631 | version = "1.5.0" 632 | source = "registry+https://github.com/rust-lang/crates.io-index" 633 | checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" 634 | dependencies = [ 635 | "displaydoc", 636 | "icu_collections", 637 | "icu_normalizer_data", 638 | "icu_properties", 639 | "icu_provider", 640 | "smallvec", 641 | "utf16_iter", 642 | "utf8_iter", 643 | "write16", 644 | "zerovec", 645 | ] 646 | 647 | [[package]] 648 | name = "icu_normalizer_data" 649 | version = "1.5.0" 650 | source = "registry+https://github.com/rust-lang/crates.io-index" 651 | checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" 652 | 653 | [[package]] 654 | name = "icu_properties" 655 | version = "1.5.1" 656 | source = "registry+https://github.com/rust-lang/crates.io-index" 657 | checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" 658 | dependencies = [ 659 | "displaydoc", 660 | "icu_collections", 661 | "icu_locid_transform", 662 | "icu_properties_data", 663 | "icu_provider", 664 | "tinystr", 665 | "zerovec", 666 | ] 667 | 668 | [[package]] 669 | name = "icu_properties_data" 670 | version = "1.5.0" 671 | source = "registry+https://github.com/rust-lang/crates.io-index" 672 | checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" 673 | 674 | [[package]] 675 | name = "icu_provider" 676 | version = "1.5.0" 677 | source = "registry+https://github.com/rust-lang/crates.io-index" 678 | checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" 679 | dependencies = [ 680 | "displaydoc", 681 | "icu_locid", 682 | "icu_provider_macros", 683 | "stable_deref_trait", 684 | "tinystr", 685 | "writeable", 686 | "yoke", 687 | "zerofrom", 688 | "zerovec", 689 | ] 690 | 691 | [[package]] 692 | name = "icu_provider_macros" 693 | version = "1.5.0" 694 | source = "registry+https://github.com/rust-lang/crates.io-index" 695 | checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" 696 | dependencies = [ 697 | "proc-macro2", 698 | "quote", 699 | "syn", 700 | ] 701 | 702 | [[package]] 703 | name = "idna" 704 | version = "1.0.3" 705 | source = "registry+https://github.com/rust-lang/crates.io-index" 706 | checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" 707 | dependencies = [ 708 | "idna_adapter", 709 | "smallvec", 710 | "utf8_iter", 711 | ] 712 | 713 | [[package]] 714 | name = "idna_adapter" 715 | version = "1.2.0" 716 | source = "registry+https://github.com/rust-lang/crates.io-index" 717 | checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" 718 | dependencies = [ 719 | "icu_normalizer", 720 | "icu_properties", 721 | ] 722 | 723 | [[package]] 724 | name = "indexmap" 725 | version = "2.8.0" 726 | source = "registry+https://github.com/rust-lang/crates.io-index" 727 | checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" 728 | dependencies = [ 729 | "equivalent", 730 | "hashbrown", 731 | ] 732 | 733 | [[package]] 734 | name = "ipnet" 735 | version = "2.11.0" 736 | source = "registry+https://github.com/rust-lang/crates.io-index" 737 | checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" 738 | 739 | [[package]] 740 | name = "is_terminal_polyfill" 741 | version = "1.70.1" 742 | source = "registry+https://github.com/rust-lang/crates.io-index" 743 | checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" 744 | 745 | [[package]] 746 | name = "itertools" 747 | version = "0.12.1" 748 | source = "registry+https://github.com/rust-lang/crates.io-index" 749 | checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" 750 | dependencies = [ 751 | "either", 752 | ] 753 | 754 | [[package]] 755 | name = "itoa" 756 | version = "1.0.15" 757 | source = "registry+https://github.com/rust-lang/crates.io-index" 758 | checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" 759 | 760 | [[package]] 761 | name = "js-sys" 762 | version = "0.3.77" 763 | source = "registry+https://github.com/rust-lang/crates.io-index" 764 | checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" 765 | dependencies = [ 766 | "once_cell", 767 | "wasm-bindgen", 768 | ] 769 | 770 | [[package]] 771 | name = "lazy_static" 772 | version = "1.5.0" 773 | source = "registry+https://github.com/rust-lang/crates.io-index" 774 | checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 775 | 776 | [[package]] 777 | name = "lazycell" 778 | version = "1.3.0" 779 | source = "registry+https://github.com/rust-lang/crates.io-index" 780 | checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" 781 | 782 | [[package]] 783 | name = "libc" 784 | version = "0.2.171" 785 | source = "registry+https://github.com/rust-lang/crates.io-index" 786 | checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" 787 | 788 | [[package]] 789 | name = "libloading" 790 | version = "0.8.6" 791 | source = "registry+https://github.com/rust-lang/crates.io-index" 792 | checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" 793 | dependencies = [ 794 | "cfg-if", 795 | "windows-targets 0.52.6", 796 | ] 797 | 798 | [[package]] 799 | name = "libredox" 800 | version = "0.1.3" 801 | source = "registry+https://github.com/rust-lang/crates.io-index" 802 | checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" 803 | dependencies = [ 804 | "bitflags", 805 | "libc", 806 | "redox_syscall", 807 | ] 808 | 809 | [[package]] 810 | name = "linux-raw-sys" 811 | version = "0.4.15" 812 | source = "registry+https://github.com/rust-lang/crates.io-index" 813 | checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" 814 | 815 | [[package]] 816 | name = "linux-raw-sys" 817 | version = "0.9.3" 818 | source = "registry+https://github.com/rust-lang/crates.io-index" 819 | checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" 820 | 821 | [[package]] 822 | name = "litemap" 823 | version = "0.7.5" 824 | source = "registry+https://github.com/rust-lang/crates.io-index" 825 | checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" 826 | 827 | [[package]] 828 | name = "log" 829 | version = "0.4.26" 830 | source = "registry+https://github.com/rust-lang/crates.io-index" 831 | checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" 832 | 833 | [[package]] 834 | name = "lzma-sys" 835 | version = "0.1.20" 836 | source = "registry+https://github.com/rust-lang/crates.io-index" 837 | checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" 838 | dependencies = [ 839 | "cc", 840 | "libc", 841 | "pkg-config", 842 | ] 843 | 844 | [[package]] 845 | name = "matchers" 846 | version = "0.1.0" 847 | source = "registry+https://github.com/rust-lang/crates.io-index" 848 | checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" 849 | dependencies = [ 850 | "regex-automata 0.1.10", 851 | ] 852 | 853 | [[package]] 854 | name = "memchr" 855 | version = "2.7.4" 856 | source = "registry+https://github.com/rust-lang/crates.io-index" 857 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 858 | 859 | [[package]] 860 | name = "mime" 861 | version = "0.3.17" 862 | source = "registry+https://github.com/rust-lang/crates.io-index" 863 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 864 | 865 | [[package]] 866 | name = "minimal-lexical" 867 | version = "0.2.1" 868 | source = "registry+https://github.com/rust-lang/crates.io-index" 869 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 870 | 871 | [[package]] 872 | name = "miniz_oxide" 873 | version = "0.8.5" 874 | source = "registry+https://github.com/rust-lang/crates.io-index" 875 | checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" 876 | dependencies = [ 877 | "adler2", 878 | ] 879 | 880 | [[package]] 881 | name = "mio" 882 | version = "1.0.3" 883 | source = "registry+https://github.com/rust-lang/crates.io-index" 884 | checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" 885 | dependencies = [ 886 | "libc", 887 | "wasi 0.11.0+wasi-snapshot-preview1", 888 | "windows-sys 0.52.0", 889 | ] 890 | 891 | [[package]] 892 | name = "nom" 893 | version = "7.1.3" 894 | source = "registry+https://github.com/rust-lang/crates.io-index" 895 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" 896 | dependencies = [ 897 | "memchr", 898 | "minimal-lexical", 899 | ] 900 | 901 | [[package]] 902 | name = "nu-ansi-term" 903 | version = "0.46.0" 904 | source = "registry+https://github.com/rust-lang/crates.io-index" 905 | checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" 906 | dependencies = [ 907 | "overload", 908 | "winapi", 909 | ] 910 | 911 | [[package]] 912 | name = "num" 913 | version = "0.4.3" 914 | source = "registry+https://github.com/rust-lang/crates.io-index" 915 | checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" 916 | dependencies = [ 917 | "num-complex", 918 | "num-integer", 919 | "num-iter", 920 | "num-rational", 921 | "num-traits", 922 | ] 923 | 924 | [[package]] 925 | name = "num-complex" 926 | version = "0.4.6" 927 | source = "registry+https://github.com/rust-lang/crates.io-index" 928 | checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" 929 | dependencies = [ 930 | "num-traits", 931 | ] 932 | 933 | [[package]] 934 | name = "num-derive" 935 | version = "0.4.2" 936 | source = "registry+https://github.com/rust-lang/crates.io-index" 937 | checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" 938 | dependencies = [ 939 | "proc-macro2", 940 | "quote", 941 | "syn", 942 | ] 943 | 944 | [[package]] 945 | name = "num-integer" 946 | version = "0.1.46" 947 | source = "registry+https://github.com/rust-lang/crates.io-index" 948 | checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" 949 | dependencies = [ 950 | "num-traits", 951 | ] 952 | 953 | [[package]] 954 | name = "num-iter" 955 | version = "0.1.45" 956 | source = "registry+https://github.com/rust-lang/crates.io-index" 957 | checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" 958 | dependencies = [ 959 | "autocfg", 960 | "num-integer", 961 | "num-traits", 962 | ] 963 | 964 | [[package]] 965 | name = "num-rational" 966 | version = "0.4.2" 967 | source = "registry+https://github.com/rust-lang/crates.io-index" 968 | checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" 969 | dependencies = [ 970 | "num-integer", 971 | "num-traits", 972 | ] 973 | 974 | [[package]] 975 | name = "num-traits" 976 | version = "0.2.19" 977 | source = "registry+https://github.com/rust-lang/crates.io-index" 978 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 979 | dependencies = [ 980 | "autocfg", 981 | ] 982 | 983 | [[package]] 984 | name = "object" 985 | version = "0.36.7" 986 | source = "registry+https://github.com/rust-lang/crates.io-index" 987 | checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" 988 | dependencies = [ 989 | "memchr", 990 | ] 991 | 992 | [[package]] 993 | name = "once_cell" 994 | version = "1.21.1" 995 | source = "registry+https://github.com/rust-lang/crates.io-index" 996 | checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" 997 | 998 | [[package]] 999 | name = "overload" 1000 | version = "0.1.1" 1001 | source = "registry+https://github.com/rust-lang/crates.io-index" 1002 | checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" 1003 | 1004 | [[package]] 1005 | name = "paste" 1006 | version = "1.0.15" 1007 | source = "registry+https://github.com/rust-lang/crates.io-index" 1008 | checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" 1009 | 1010 | [[package]] 1011 | name = "percent-encoding" 1012 | version = "2.3.1" 1013 | source = "registry+https://github.com/rust-lang/crates.io-index" 1014 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 1015 | 1016 | [[package]] 1017 | name = "pin-project-lite" 1018 | version = "0.2.16" 1019 | source = "registry+https://github.com/rust-lang/crates.io-index" 1020 | checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" 1021 | 1022 | [[package]] 1023 | name = "pin-utils" 1024 | version = "0.1.0" 1025 | source = "registry+https://github.com/rust-lang/crates.io-index" 1026 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1027 | 1028 | [[package]] 1029 | name = "pkg-config" 1030 | version = "0.3.32" 1031 | source = "registry+https://github.com/rust-lang/crates.io-index" 1032 | checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" 1033 | 1034 | [[package]] 1035 | name = "ppv-lite86" 1036 | version = "0.2.21" 1037 | source = "registry+https://github.com/rust-lang/crates.io-index" 1038 | checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" 1039 | dependencies = [ 1040 | "zerocopy", 1041 | ] 1042 | 1043 | [[package]] 1044 | name = "prettyplease" 1045 | version = "0.2.31" 1046 | source = "registry+https://github.com/rust-lang/crates.io-index" 1047 | checksum = "5316f57387668042f561aae71480de936257848f9c43ce528e311d89a07cadeb" 1048 | dependencies = [ 1049 | "proc-macro2", 1050 | "syn", 1051 | ] 1052 | 1053 | [[package]] 1054 | name = "proc-macro2" 1055 | version = "1.0.94" 1056 | source = "registry+https://github.com/rust-lang/crates.io-index" 1057 | checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" 1058 | dependencies = [ 1059 | "unicode-ident", 1060 | ] 1061 | 1062 | [[package]] 1063 | name = "quinn" 1064 | version = "0.11.7" 1065 | source = "registry+https://github.com/rust-lang/crates.io-index" 1066 | checksum = "c3bd15a6f2967aef83887dcb9fec0014580467e33720d073560cf015a5683012" 1067 | dependencies = [ 1068 | "bytes", 1069 | "cfg_aliases", 1070 | "pin-project-lite", 1071 | "quinn-proto", 1072 | "quinn-udp", 1073 | "rustc-hash 2.1.1", 1074 | "rustls", 1075 | "socket2", 1076 | "thiserror", 1077 | "tokio", 1078 | "tracing", 1079 | "web-time", 1080 | ] 1081 | 1082 | [[package]] 1083 | name = "quinn-proto" 1084 | version = "0.11.10" 1085 | source = "registry+https://github.com/rust-lang/crates.io-index" 1086 | checksum = "b820744eb4dc9b57a3398183639c511b5a26d2ed702cedd3febaa1393caa22cc" 1087 | dependencies = [ 1088 | "bytes", 1089 | "getrandom 0.3.2", 1090 | "rand", 1091 | "ring", 1092 | "rustc-hash 2.1.1", 1093 | "rustls", 1094 | "rustls-pki-types", 1095 | "slab", 1096 | "thiserror", 1097 | "tinyvec", 1098 | "tracing", 1099 | "web-time", 1100 | ] 1101 | 1102 | [[package]] 1103 | name = "quinn-udp" 1104 | version = "0.5.10" 1105 | source = "registry+https://github.com/rust-lang/crates.io-index" 1106 | checksum = "e46f3055866785f6b92bc6164b76be02ca8f2eb4b002c0354b28cf4c119e5944" 1107 | dependencies = [ 1108 | "cfg_aliases", 1109 | "libc", 1110 | "once_cell", 1111 | "socket2", 1112 | "tracing", 1113 | "windows-sys 0.59.0", 1114 | ] 1115 | 1116 | [[package]] 1117 | name = "quote" 1118 | version = "1.0.40" 1119 | source = "registry+https://github.com/rust-lang/crates.io-index" 1120 | checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" 1121 | dependencies = [ 1122 | "proc-macro2", 1123 | ] 1124 | 1125 | [[package]] 1126 | name = "r-efi" 1127 | version = "5.2.0" 1128 | source = "registry+https://github.com/rust-lang/crates.io-index" 1129 | checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" 1130 | 1131 | [[package]] 1132 | name = "rand" 1133 | version = "0.9.0" 1134 | source = "registry+https://github.com/rust-lang/crates.io-index" 1135 | checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" 1136 | dependencies = [ 1137 | "rand_chacha", 1138 | "rand_core", 1139 | "zerocopy", 1140 | ] 1141 | 1142 | [[package]] 1143 | name = "rand_chacha" 1144 | version = "0.9.0" 1145 | source = "registry+https://github.com/rust-lang/crates.io-index" 1146 | checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" 1147 | dependencies = [ 1148 | "ppv-lite86", 1149 | "rand_core", 1150 | ] 1151 | 1152 | [[package]] 1153 | name = "rand_core" 1154 | version = "0.9.3" 1155 | source = "registry+https://github.com/rust-lang/crates.io-index" 1156 | checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" 1157 | dependencies = [ 1158 | "getrandom 0.3.2", 1159 | ] 1160 | 1161 | [[package]] 1162 | name = "redox_syscall" 1163 | version = "0.5.10" 1164 | source = "registry+https://github.com/rust-lang/crates.io-index" 1165 | checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" 1166 | dependencies = [ 1167 | "bitflags", 1168 | ] 1169 | 1170 | [[package]] 1171 | name = "regex" 1172 | version = "1.11.1" 1173 | source = "registry+https://github.com/rust-lang/crates.io-index" 1174 | checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" 1175 | dependencies = [ 1176 | "aho-corasick", 1177 | "memchr", 1178 | "regex-automata 0.4.9", 1179 | "regex-syntax 0.8.5", 1180 | ] 1181 | 1182 | [[package]] 1183 | name = "regex-automata" 1184 | version = "0.1.10" 1185 | source = "registry+https://github.com/rust-lang/crates.io-index" 1186 | checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" 1187 | dependencies = [ 1188 | "regex-syntax 0.6.29", 1189 | ] 1190 | 1191 | [[package]] 1192 | name = "regex-automata" 1193 | version = "0.4.9" 1194 | source = "registry+https://github.com/rust-lang/crates.io-index" 1195 | checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" 1196 | dependencies = [ 1197 | "aho-corasick", 1198 | "memchr", 1199 | "regex-syntax 0.8.5", 1200 | ] 1201 | 1202 | [[package]] 1203 | name = "regex-syntax" 1204 | version = "0.6.29" 1205 | source = "registry+https://github.com/rust-lang/crates.io-index" 1206 | checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" 1207 | 1208 | [[package]] 1209 | name = "regex-syntax" 1210 | version = "0.8.5" 1211 | source = "registry+https://github.com/rust-lang/crates.io-index" 1212 | checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" 1213 | 1214 | [[package]] 1215 | name = "reqwest" 1216 | version = "0.12.15" 1217 | source = "registry+https://github.com/rust-lang/crates.io-index" 1218 | checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" 1219 | dependencies = [ 1220 | "base64", 1221 | "bytes", 1222 | "futures-channel", 1223 | "futures-core", 1224 | "futures-util", 1225 | "http", 1226 | "http-body", 1227 | "http-body-util", 1228 | "hyper", 1229 | "hyper-rustls", 1230 | "hyper-util", 1231 | "ipnet", 1232 | "js-sys", 1233 | "log", 1234 | "mime", 1235 | "once_cell", 1236 | "percent-encoding", 1237 | "pin-project-lite", 1238 | "quinn", 1239 | "rustls", 1240 | "rustls-pemfile", 1241 | "rustls-pki-types", 1242 | "serde", 1243 | "serde_json", 1244 | "serde_urlencoded", 1245 | "sync_wrapper", 1246 | "tokio", 1247 | "tokio-rustls", 1248 | "tower", 1249 | "tower-service", 1250 | "url", 1251 | "wasm-bindgen", 1252 | "wasm-bindgen-futures", 1253 | "web-sys", 1254 | "webpki-roots", 1255 | "windows-registry", 1256 | ] 1257 | 1258 | [[package]] 1259 | name = "ring" 1260 | version = "0.17.14" 1261 | source = "registry+https://github.com/rust-lang/crates.io-index" 1262 | checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" 1263 | dependencies = [ 1264 | "cc", 1265 | "cfg-if", 1266 | "getrandom 0.2.15", 1267 | "libc", 1268 | "untrusted", 1269 | "windows-sys 0.52.0", 1270 | ] 1271 | 1272 | [[package]] 1273 | name = "rustc-demangle" 1274 | version = "0.1.24" 1275 | source = "registry+https://github.com/rust-lang/crates.io-index" 1276 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 1277 | 1278 | [[package]] 1279 | name = "rustc-hash" 1280 | version = "1.1.0" 1281 | source = "registry+https://github.com/rust-lang/crates.io-index" 1282 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 1283 | 1284 | [[package]] 1285 | name = "rustc-hash" 1286 | version = "2.1.1" 1287 | source = "registry+https://github.com/rust-lang/crates.io-index" 1288 | checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" 1289 | 1290 | [[package]] 1291 | name = "rustix" 1292 | version = "0.38.44" 1293 | source = "registry+https://github.com/rust-lang/crates.io-index" 1294 | checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" 1295 | dependencies = [ 1296 | "bitflags", 1297 | "errno", 1298 | "libc", 1299 | "linux-raw-sys 0.4.15", 1300 | "windows-sys 0.59.0", 1301 | ] 1302 | 1303 | [[package]] 1304 | name = "rustix" 1305 | version = "1.0.3" 1306 | source = "registry+https://github.com/rust-lang/crates.io-index" 1307 | checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96" 1308 | dependencies = [ 1309 | "bitflags", 1310 | "errno", 1311 | "libc", 1312 | "linux-raw-sys 0.9.3", 1313 | "windows-sys 0.59.0", 1314 | ] 1315 | 1316 | [[package]] 1317 | name = "rustls" 1318 | version = "0.23.25" 1319 | source = "registry+https://github.com/rust-lang/crates.io-index" 1320 | checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c" 1321 | dependencies = [ 1322 | "once_cell", 1323 | "ring", 1324 | "rustls-pki-types", 1325 | "rustls-webpki", 1326 | "subtle", 1327 | "zeroize", 1328 | ] 1329 | 1330 | [[package]] 1331 | name = "rustls-pemfile" 1332 | version = "2.2.0" 1333 | source = "registry+https://github.com/rust-lang/crates.io-index" 1334 | checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" 1335 | dependencies = [ 1336 | "rustls-pki-types", 1337 | ] 1338 | 1339 | [[package]] 1340 | name = "rustls-pki-types" 1341 | version = "1.11.0" 1342 | source = "registry+https://github.com/rust-lang/crates.io-index" 1343 | checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" 1344 | dependencies = [ 1345 | "web-time", 1346 | ] 1347 | 1348 | [[package]] 1349 | name = "rustls-webpki" 1350 | version = "0.103.0" 1351 | source = "registry+https://github.com/rust-lang/crates.io-index" 1352 | checksum = "0aa4eeac2588ffff23e9d7a7e9b3f971c5fb5b7ebc9452745e0c232c64f83b2f" 1353 | dependencies = [ 1354 | "ring", 1355 | "rustls-pki-types", 1356 | "untrusted", 1357 | ] 1358 | 1359 | [[package]] 1360 | name = "rustversion" 1361 | version = "1.0.20" 1362 | source = "registry+https://github.com/rust-lang/crates.io-index" 1363 | checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" 1364 | 1365 | [[package]] 1366 | name = "ryu" 1367 | version = "1.0.20" 1368 | source = "registry+https://github.com/rust-lang/crates.io-index" 1369 | checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" 1370 | 1371 | [[package]] 1372 | name = "serde" 1373 | version = "1.0.219" 1374 | source = "registry+https://github.com/rust-lang/crates.io-index" 1375 | checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" 1376 | dependencies = [ 1377 | "serde_derive", 1378 | ] 1379 | 1380 | [[package]] 1381 | name = "serde_derive" 1382 | version = "1.0.219" 1383 | source = "registry+https://github.com/rust-lang/crates.io-index" 1384 | checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" 1385 | dependencies = [ 1386 | "proc-macro2", 1387 | "quote", 1388 | "syn", 1389 | ] 1390 | 1391 | [[package]] 1392 | name = "serde_json" 1393 | version = "1.0.140" 1394 | source = "registry+https://github.com/rust-lang/crates.io-index" 1395 | checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" 1396 | dependencies = [ 1397 | "itoa", 1398 | "memchr", 1399 | "ryu", 1400 | "serde", 1401 | ] 1402 | 1403 | [[package]] 1404 | name = "serde_spanned" 1405 | version = "0.6.8" 1406 | source = "registry+https://github.com/rust-lang/crates.io-index" 1407 | checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" 1408 | dependencies = [ 1409 | "serde", 1410 | ] 1411 | 1412 | [[package]] 1413 | name = "serde_urlencoded" 1414 | version = "0.7.1" 1415 | source = "registry+https://github.com/rust-lang/crates.io-index" 1416 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 1417 | dependencies = [ 1418 | "form_urlencoded", 1419 | "itoa", 1420 | "ryu", 1421 | "serde", 1422 | ] 1423 | 1424 | [[package]] 1425 | name = "sharded-slab" 1426 | version = "0.1.7" 1427 | source = "registry+https://github.com/rust-lang/crates.io-index" 1428 | checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" 1429 | dependencies = [ 1430 | "lazy_static", 1431 | ] 1432 | 1433 | [[package]] 1434 | name = "shlex" 1435 | version = "1.3.0" 1436 | source = "registry+https://github.com/rust-lang/crates.io-index" 1437 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 1438 | 1439 | [[package]] 1440 | name = "slab" 1441 | version = "0.4.9" 1442 | source = "registry+https://github.com/rust-lang/crates.io-index" 1443 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 1444 | dependencies = [ 1445 | "autocfg", 1446 | ] 1447 | 1448 | [[package]] 1449 | name = "smallvec" 1450 | version = "1.14.0" 1451 | source = "registry+https://github.com/rust-lang/crates.io-index" 1452 | checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" 1453 | 1454 | [[package]] 1455 | name = "socket2" 1456 | version = "0.5.8" 1457 | source = "registry+https://github.com/rust-lang/crates.io-index" 1458 | checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" 1459 | dependencies = [ 1460 | "libc", 1461 | "windows-sys 0.52.0", 1462 | ] 1463 | 1464 | [[package]] 1465 | name = "spin" 1466 | version = "0.9.8" 1467 | source = "registry+https://github.com/rust-lang/crates.io-index" 1468 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 1469 | 1470 | [[package]] 1471 | name = "stable_deref_trait" 1472 | version = "1.2.0" 1473 | source = "registry+https://github.com/rust-lang/crates.io-index" 1474 | checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" 1475 | 1476 | [[package]] 1477 | name = "strsim" 1478 | version = "0.11.1" 1479 | source = "registry+https://github.com/rust-lang/crates.io-index" 1480 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 1481 | 1482 | [[package]] 1483 | name = "subtle" 1484 | version = "2.6.1" 1485 | source = "registry+https://github.com/rust-lang/crates.io-index" 1486 | checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" 1487 | 1488 | [[package]] 1489 | name = "syn" 1490 | version = "2.0.100" 1491 | source = "registry+https://github.com/rust-lang/crates.io-index" 1492 | checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" 1493 | dependencies = [ 1494 | "proc-macro2", 1495 | "quote", 1496 | "unicode-ident", 1497 | ] 1498 | 1499 | [[package]] 1500 | name = "sync_wrapper" 1501 | version = "1.0.2" 1502 | source = "registry+https://github.com/rust-lang/crates.io-index" 1503 | checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" 1504 | dependencies = [ 1505 | "futures-core", 1506 | ] 1507 | 1508 | [[package]] 1509 | name = "synstructure" 1510 | version = "0.13.1" 1511 | source = "registry+https://github.com/rust-lang/crates.io-index" 1512 | checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" 1513 | dependencies = [ 1514 | "proc-macro2", 1515 | "quote", 1516 | "syn", 1517 | ] 1518 | 1519 | [[package]] 1520 | name = "tar" 1521 | version = "0.4.44" 1522 | source = "registry+https://github.com/rust-lang/crates.io-index" 1523 | checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" 1524 | dependencies = [ 1525 | "filetime", 1526 | "libc", 1527 | "xattr", 1528 | ] 1529 | 1530 | [[package]] 1531 | name = "thiserror" 1532 | version = "2.0.12" 1533 | source = "registry+https://github.com/rust-lang/crates.io-index" 1534 | checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" 1535 | dependencies = [ 1536 | "thiserror-impl", 1537 | ] 1538 | 1539 | [[package]] 1540 | name = "thiserror-impl" 1541 | version = "2.0.12" 1542 | source = "registry+https://github.com/rust-lang/crates.io-index" 1543 | checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" 1544 | dependencies = [ 1545 | "proc-macro2", 1546 | "quote", 1547 | "syn", 1548 | ] 1549 | 1550 | [[package]] 1551 | name = "thread_local" 1552 | version = "1.1.8" 1553 | source = "registry+https://github.com/rust-lang/crates.io-index" 1554 | checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" 1555 | dependencies = [ 1556 | "cfg-if", 1557 | "once_cell", 1558 | ] 1559 | 1560 | [[package]] 1561 | name = "tinystr" 1562 | version = "0.7.6" 1563 | source = "registry+https://github.com/rust-lang/crates.io-index" 1564 | checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" 1565 | dependencies = [ 1566 | "displaydoc", 1567 | "zerovec", 1568 | ] 1569 | 1570 | [[package]] 1571 | name = "tinyvec" 1572 | version = "1.9.0" 1573 | source = "registry+https://github.com/rust-lang/crates.io-index" 1574 | checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" 1575 | dependencies = [ 1576 | "tinyvec_macros", 1577 | ] 1578 | 1579 | [[package]] 1580 | name = "tinyvec_macros" 1581 | version = "0.1.1" 1582 | source = "registry+https://github.com/rust-lang/crates.io-index" 1583 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 1584 | 1585 | [[package]] 1586 | name = "tokio" 1587 | version = "1.44.1" 1588 | source = "registry+https://github.com/rust-lang/crates.io-index" 1589 | checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" 1590 | dependencies = [ 1591 | "backtrace", 1592 | "bytes", 1593 | "libc", 1594 | "mio", 1595 | "pin-project-lite", 1596 | "socket2", 1597 | "windows-sys 0.52.0", 1598 | ] 1599 | 1600 | [[package]] 1601 | name = "tokio-rustls" 1602 | version = "0.26.2" 1603 | source = "registry+https://github.com/rust-lang/crates.io-index" 1604 | checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" 1605 | dependencies = [ 1606 | "rustls", 1607 | "tokio", 1608 | ] 1609 | 1610 | [[package]] 1611 | name = "toml" 1612 | version = "0.8.20" 1613 | source = "registry+https://github.com/rust-lang/crates.io-index" 1614 | checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148" 1615 | dependencies = [ 1616 | "serde", 1617 | "serde_spanned", 1618 | "toml_datetime", 1619 | "toml_edit", 1620 | ] 1621 | 1622 | [[package]] 1623 | name = "toml_datetime" 1624 | version = "0.6.8" 1625 | source = "registry+https://github.com/rust-lang/crates.io-index" 1626 | checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" 1627 | dependencies = [ 1628 | "serde", 1629 | ] 1630 | 1631 | [[package]] 1632 | name = "toml_edit" 1633 | version = "0.22.24" 1634 | source = "registry+https://github.com/rust-lang/crates.io-index" 1635 | checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" 1636 | dependencies = [ 1637 | "indexmap", 1638 | "serde", 1639 | "serde_spanned", 1640 | "toml_datetime", 1641 | "winnow", 1642 | ] 1643 | 1644 | [[package]] 1645 | name = "tower" 1646 | version = "0.5.2" 1647 | source = "registry+https://github.com/rust-lang/crates.io-index" 1648 | checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" 1649 | dependencies = [ 1650 | "futures-core", 1651 | "futures-util", 1652 | "pin-project-lite", 1653 | "sync_wrapper", 1654 | "tokio", 1655 | "tower-layer", 1656 | "tower-service", 1657 | ] 1658 | 1659 | [[package]] 1660 | name = "tower-layer" 1661 | version = "0.3.3" 1662 | source = "registry+https://github.com/rust-lang/crates.io-index" 1663 | checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" 1664 | 1665 | [[package]] 1666 | name = "tower-service" 1667 | version = "0.3.3" 1668 | source = "registry+https://github.com/rust-lang/crates.io-index" 1669 | checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" 1670 | 1671 | [[package]] 1672 | name = "tracing" 1673 | version = "0.1.41" 1674 | source = "registry+https://github.com/rust-lang/crates.io-index" 1675 | checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" 1676 | dependencies = [ 1677 | "pin-project-lite", 1678 | "tracing-attributes", 1679 | "tracing-core", 1680 | ] 1681 | 1682 | [[package]] 1683 | name = "tracing-attributes" 1684 | version = "0.1.28" 1685 | source = "registry+https://github.com/rust-lang/crates.io-index" 1686 | checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" 1687 | dependencies = [ 1688 | "proc-macro2", 1689 | "quote", 1690 | "syn", 1691 | ] 1692 | 1693 | [[package]] 1694 | name = "tracing-core" 1695 | version = "0.1.33" 1696 | source = "registry+https://github.com/rust-lang/crates.io-index" 1697 | checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" 1698 | dependencies = [ 1699 | "once_cell", 1700 | "valuable", 1701 | ] 1702 | 1703 | [[package]] 1704 | name = "tracing-log" 1705 | version = "0.2.0" 1706 | source = "registry+https://github.com/rust-lang/crates.io-index" 1707 | checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" 1708 | dependencies = [ 1709 | "log", 1710 | "once_cell", 1711 | "tracing-core", 1712 | ] 1713 | 1714 | [[package]] 1715 | name = "tracing-subscriber" 1716 | version = "0.3.19" 1717 | source = "registry+https://github.com/rust-lang/crates.io-index" 1718 | checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" 1719 | dependencies = [ 1720 | "matchers", 1721 | "nu-ansi-term", 1722 | "once_cell", 1723 | "regex", 1724 | "sharded-slab", 1725 | "smallvec", 1726 | "thread_local", 1727 | "tracing", 1728 | "tracing-core", 1729 | "tracing-log", 1730 | ] 1731 | 1732 | [[package]] 1733 | name = "try-lock" 1734 | version = "0.2.5" 1735 | source = "registry+https://github.com/rust-lang/crates.io-index" 1736 | checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" 1737 | 1738 | [[package]] 1739 | name = "unicode-ident" 1740 | version = "1.0.18" 1741 | source = "registry+https://github.com/rust-lang/crates.io-index" 1742 | checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" 1743 | 1744 | [[package]] 1745 | name = "untrusted" 1746 | version = "0.9.0" 1747 | source = "registry+https://github.com/rust-lang/crates.io-index" 1748 | checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 1749 | 1750 | [[package]] 1751 | name = "url" 1752 | version = "2.5.4" 1753 | source = "registry+https://github.com/rust-lang/crates.io-index" 1754 | checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" 1755 | dependencies = [ 1756 | "form_urlencoded", 1757 | "idna", 1758 | "percent-encoding", 1759 | ] 1760 | 1761 | [[package]] 1762 | name = "utf16_iter" 1763 | version = "1.0.5" 1764 | source = "registry+https://github.com/rust-lang/crates.io-index" 1765 | checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" 1766 | 1767 | [[package]] 1768 | name = "utf8_iter" 1769 | version = "1.0.4" 1770 | source = "registry+https://github.com/rust-lang/crates.io-index" 1771 | checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" 1772 | 1773 | [[package]] 1774 | name = "utf8parse" 1775 | version = "0.2.2" 1776 | source = "registry+https://github.com/rust-lang/crates.io-index" 1777 | checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 1778 | 1779 | [[package]] 1780 | name = "v8_killer_core" 1781 | version = "0.1.0" 1782 | dependencies = [ 1783 | "ctor", 1784 | "frida-gum", 1785 | "once_cell", 1786 | "regex", 1787 | "serde", 1788 | "toml", 1789 | "tracing", 1790 | "tracing-subscriber", 1791 | "windows-sys 0.59.0", 1792 | ] 1793 | 1794 | [[package]] 1795 | name = "v8_killer_launcher" 1796 | version = "0.1.0" 1797 | dependencies = [ 1798 | "clap", 1799 | "tracing", 1800 | "tracing-subscriber", 1801 | "windows", 1802 | ] 1803 | 1804 | [[package]] 1805 | name = "valuable" 1806 | version = "0.1.1" 1807 | source = "registry+https://github.com/rust-lang/crates.io-index" 1808 | checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" 1809 | 1810 | [[package]] 1811 | name = "want" 1812 | version = "0.3.1" 1813 | source = "registry+https://github.com/rust-lang/crates.io-index" 1814 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 1815 | dependencies = [ 1816 | "try-lock", 1817 | ] 1818 | 1819 | [[package]] 1820 | name = "wasi" 1821 | version = "0.11.0+wasi-snapshot-preview1" 1822 | source = "registry+https://github.com/rust-lang/crates.io-index" 1823 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1824 | 1825 | [[package]] 1826 | name = "wasi" 1827 | version = "0.14.2+wasi-0.2.4" 1828 | source = "registry+https://github.com/rust-lang/crates.io-index" 1829 | checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" 1830 | dependencies = [ 1831 | "wit-bindgen-rt", 1832 | ] 1833 | 1834 | [[package]] 1835 | name = "wasm-bindgen" 1836 | version = "0.2.100" 1837 | source = "registry+https://github.com/rust-lang/crates.io-index" 1838 | checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" 1839 | dependencies = [ 1840 | "cfg-if", 1841 | "once_cell", 1842 | "rustversion", 1843 | "wasm-bindgen-macro", 1844 | ] 1845 | 1846 | [[package]] 1847 | name = "wasm-bindgen-backend" 1848 | version = "0.2.100" 1849 | source = "registry+https://github.com/rust-lang/crates.io-index" 1850 | checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" 1851 | dependencies = [ 1852 | "bumpalo", 1853 | "log", 1854 | "proc-macro2", 1855 | "quote", 1856 | "syn", 1857 | "wasm-bindgen-shared", 1858 | ] 1859 | 1860 | [[package]] 1861 | name = "wasm-bindgen-futures" 1862 | version = "0.4.50" 1863 | source = "registry+https://github.com/rust-lang/crates.io-index" 1864 | checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" 1865 | dependencies = [ 1866 | "cfg-if", 1867 | "js-sys", 1868 | "once_cell", 1869 | "wasm-bindgen", 1870 | "web-sys", 1871 | ] 1872 | 1873 | [[package]] 1874 | name = "wasm-bindgen-macro" 1875 | version = "0.2.100" 1876 | source = "registry+https://github.com/rust-lang/crates.io-index" 1877 | checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" 1878 | dependencies = [ 1879 | "quote", 1880 | "wasm-bindgen-macro-support", 1881 | ] 1882 | 1883 | [[package]] 1884 | name = "wasm-bindgen-macro-support" 1885 | version = "0.2.100" 1886 | source = "registry+https://github.com/rust-lang/crates.io-index" 1887 | checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" 1888 | dependencies = [ 1889 | "proc-macro2", 1890 | "quote", 1891 | "syn", 1892 | "wasm-bindgen-backend", 1893 | "wasm-bindgen-shared", 1894 | ] 1895 | 1896 | [[package]] 1897 | name = "wasm-bindgen-shared" 1898 | version = "0.2.100" 1899 | source = "registry+https://github.com/rust-lang/crates.io-index" 1900 | checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" 1901 | dependencies = [ 1902 | "unicode-ident", 1903 | ] 1904 | 1905 | [[package]] 1906 | name = "web-sys" 1907 | version = "0.3.77" 1908 | source = "registry+https://github.com/rust-lang/crates.io-index" 1909 | checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" 1910 | dependencies = [ 1911 | "js-sys", 1912 | "wasm-bindgen", 1913 | ] 1914 | 1915 | [[package]] 1916 | name = "web-time" 1917 | version = "1.1.0" 1918 | source = "registry+https://github.com/rust-lang/crates.io-index" 1919 | checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" 1920 | dependencies = [ 1921 | "js-sys", 1922 | "wasm-bindgen", 1923 | ] 1924 | 1925 | [[package]] 1926 | name = "webpki-roots" 1927 | version = "0.26.8" 1928 | source = "registry+https://github.com/rust-lang/crates.io-index" 1929 | checksum = "2210b291f7ea53617fbafcc4939f10914214ec15aace5ba62293a668f322c5c9" 1930 | dependencies = [ 1931 | "rustls-pki-types", 1932 | ] 1933 | 1934 | [[package]] 1935 | name = "which" 1936 | version = "4.4.2" 1937 | source = "registry+https://github.com/rust-lang/crates.io-index" 1938 | checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" 1939 | dependencies = [ 1940 | "either", 1941 | "home", 1942 | "once_cell", 1943 | "rustix 0.38.44", 1944 | ] 1945 | 1946 | [[package]] 1947 | name = "winapi" 1948 | version = "0.3.9" 1949 | source = "registry+https://github.com/rust-lang/crates.io-index" 1950 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1951 | dependencies = [ 1952 | "winapi-i686-pc-windows-gnu", 1953 | "winapi-x86_64-pc-windows-gnu", 1954 | ] 1955 | 1956 | [[package]] 1957 | name = "winapi-i686-pc-windows-gnu" 1958 | version = "0.4.0" 1959 | source = "registry+https://github.com/rust-lang/crates.io-index" 1960 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1961 | 1962 | [[package]] 1963 | name = "winapi-x86_64-pc-windows-gnu" 1964 | version = "0.4.0" 1965 | source = "registry+https://github.com/rust-lang/crates.io-index" 1966 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1967 | 1968 | [[package]] 1969 | name = "windows" 1970 | version = "0.61.0" 1971 | source = "registry+https://github.com/rust-lang/crates.io-index" 1972 | checksum = "b76779b1008b2bafb6cdf5e299dfe7f5780d604349fe68d9476c08feb448e98f" 1973 | dependencies = [ 1974 | "windows-collections", 1975 | "windows-core", 1976 | "windows-future", 1977 | "windows-link", 1978 | "windows-numerics", 1979 | ] 1980 | 1981 | [[package]] 1982 | name = "windows-collections" 1983 | version = "0.1.2" 1984 | source = "registry+https://github.com/rust-lang/crates.io-index" 1985 | checksum = "b095389c0f7a1e16ba4927c17478dca870938c7bbeb31e7f77eab4e86dc8fd1a" 1986 | dependencies = [ 1987 | "windows-core", 1988 | ] 1989 | 1990 | [[package]] 1991 | name = "windows-core" 1992 | version = "0.61.0" 1993 | source = "registry+https://github.com/rust-lang/crates.io-index" 1994 | checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" 1995 | dependencies = [ 1996 | "windows-implement", 1997 | "windows-interface", 1998 | "windows-link", 1999 | "windows-result", 2000 | "windows-strings 0.4.0", 2001 | ] 2002 | 2003 | [[package]] 2004 | name = "windows-future" 2005 | version = "0.1.2" 2006 | source = "registry+https://github.com/rust-lang/crates.io-index" 2007 | checksum = "dbb86813135724d122c524095d1e55a72f2844b0ce6b77ef05e782dff1e6abfc" 2008 | dependencies = [ 2009 | "windows-core", 2010 | "windows-link", 2011 | ] 2012 | 2013 | [[package]] 2014 | name = "windows-implement" 2015 | version = "0.60.0" 2016 | source = "registry+https://github.com/rust-lang/crates.io-index" 2017 | checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" 2018 | dependencies = [ 2019 | "proc-macro2", 2020 | "quote", 2021 | "syn", 2022 | ] 2023 | 2024 | [[package]] 2025 | name = "windows-interface" 2026 | version = "0.59.1" 2027 | source = "registry+https://github.com/rust-lang/crates.io-index" 2028 | checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" 2029 | dependencies = [ 2030 | "proc-macro2", 2031 | "quote", 2032 | "syn", 2033 | ] 2034 | 2035 | [[package]] 2036 | name = "windows-link" 2037 | version = "0.1.1" 2038 | source = "registry+https://github.com/rust-lang/crates.io-index" 2039 | checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" 2040 | 2041 | [[package]] 2042 | name = "windows-numerics" 2043 | version = "0.2.0" 2044 | source = "registry+https://github.com/rust-lang/crates.io-index" 2045 | checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" 2046 | dependencies = [ 2047 | "windows-core", 2048 | "windows-link", 2049 | ] 2050 | 2051 | [[package]] 2052 | name = "windows-registry" 2053 | version = "0.4.0" 2054 | source = "registry+https://github.com/rust-lang/crates.io-index" 2055 | checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" 2056 | dependencies = [ 2057 | "windows-result", 2058 | "windows-strings 0.3.1", 2059 | "windows-targets 0.53.0", 2060 | ] 2061 | 2062 | [[package]] 2063 | name = "windows-result" 2064 | version = "0.3.2" 2065 | source = "registry+https://github.com/rust-lang/crates.io-index" 2066 | checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" 2067 | dependencies = [ 2068 | "windows-link", 2069 | ] 2070 | 2071 | [[package]] 2072 | name = "windows-strings" 2073 | version = "0.3.1" 2074 | source = "registry+https://github.com/rust-lang/crates.io-index" 2075 | checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" 2076 | dependencies = [ 2077 | "windows-link", 2078 | ] 2079 | 2080 | [[package]] 2081 | name = "windows-strings" 2082 | version = "0.4.0" 2083 | source = "registry+https://github.com/rust-lang/crates.io-index" 2084 | checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" 2085 | dependencies = [ 2086 | "windows-link", 2087 | ] 2088 | 2089 | [[package]] 2090 | name = "windows-sys" 2091 | version = "0.52.0" 2092 | source = "registry+https://github.com/rust-lang/crates.io-index" 2093 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 2094 | dependencies = [ 2095 | "windows-targets 0.52.6", 2096 | ] 2097 | 2098 | [[package]] 2099 | name = "windows-sys" 2100 | version = "0.59.0" 2101 | source = "registry+https://github.com/rust-lang/crates.io-index" 2102 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 2103 | dependencies = [ 2104 | "windows-targets 0.52.6", 2105 | ] 2106 | 2107 | [[package]] 2108 | name = "windows-targets" 2109 | version = "0.52.6" 2110 | source = "registry+https://github.com/rust-lang/crates.io-index" 2111 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 2112 | dependencies = [ 2113 | "windows_aarch64_gnullvm 0.52.6", 2114 | "windows_aarch64_msvc 0.52.6", 2115 | "windows_i686_gnu 0.52.6", 2116 | "windows_i686_gnullvm 0.52.6", 2117 | "windows_i686_msvc 0.52.6", 2118 | "windows_x86_64_gnu 0.52.6", 2119 | "windows_x86_64_gnullvm 0.52.6", 2120 | "windows_x86_64_msvc 0.52.6", 2121 | ] 2122 | 2123 | [[package]] 2124 | name = "windows-targets" 2125 | version = "0.53.0" 2126 | source = "registry+https://github.com/rust-lang/crates.io-index" 2127 | checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" 2128 | dependencies = [ 2129 | "windows_aarch64_gnullvm 0.53.0", 2130 | "windows_aarch64_msvc 0.53.0", 2131 | "windows_i686_gnu 0.53.0", 2132 | "windows_i686_gnullvm 0.53.0", 2133 | "windows_i686_msvc 0.53.0", 2134 | "windows_x86_64_gnu 0.53.0", 2135 | "windows_x86_64_gnullvm 0.53.0", 2136 | "windows_x86_64_msvc 0.53.0", 2137 | ] 2138 | 2139 | [[package]] 2140 | name = "windows_aarch64_gnullvm" 2141 | version = "0.52.6" 2142 | source = "registry+https://github.com/rust-lang/crates.io-index" 2143 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 2144 | 2145 | [[package]] 2146 | name = "windows_aarch64_gnullvm" 2147 | version = "0.53.0" 2148 | source = "registry+https://github.com/rust-lang/crates.io-index" 2149 | checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" 2150 | 2151 | [[package]] 2152 | name = "windows_aarch64_msvc" 2153 | version = "0.52.6" 2154 | source = "registry+https://github.com/rust-lang/crates.io-index" 2155 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 2156 | 2157 | [[package]] 2158 | name = "windows_aarch64_msvc" 2159 | version = "0.53.0" 2160 | source = "registry+https://github.com/rust-lang/crates.io-index" 2161 | checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" 2162 | 2163 | [[package]] 2164 | name = "windows_i686_gnu" 2165 | version = "0.52.6" 2166 | source = "registry+https://github.com/rust-lang/crates.io-index" 2167 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 2168 | 2169 | [[package]] 2170 | name = "windows_i686_gnu" 2171 | version = "0.53.0" 2172 | source = "registry+https://github.com/rust-lang/crates.io-index" 2173 | checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" 2174 | 2175 | [[package]] 2176 | name = "windows_i686_gnullvm" 2177 | version = "0.52.6" 2178 | source = "registry+https://github.com/rust-lang/crates.io-index" 2179 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 2180 | 2181 | [[package]] 2182 | name = "windows_i686_gnullvm" 2183 | version = "0.53.0" 2184 | source = "registry+https://github.com/rust-lang/crates.io-index" 2185 | checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" 2186 | 2187 | [[package]] 2188 | name = "windows_i686_msvc" 2189 | version = "0.52.6" 2190 | source = "registry+https://github.com/rust-lang/crates.io-index" 2191 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 2192 | 2193 | [[package]] 2194 | name = "windows_i686_msvc" 2195 | version = "0.53.0" 2196 | source = "registry+https://github.com/rust-lang/crates.io-index" 2197 | checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" 2198 | 2199 | [[package]] 2200 | name = "windows_x86_64_gnu" 2201 | version = "0.52.6" 2202 | source = "registry+https://github.com/rust-lang/crates.io-index" 2203 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 2204 | 2205 | [[package]] 2206 | name = "windows_x86_64_gnu" 2207 | version = "0.53.0" 2208 | source = "registry+https://github.com/rust-lang/crates.io-index" 2209 | checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" 2210 | 2211 | [[package]] 2212 | name = "windows_x86_64_gnullvm" 2213 | version = "0.52.6" 2214 | source = "registry+https://github.com/rust-lang/crates.io-index" 2215 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 2216 | 2217 | [[package]] 2218 | name = "windows_x86_64_gnullvm" 2219 | version = "0.53.0" 2220 | source = "registry+https://github.com/rust-lang/crates.io-index" 2221 | checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" 2222 | 2223 | [[package]] 2224 | name = "windows_x86_64_msvc" 2225 | version = "0.52.6" 2226 | source = "registry+https://github.com/rust-lang/crates.io-index" 2227 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 2228 | 2229 | [[package]] 2230 | name = "windows_x86_64_msvc" 2231 | version = "0.53.0" 2232 | source = "registry+https://github.com/rust-lang/crates.io-index" 2233 | checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" 2234 | 2235 | [[package]] 2236 | name = "winnow" 2237 | version = "0.7.4" 2238 | source = "registry+https://github.com/rust-lang/crates.io-index" 2239 | checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36" 2240 | dependencies = [ 2241 | "memchr", 2242 | ] 2243 | 2244 | [[package]] 2245 | name = "wit-bindgen-rt" 2246 | version = "0.39.0" 2247 | source = "registry+https://github.com/rust-lang/crates.io-index" 2248 | checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" 2249 | dependencies = [ 2250 | "bitflags", 2251 | ] 2252 | 2253 | [[package]] 2254 | name = "write16" 2255 | version = "1.0.0" 2256 | source = "registry+https://github.com/rust-lang/crates.io-index" 2257 | checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" 2258 | 2259 | [[package]] 2260 | name = "writeable" 2261 | version = "0.5.5" 2262 | source = "registry+https://github.com/rust-lang/crates.io-index" 2263 | checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" 2264 | 2265 | [[package]] 2266 | name = "xattr" 2267 | version = "1.5.0" 2268 | source = "registry+https://github.com/rust-lang/crates.io-index" 2269 | checksum = "0d65cbf2f12c15564212d48f4e3dfb87923d25d611f2aed18f4cb23f0413d89e" 2270 | dependencies = [ 2271 | "libc", 2272 | "rustix 1.0.3", 2273 | ] 2274 | 2275 | [[package]] 2276 | name = "xz" 2277 | version = "0.1.0" 2278 | source = "registry+https://github.com/rust-lang/crates.io-index" 2279 | checksum = "3c887690ff2a2e233e8e49633461521f98ec57fbff9d59a884c9a4f04ec1da34" 2280 | dependencies = [ 2281 | "xz2", 2282 | ] 2283 | 2284 | [[package]] 2285 | name = "xz2" 2286 | version = "0.1.7" 2287 | source = "registry+https://github.com/rust-lang/crates.io-index" 2288 | checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" 2289 | dependencies = [ 2290 | "lzma-sys", 2291 | ] 2292 | 2293 | [[package]] 2294 | name = "yoke" 2295 | version = "0.7.5" 2296 | source = "registry+https://github.com/rust-lang/crates.io-index" 2297 | checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" 2298 | dependencies = [ 2299 | "serde", 2300 | "stable_deref_trait", 2301 | "yoke-derive", 2302 | "zerofrom", 2303 | ] 2304 | 2305 | [[package]] 2306 | name = "yoke-derive" 2307 | version = "0.7.5" 2308 | source = "registry+https://github.com/rust-lang/crates.io-index" 2309 | checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" 2310 | dependencies = [ 2311 | "proc-macro2", 2312 | "quote", 2313 | "syn", 2314 | "synstructure", 2315 | ] 2316 | 2317 | [[package]] 2318 | name = "zerocopy" 2319 | version = "0.8.23" 2320 | source = "registry+https://github.com/rust-lang/crates.io-index" 2321 | checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6" 2322 | dependencies = [ 2323 | "zerocopy-derive", 2324 | ] 2325 | 2326 | [[package]] 2327 | name = "zerocopy-derive" 2328 | version = "0.8.23" 2329 | source = "registry+https://github.com/rust-lang/crates.io-index" 2330 | checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154" 2331 | dependencies = [ 2332 | "proc-macro2", 2333 | "quote", 2334 | "syn", 2335 | ] 2336 | 2337 | [[package]] 2338 | name = "zerofrom" 2339 | version = "0.1.6" 2340 | source = "registry+https://github.com/rust-lang/crates.io-index" 2341 | checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" 2342 | dependencies = [ 2343 | "zerofrom-derive", 2344 | ] 2345 | 2346 | [[package]] 2347 | name = "zerofrom-derive" 2348 | version = "0.1.6" 2349 | source = "registry+https://github.com/rust-lang/crates.io-index" 2350 | checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" 2351 | dependencies = [ 2352 | "proc-macro2", 2353 | "quote", 2354 | "syn", 2355 | "synstructure", 2356 | ] 2357 | 2358 | [[package]] 2359 | name = "zeroize" 2360 | version = "1.8.1" 2361 | source = "registry+https://github.com/rust-lang/crates.io-index" 2362 | checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" 2363 | 2364 | [[package]] 2365 | name = "zerovec" 2366 | version = "0.10.4" 2367 | source = "registry+https://github.com/rust-lang/crates.io-index" 2368 | checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" 2369 | dependencies = [ 2370 | "yoke", 2371 | "zerofrom", 2372 | "zerovec-derive", 2373 | ] 2374 | 2375 | [[package]] 2376 | name = "zerovec-derive" 2377 | version = "0.10.3" 2378 | source = "registry+https://github.com/rust-lang/crates.io-index" 2379 | checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" 2380 | dependencies = [ 2381 | "proc-macro2", 2382 | "quote", 2383 | "syn", 2384 | ] 2385 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "crates/core", 4 | "crates/launcher", 5 | ] 6 | resolver = "2" 7 | 8 | [workspace.package] 9 | version = "0.1.0" 10 | edition = "2021" 11 | authors = ["ShellWen "] 12 | 13 | [workspace.dependencies] 14 | clap = { version = "4.5", features = ["derive"] } 15 | tracing = "0.1" 16 | tracing-subscriber = "0.3" 17 | 18 | [profile.release] 19 | opt-level = "z" 20 | lto = true 21 | codegen-units = 1 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2023 ShellWen 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 15 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 16 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 18 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 19 | OR OTHER DEALINGS IN THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 11 | 12 | 13 | 14 | 21 | [![Contributors][contributors-shield]][contributors-url] 22 | [![Forks][forks-shield]][forks-url] 23 | [![Stargazers][stars-shield]][stars-url] 24 | [![Issues][issues-shield]][issues-url] 25 | [![MIT License][license-shield]][license-url] 26 | [![LinkedIn][linkedin-shield]][linkedin-url] 27 | [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/O5O4RNVHA) 28 | 29 | 30 | 31 | 32 |
33 |
34 |

V8 Killer

35 | 36 |

37 | A powerful and highly customizable universal V8 virtual machine injector. 38 |
39 | Explore the docs » 40 |
41 |
42 | Report Bug 43 | · 44 | Request Feature 45 |

46 |
47 | 48 | 49 | ## Documentations 50 | 51 | Documentations are available under [GitHub Pages](https://shellwen.github.io/v8_killer/). 52 | 53 | 54 | 55 | ## About The Project 56 | 57 | This project began with an initial idea: injecting scripts into Electron applications. There are traditionally two main approaches for accomplishing this. 58 | - Modifying resource files, such as .js or .asar files. However, this approach is highly invasive and cannot pass integrity checks in some software. 59 | - Opening a debugging port (`--inspect` or `--inspect-brk`) and injecting scripts using a debugger. However, some software may inspect this parameter or outright block it. 60 | 61 | This project takes a different approach by hooking into the compilation functions of the V8 engine, directly modifying the source code passed to the V8 compiler. This allows scripts to be injected into the V8 engine without altering any local files or opening any debugging ports. Through testing, it has been confirmed that this method can be used with any software/framework built on the V8 engine, including but not limited to Node.js, Electron, and Deno. 62 | 63 | Currently, this project has been tested exclusively on Linux and Windows. In theory, with minor modifications, it should be possible to run it on macOS. However, this is not currently part of our development roadmap. 64 | 65 | This project is divided into two parts: `core` and `launcher`. The `core` constitutes the central component and represents the actual injected payload. The `launcher` is responsible for loading the payload, which is the `core`, into the target program. 66 | 67 | On Linux, loading the payload can be accomplished simply using `LD_PRELOAD`. However, on Windows, this might require additional work, and this is where the purpose of the launcher comes into play. 68 | 69 | So far, we support the following targets: 70 | 71 | | Target | Supported | Note | 72 | |----------|-----------|------------------------------------------------------------------------------------------------------------| 73 | | Node.js | Yes | | 74 | | Electron | Yes | | 75 | | CEF | Untested | | 76 | | Deno | No | Deno remove exports from V8. In future versions, we will introduce pattern matching to address this issue. | 77 | 78 | Pattern matching is on the way. [#12](https://github.com/ShellWen/v8_killer/issues/12) 79 | 80 |

(back to top)

81 | 82 | 83 | ## Getting Started 84 | 85 | This is an example of how you may give instructions on setting up your project locally. To get a local copy up and running follow these simple example steps. 86 | 87 | 88 | ## License 89 | 90 | Distributed under the MIT License. See `LICENSE` for more information. 91 | 92 |

(back to top)

93 | 94 | 95 | 96 | 97 | ## Contact 98 | 99 | ShellWen - [@realShellWen](https://twitter.com/realShellWen) - me@shellwen.com 100 | 101 | Project Link: [https://github.com/ShellWen/v8_killer](https://github.com/ShellWen/v8_killer) 102 | 103 |

(back to top)

104 | 105 | 106 | 107 | [contributors-shield]: https://img.shields.io/github/contributors/ShellWen/v8_killer.svg?style=for-the-badge 108 | [contributors-url]: https://github.com/ShellWen/v8_killer/graphs/contributors 109 | [forks-shield]: https://img.shields.io/github/forks/ShellWen/v8_killer.svg?style=for-the-badge 110 | [forks-url]: https://github.com/ShellWen/v8_killer/network/members 111 | [stars-shield]: https://img.shields.io/github/stars/ShellWen/v8_killer.svg?style=for-the-badge 112 | [stars-url]: https://github.com/ShellWen/v8_killer/stargazers 113 | [issues-shield]: https://img.shields.io/github/issues/ShellWen/v8_killer.svg?style=for-the-badge 114 | [issues-url]: https://github.com/ShellWen/v8_killer/issues 115 | [license-shield]: https://img.shields.io/github/license/ShellWen/v8_killer.svg?style=for-the-badge 116 | [license-url]: https://github.com/ShellWen/v8_killer/blob/master/LICENSE 117 | [linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=for-the-badge&logo=linkedin&colorB=555 118 | [linkedin-url]: https://linkedin.com/in/ShellWen 119 | 120 | 121 | 126 | 127 | [rust-badge]: https://img.shields.io/badge/Rust-000000?style=for-the-badge&logo=rust&logoColor=white 128 | [rust-url]: https://www.rust-lang.org/ 129 | [v8-badge]: https://img.shields.io/badge/V8-4B8BF5?style=for-the-badge&logo=v8&logoColor=white 130 | [v8-url]: https://v8.dev/ 131 | -------------------------------------------------------------------------------- /crates/core/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /Cargo.lock 3 | -------------------------------------------------------------------------------- /crates/core/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "v8_killer_core" 3 | version.workspace = true 4 | edition.workspace = true 5 | authors.workspace = true 6 | 7 | [lib] 8 | crate-type = ["cdylib"] 9 | 10 | [dependencies] 11 | ctor = "0.4" 12 | frida-gum = { version = "0.16", features = ["auto-download", "invocation-listener"] } 13 | once_cell = "1.21" 14 | regex = "1.10" 15 | serde = { version = "1.0", features = ["derive"] } 16 | toml = "0.8" 17 | tracing = { workspace = true } 18 | tracing-subscriber = { workspace = true, features = ["env-filter"] } 19 | 20 | [target.'cfg(target_os = "windows")'.dependencies] 21 | windows-sys = { version = "0.59", features = [ 22 | "Win32_Foundation", 23 | "Win32_System_Console", 24 | ] } 25 | -------------------------------------------------------------------------------- /crates/core/src/config.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | use std::fs::File; 3 | use std::io::Read; 4 | use std::path::Path; 5 | 6 | use serde::Deserialize; 7 | 8 | use crate::identifier::Identifiers; 9 | use crate::matcher::SourceMatcherEnum; 10 | use crate::processor::SourceProcessor; 11 | 12 | #[derive(Deserialize, Debug)] 13 | pub(crate) struct ConfigRule { 14 | pub(crate) matcher: Box, 15 | pub(crate) processors: Vec, 16 | } 17 | 18 | #[derive(Deserialize, Default, Debug)] 19 | pub(crate) struct Config { 20 | #[serde(default)] 21 | pub(crate) identifiers: Identifiers, 22 | pub(crate) rules: HashMap, 23 | } 24 | 25 | pub(crate) trait ReadFromFile { 26 | fn load_from_toml(file_path: &Path) -> Self; 27 | } 28 | 29 | impl ReadFromFile for Config { 30 | fn load_from_toml(file_path: &Path) -> Config { 31 | let mut file = File::open(file_path).expect("open config file failed"); 32 | let mut file_content = String::new(); 33 | file.read_to_string(&mut file_content) 34 | .expect("read config file failed"); 35 | toml::from_str(file_content.as_str()).expect("parse config file failed") 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /crates/core/src/core.rs: -------------------------------------------------------------------------------- 1 | use std::ops::Deref; 2 | 3 | use tracing::*; 4 | 5 | use crate::config::Config; 6 | use crate::matcher::SourceMatcher; 7 | use crate::source::Source; 8 | use crate::v8_sys::{ 9 | local_string_from_string, string_from_local_string, v8_context_get_isolate, V8Context, V8Source, 10 | }; 11 | 12 | pub(crate) unsafe fn process_script( 13 | config: &Config, 14 | v8_context: *const V8Context, 15 | v8_source: *mut V8Source, 16 | ) { 17 | let isolate = v8_context_get_isolate(v8_context); 18 | let resource_name = string_from_local_string(isolate, (*v8_source)._resource_name); 19 | let source_string = string_from_local_string(isolate, (*v8_source)._source_string); 20 | debug!("Processing source: {resource_name}"); 21 | let mut source = Source { 22 | resource_name, 23 | source_string, 24 | }; 25 | config.rules.iter().for_each(|rule_item| { 26 | let (rule_name, rule) = rule_item; 27 | let is_match = &rule.matcher.deref().matches(&source); 28 | if *is_match { 29 | info!("Rule {} matched in {}", rule_name, &source.resource_name); 30 | let processors = &rule.processors; 31 | processors.iter().for_each(|processor_item| { 32 | let processor = processor_item; 33 | let result = processor.process(&mut source); 34 | if result.is_err() { 35 | error!( 36 | "Processor {:#?} process failed: {}", 37 | processor, 38 | result.err().unwrap() 39 | ); 40 | }; 41 | }); 42 | } 43 | }); 44 | let processed_source_string = source.source_string.as_str(); 45 | let processed_local_string = 46 | local_string_from_string(isolate, processed_source_string.to_string()); 47 | (*v8_source)._source_string = processed_local_string; 48 | } 49 | -------------------------------------------------------------------------------- /crates/core/src/identifier.rs: -------------------------------------------------------------------------------- 1 | use crate::GUM; 2 | use frida_gum::{Module, NativePointer}; 3 | use serde::Deserialize; 4 | use tracing::debug; 5 | 6 | #[allow(non_snake_case)] 7 | #[derive(Debug)] 8 | pub(crate) struct Symbols { 9 | pub(crate) V8_SCRIPT_COMPILER_COMPILE_FUNCTION: Option, 10 | pub(crate) V8_STRING_UTF8LENGTH: Option, 11 | pub(crate) V8_STRING_WRITE_UTF8: Option, 12 | pub(crate) V8_CONTEXT_GET_ISOLATE: Option, 13 | pub(crate) V8_STRING_NEW_FROM_UTF8: Option, 14 | } 15 | 16 | // Bypass check for `Send` and `Sync` traits 17 | unsafe impl Sync for Symbols {} 18 | unsafe impl Send for Symbols {} 19 | 20 | impl Symbols { 21 | pub(crate) fn from_identifiers(identifiers: &Identifiers) -> Self { 22 | Symbols { 23 | V8_SCRIPT_COMPILER_COMPILE_FUNCTION: identifiers 24 | .V8_SCRIPT_COMPILER_COMPILE_FUNCTION 25 | .identify(), 26 | V8_STRING_UTF8LENGTH: identifiers.V8_STRING_UTF8LENGTH.identify(), 27 | V8_STRING_WRITE_UTF8: identifiers.V8_STRING_WRITE_UTF8.identify(), 28 | V8_CONTEXT_GET_ISOLATE: identifiers.V8_CONTEXT_GET_ISOLATE.identify(), 29 | V8_STRING_NEW_FROM_UTF8: identifiers.V8_STRING_NEW_FROM_UTF8.identify(), 30 | } 31 | } 32 | } 33 | 34 | #[allow(non_snake_case)] 35 | #[derive(Deserialize, Debug)] 36 | pub(crate) struct Identifiers { 37 | pub(crate) V8_SCRIPT_COMPILER_COMPILE_FUNCTION: Vec, 38 | pub(crate) V8_STRING_UTF8LENGTH: Vec, 39 | pub(crate) V8_STRING_WRITE_UTF8: Vec, 40 | pub(crate) V8_CONTEXT_GET_ISOLATE: Vec, 41 | pub(crate) V8_STRING_NEW_FROM_UTF8: Vec, 42 | } 43 | 44 | pub(crate) trait Identifier { 45 | fn identify(&self) -> Option; 46 | } 47 | 48 | impl Identifier for Vec { 49 | fn identify(&self) -> Option { 50 | self.iter() 51 | .find_map(|identifier| match identifier.identify() { 52 | Some(ptr) => { 53 | debug!("Identifier found: {:?}, by {:?}", ptr.0, identifier); 54 | Some(ptr) 55 | } 56 | None => None, 57 | }) 58 | } 59 | } 60 | 61 | #[derive(Deserialize, Debug)] 62 | #[serde(tag = "type")] 63 | pub(crate) enum IdentifierEnum { 64 | #[serde(rename = "symbol")] 65 | SymbolIdentifier(SymbolIdentifier), 66 | #[serde(rename = "rva")] 67 | RvaIdentifier(RvaIdentifier), 68 | } 69 | 70 | impl Identifier for IdentifierEnum { 71 | fn identify(&self) -> Option { 72 | match self { 73 | IdentifierEnum::SymbolIdentifier(identifier) => identifier.identify(), 74 | IdentifierEnum::RvaIdentifier(identifier) => identifier.identify(), 75 | } 76 | } 77 | } 78 | 79 | #[derive(Deserialize, Debug)] 80 | pub(crate) struct SymbolIdentifier { 81 | pub(crate) symbols: Vec, 82 | } 83 | 84 | impl Identifier for SymbolIdentifier { 85 | fn identify(&self) -> Option { 86 | for symbol in &self.symbols { 87 | let ptr = Module::find_global_export_by_name(symbol); 88 | if ptr.is_some() { 89 | return ptr; 90 | } 91 | } 92 | None 93 | } 94 | } 95 | 96 | #[derive(Deserialize, Debug)] 97 | pub(crate) struct RvaIdentifier { 98 | pub(crate) module_name: String, 99 | pub(crate) rva: usize, 100 | } 101 | 102 | impl Identifier for RvaIdentifier { 103 | fn identify(&self) -> Option { 104 | let m = Module::load(&GUM, self.module_name.as_str()); 105 | let base_address = m.range().base_address(); 106 | if base_address.is_null() { 107 | return None; 108 | } 109 | Some(NativePointer(unsafe { base_address.0.add(self.rva) })) 110 | } 111 | } 112 | 113 | impl Default for Identifiers { 114 | fn default() -> Self { 115 | Identifiers { 116 | V8_SCRIPT_COMPILER_COMPILE_FUNCTION: vec![ 117 | IdentifierEnum::SymbolIdentifier(SymbolIdentifier { 118 | symbols: vec![ 119 | "_ZN2v814ScriptCompiler23CompileFunctionInternalENS_5LocalINS_7ContextEEEPNS0_6SourceEmPNS1_INS_6StringEEEmPNS1_INS_6ObjectEEENS0_14CompileOptionsENS0_13NoCacheReasonEPNS1_INS_14ScriptOrModuleEEE" 120 | .to_string(), 121 | "?CompileFunctionInternal@ScriptCompiler@v8@@CA?AV?$MaybeLocal@VFunction@v8@@@2@V?$Local@VContext@v8@@@2@PEAVSource@12@_KQEAV?$Local@VString@v8@@@2@2QEAV?$Local@VObject@v8@@@2@W4CompileOptions@12@W4NoCacheReason@12@PEAV?$Local@VScriptOrModule@v8@@@2@@Z" 122 | .to_string(), 123 | // fallback for newer v8 versions 124 | "_ZN2v814ScriptCompiler15CompileFunctionENS_5LocalINS_7ContextEEEPNS0_6SourceEmPNS1_INS_6StringEEEmPNS1_INS_6ObjectEEENS0_14CompileOptionsENS0_13NoCacheReasonE".to_string(), 125 | "?CompileFunction@ScriptCompiler@v8@@SA?AV?$MaybeLocal@VFunction@v8@@@2@V?$Local@VContext@v8@@@2@PEAVSource@12@_KQEAV?$Local@VString@v8@@@2@2QEAV?$Local@VObject@v8@@@2@W4CompileOptions@12@W4NoCacheReason@12@@Z".to_string(), 126 | ], 127 | }) 128 | ], 129 | V8_STRING_UTF8LENGTH: vec![ 130 | IdentifierEnum::SymbolIdentifier(SymbolIdentifier { 131 | symbols: vec![ 132 | "_ZNK2v86String10Utf8LengthEPNS_7IsolateE".to_string(), 133 | "?Utf8Length@String@v8@@QEBAHPEAVIsolate@2@@Z".to_string(), 134 | ], 135 | } 136 | )], 137 | V8_STRING_WRITE_UTF8: vec![ 138 | IdentifierEnum::SymbolIdentifier(SymbolIdentifier { 139 | symbols: vec![ 140 | "_ZNK2v86String9WriteUtf8EPNS_7IsolateEPciPii".to_string(), 141 | "?WriteUtf8@String@v8@@QEBAHPEAVIsolate@2@PEADHPEAHH@Z".to_string(), 142 | ], 143 | } 144 | )], 145 | V8_CONTEXT_GET_ISOLATE: vec![ 146 | IdentifierEnum::SymbolIdentifier(SymbolIdentifier { 147 | symbols: vec![ 148 | "_ZN2v87Context10GetIsolateEv".to_string(), 149 | "?GetIsolate@Context@v8@@QEAAPEAVIsolate@2@XZ".to_string(), 150 | ], 151 | } 152 | )], 153 | V8_STRING_NEW_FROM_UTF8: vec![ 154 | IdentifierEnum::SymbolIdentifier(SymbolIdentifier { 155 | symbols: vec![ 156 | "_ZN2v86String11NewFromUtf8EPNS_7IsolateEPKcNS_13NewStringTypeEi".to_string(), 157 | "?NewFromUtf8@String@v8@@SA?AV?$MaybeLocal@VString@v8@@@2@PEAVIsolate@2@PEBDW4NewStringType@2@H@Z".to_string(), 158 | ], 159 | } 160 | )], 161 | } 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /crates/core/src/lib.rs: -------------------------------------------------------------------------------- 1 | use crate::config::{Config, ReadFromFile}; 2 | use crate::core::process_script; 3 | use crate::identifier::Symbols; 4 | use crate::pid_span::pid_span; 5 | use crate::v8_sys::{V8Context, V8Source}; 6 | use ctor::ctor; 7 | use frida_gum::interceptor::{InvocationContext, InvocationListener}; 8 | use frida_gum::{interceptor::Interceptor, Gum}; 9 | use once_cell::sync::Lazy; 10 | use std::path::Path; 11 | use tracing::level_filters::LevelFilter; 12 | use tracing::*; 13 | use tracing_subscriber::fmt::time::uptime; 14 | use tracing_subscriber::EnvFilter; 15 | 16 | mod config; 17 | mod core; 18 | mod identifier; 19 | mod matcher; 20 | mod pid_span; 21 | mod processor; 22 | mod source; 23 | mod v8_sys; 24 | 25 | static GUM: Lazy = Lazy::new(Gum::obtain); 26 | 27 | static CONFIG: Lazy = Lazy::new(|| { 28 | let config_file_path = std::env::var("V8_KILLER_CONFIG_FILE_PATH"); 29 | match config_file_path { 30 | Ok(config_file_path) => { 31 | debug!("V8_KILLER_CONFIG_FILE_PATH: {config_file_path}"); 32 | let path = Path::new(&config_file_path); 33 | let config = Config::load_from_toml(path); 34 | info!("Read config success"); 35 | debug!("Config: {config:#?}"); 36 | config 37 | } 38 | Err(_) => { 39 | warn!("V8_KILLER_CONFIG_FILE_PATH not found"); 40 | warn!("Please set V8_KILLER_CONFIG_FILE_PATH to config file path"); 41 | warn!("V8 Killer will only tracing source code without config file"); 42 | Default::default() 43 | } 44 | } 45 | }); 46 | 47 | static SYMBOLS: Lazy = Lazy::new(|| { 48 | let symbols = Symbols::from_identifiers(&CONFIG.identifiers); 49 | debug!("Symbols: {symbols:#?}"); 50 | symbols 51 | }); 52 | 53 | // v8::ScriptCompiler::CompileFunctionInternal(v8::Local, v8::ScriptCompiler::Source*, unsigned long, v8::Local*, unsigned long, v8::Local*, v8::ScriptCompiler::CompileOptions, v8::ScriptCompiler::NoCacheReason, v8::Local*) 54 | // fallback for newer v8 55 | // v8::ScriptCompiler::CompileFunction(v8::Local, v8::ScriptCompiler::Source*, unsigned long, v8::Local*, unsigned long, v8::Local*, v8::ScriptCompiler::CompileOptions, v8::ScriptCompiler::NoCacheReason) 56 | struct V8ScriptCompilerCompileFunctionListener; 57 | 58 | impl InvocationListener for V8ScriptCompilerCompileFunctionListener { 59 | fn on_enter(&mut self, frida_context: InvocationContext) { 60 | let pid_span = pid_span(); 61 | let _enter = pid_span.enter(); 62 | 63 | unsafe { 64 | #[cfg(any(target_os = "linux", target_os = "macos"))] 65 | let context = frida_context.arg(0) as *const V8Context; 66 | #[cfg(any(target_os = "linux", target_os = "macos"))] 67 | let source = frida_context.arg(1) as *mut V8Source; 68 | #[cfg(target_os = "windows")] 69 | let context = frida_context.arg(1) as *const V8Context; 70 | #[cfg(target_os = "windows")] 71 | let source = frida_context.arg(2) as *mut V8Source; 72 | process_script(&CONFIG, context, source); 73 | } 74 | } 75 | 76 | fn on_leave(&mut self, _frida_context: InvocationContext) {} 77 | } 78 | 79 | #[ctor] 80 | fn init() { 81 | let filter = EnvFilter::builder() 82 | .with_default_directive(LevelFilter::INFO.into()) 83 | .from_env_lossy(); 84 | 85 | tracing_subscriber::fmt() 86 | .with_timer(uptime()) 87 | .with_max_level(Level::DEBUG) 88 | .with_env_filter(filter) 89 | .init(); 90 | 91 | let pid_span = pid_span(); 92 | let _enter = pid_span.enter(); 93 | 94 | // Fix no output in the Windows GUI subsystem programs 95 | // See also: [#11](https://github.com/ShellWen/v8_killer/issues/11) 96 | #[cfg(target_os = "windows")] 97 | unsafe { 98 | use windows_sys::Win32::System::Console::{AttachConsole, ATTACH_PARENT_PROCESS}; 99 | 100 | AttachConsole(ATTACH_PARENT_PROCESS); 101 | } 102 | 103 | info!("V8 Killer has been injected and started!"); 104 | 105 | let mut interceptor = Interceptor::obtain(&GUM); 106 | 107 | interceptor.begin_transaction(); 108 | 109 | let v8_script_compiler_compile_function = SYMBOLS.V8_SCRIPT_COMPILER_COMPILE_FUNCTION; 110 | 111 | match v8_script_compiler_compile_function { 112 | None => { 113 | error!("v8_script_compiler_compile_function not found"); 114 | error!("source processing will not work properly"); 115 | } 116 | Some(addr) => { 117 | let mut v8_script_compiler_compile_function_listener = 118 | V8ScriptCompilerCompileFunctionListener; 119 | interceptor.attach(addr, &mut v8_script_compiler_compile_function_listener).map_err(|e| { 120 | error!( 121 | "Failed to attach V8ScriptCompilerCompileFunctionListener to v8_script_compiler_compile_function, error: {e}" 122 | ) 123 | }).unwrap(); 124 | } 125 | } 126 | 127 | interceptor.end_transaction(); 128 | } 129 | -------------------------------------------------------------------------------- /crates/core/src/matcher.rs: -------------------------------------------------------------------------------- 1 | use serde::Deserialize; 2 | use tracing::warn; 3 | 4 | use crate::source::Source; 5 | 6 | pub(crate) trait SourceMatcher { 7 | fn matches(&self, resource: &Source) -> bool; 8 | } 9 | 10 | #[derive(Deserialize, Debug)] 11 | #[serde(tag = "type")] 12 | pub(crate) enum SourceMatcherEnum { 13 | #[serde(rename = "resource-name-keyword")] 14 | ResourceNameKeyword(ResourceNameKeywordMatcher), 15 | #[serde(rename = "resource-name-regexp")] 16 | ResourceNameRegexp(ResourceNameRegexpMatcher), 17 | } 18 | 19 | impl SourceMatcher for SourceMatcherEnum { 20 | fn matches(&self, source: &Source) -> bool { 21 | match self { 22 | SourceMatcherEnum::ResourceNameKeyword(matcher) => matcher.matches(source), 23 | SourceMatcherEnum::ResourceNameRegexp(matcher) => matcher.matches(source), 24 | } 25 | } 26 | } 27 | 28 | #[derive(Deserialize, Debug)] 29 | pub struct ResourceNameKeywordMatcher { 30 | pub keyword: String, 31 | } 32 | 33 | impl SourceMatcher for ResourceNameKeywordMatcher { 34 | fn matches(&self, source: &Source) -> bool { 35 | source.resource_name.contains(&self.keyword) 36 | } 37 | } 38 | 39 | #[derive(Deserialize, Debug)] 40 | pub struct ResourceNameRegexpMatcher { 41 | pub regexp: String, 42 | } 43 | 44 | impl SourceMatcher for ResourceNameRegexpMatcher { 45 | fn matches(&self, source: &Source) -> bool { 46 | let re = regex::Regex::new(&self.regexp); 47 | match re { 48 | Ok(re) => re.is_match(&source.resource_name), 49 | Err(_) => { 50 | warn!("Invalid regexp: {}", &self.regexp); 51 | warn!("It will be ignored. Please check your config file"); 52 | false 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /crates/core/src/pid_span.rs: -------------------------------------------------------------------------------- 1 | use once_cell::sync::Lazy; 2 | use std::process; 3 | use tracing::{info_span, Span}; 4 | 5 | static PID_SPAN: Lazy = Lazy::new(|| { 6 | let pid = process::id(); 7 | #[cfg(not(target_os = "linux"))] 8 | let pid_span: Span = info_span!("process", pid); 9 | #[cfg(target_os = "linux")] 10 | let pid_span: Span = { 11 | fn read_host_pid() -> Option { 12 | let status = std::fs::read_to_string("/proc/self/status").ok()?; 13 | // format: 14 | // NSpid: 1381510 1 15 | let mut nspid_line = status 16 | .lines() 17 | .find(|line| line.starts_with("NSpid"))? 18 | .split_whitespace(); 19 | let nspid = nspid_line.nth(1)?.parse::().ok()?; 20 | // if ns pid is None, it will return None 21 | nspid_line.next()?; 22 | Some(nspid) 23 | } 24 | let host_pid = read_host_pid(); 25 | match host_pid { 26 | Some(host_pid) => info_span!("process", pid, host_pid, in_sandbox = true), 27 | None => info_span!("process", pid), 28 | } 29 | }; 30 | pid_span 31 | }); 32 | 33 | pub(crate) fn pid_span() -> Span { 34 | PID_SPAN.clone() 35 | } 36 | -------------------------------------------------------------------------------- /crates/core/src/processor.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::Error; 2 | 3 | use serde::Deserialize; 4 | 5 | use crate::source::Source; 6 | 7 | pub(crate) trait SourceProcessorTrait { 8 | fn process<'a>(&self, source: &'a mut Source) -> Result<&'a mut Source, Error>; 9 | } 10 | 11 | #[derive(Deserialize, Debug)] 12 | #[serde(tag = "type")] 13 | pub enum SourceProcessor { 14 | #[serde(rename = "insert-before")] 15 | InsertBefore(InsertBeforeProcessor), 16 | #[serde(rename = "insert-after")] 17 | InsertAfter(InsertAfterProcessor), 18 | #[serde(rename = "replace")] 19 | Replace(ReplaceProcessor), 20 | #[serde(rename = "replace-regexp")] 21 | ReplaceRegexp(ReplaceRegexpProcessor), 22 | } 23 | 24 | impl SourceProcessor { 25 | pub fn process<'a>(&self, source: &'a mut Source) -> Result<&'a mut Source, Error> { 26 | match self { 27 | SourceProcessor::InsertBefore(processor) => processor.process(source), 28 | SourceProcessor::InsertAfter(processor) => processor.process(source), 29 | SourceProcessor::Replace(processor) => processor.process(source), 30 | SourceProcessor::ReplaceRegexp(processor) => processor.process(source), 31 | } 32 | } 33 | } 34 | 35 | #[derive(Deserialize, Debug)] 36 | pub struct InsertBeforeProcessor { 37 | content: String, 38 | } 39 | 40 | impl SourceProcessorTrait for InsertBeforeProcessor { 41 | fn process<'a>(&self, source: &'a mut Source) -> Result<&'a mut Source, Error> { 42 | source.source_string = format!("{}{}", self.content, source.source_string); 43 | Ok(source) 44 | } 45 | } 46 | 47 | #[derive(Deserialize, Debug)] 48 | pub struct InsertAfterProcessor { 49 | content: String, 50 | } 51 | 52 | impl SourceProcessorTrait for InsertAfterProcessor { 53 | fn process<'a>(&self, source: &'a mut Source) -> Result<&'a mut Source, Error> { 54 | source.source_string = format!("{}{}", source.source_string, self.content); 55 | Ok(source) 56 | } 57 | } 58 | 59 | #[derive(Deserialize, Debug)] 60 | pub struct ReplaceProcessor { 61 | from: String, 62 | to: String, 63 | } 64 | 65 | impl SourceProcessorTrait for ReplaceProcessor { 66 | fn process<'a>(&self, source: &'a mut Source) -> Result<&'a mut Source, Error> { 67 | source.source_string = source.source_string.replace(&self.from, &self.to); 68 | Ok(source) 69 | } 70 | } 71 | 72 | #[derive(Deserialize, Debug)] 73 | pub struct ReplaceRegexpProcessor { 74 | regexp: String, 75 | to: String, 76 | } 77 | 78 | impl SourceProcessorTrait for ReplaceRegexpProcessor { 79 | fn process<'a>(&self, source: &'a mut Source) -> Result<&'a mut Source, Error> { 80 | let re = regex::Regex::new(&self.regexp).unwrap(); 81 | source.source_string = re.replace_all(&source.source_string, &self.to).to_string(); 82 | Ok(source) 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /crates/core/src/source.rs: -------------------------------------------------------------------------------- 1 | pub struct Source { 2 | pub resource_name: String, 3 | pub source_string: String, 4 | } 5 | 6 | impl Clone for Source { 7 | fn clone(&self) -> Self { 8 | Source { 9 | resource_name: self.resource_name.clone(), 10 | source_string: self.source_string.clone(), 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /crates/core/src/v8_sys.rs: -------------------------------------------------------------------------------- 1 | #![allow(non_camel_case_types)] 2 | 3 | use std::ffi::{c_char, c_int, c_void}; 4 | 5 | use crate::SYMBOLS; 6 | 7 | pub(crate) type V8Context = c_void; 8 | pub(crate) type V8Isolate = c_void; 9 | pub(crate) type V8String = c_void; 10 | pub(crate) type V8Local = *const T; 11 | 12 | #[repr(C)] 13 | #[derive(Debug)] 14 | pub(crate) struct V8Source { 15 | /* 16 | Local source_string; 17 | 18 | // Origin information 19 | Local resource_name; 20 | int resource_line_offset; 21 | int resource_column_offset; 22 | ScriptOriginOptions resource_options; 23 | Local source_map_url; 24 | Local host_defined_options; 25 | 26 | // Cached data from previous compilation (if a kConsume*Cache flag is 27 | // set), or hold newly generated cache data (kProduce*Cache flags) are 28 | // set when calling a compile method. 29 | std::unique_ptr cached_data; 30 | std::unique_ptr consume_cache_task; 31 | */ 32 | pub _source_string: V8Local, 33 | pub _resource_name: V8Local, 34 | pub _resource_line_offset: c_int, 35 | pub _resource_column_offset: c_int, 36 | pub _resource_options: c_int, 37 | pub _source_map_url: *const V8Local, 38 | pub _host_defined_options: *const c_void, 39 | pub _cached_data: *const c_void, 40 | pub _consume_cache_task: *const c_void, 41 | } 42 | 43 | type v8__Context__GetIsolate = unsafe extern "C" fn(context: *const V8Context) -> *const V8Isolate; 44 | type v8__String__Utf8Length = 45 | unsafe extern "C" fn(this: *const V8String, isolate: *const V8Isolate) -> usize; 46 | type v8__String__WriteUtf8 = unsafe extern "C" fn( 47 | this: *const V8String, 48 | isolate: *const V8Isolate, 49 | buffer: *mut c_char, 50 | length: c_int, 51 | nchars_ref: *mut usize, 52 | options: c_int, 53 | ) -> c_int; 54 | #[cfg(target_os = "linux")] 55 | type v8__String__NewFromUtf8 = unsafe extern "C" fn( 56 | isolate: *const V8Isolate, 57 | data: *const c_char, 58 | new_type: i32, 59 | length: i32, 60 | ) -> V8Local; 61 | #[cfg(target_os = "windows")] 62 | type v8__String__NewFromUtf8 = unsafe extern "C" fn( 63 | arg0: *const *mut c_void, 64 | isolate: *const V8Isolate, 65 | data: *const c_char, 66 | new_type: i32, 67 | length: i32, 68 | ) -> V8Local; 69 | #[cfg(target_os = "macos")] 70 | type v8__String__NewFromUtf8 = unsafe extern "C" fn( 71 | isolate: *const V8Isolate, 72 | data: *const c_char, 73 | new_type: i32, 74 | length: i32, 75 | ) -> V8Local; 76 | 77 | pub(crate) unsafe fn v8_context_get_isolate(context: *const V8Context) -> *const V8Isolate { 78 | let v8_context_get_isolate_ptr = SYMBOLS.V8_CONTEXT_GET_ISOLATE.unwrap(); 79 | let v8_context_get_isolate_func: v8__Context__GetIsolate = 80 | std::mem::transmute(v8_context_get_isolate_ptr.0); 81 | 82 | v8_context_get_isolate_func(context) 83 | } 84 | 85 | pub(super) unsafe fn v8_string_utf8_length( 86 | this: *const V8String, 87 | isolate: *const V8Isolate, 88 | ) -> usize { 89 | let v8_string_utf8_length_ptr = SYMBOLS.V8_STRING_UTF8LENGTH.unwrap(); 90 | let v8_string_utf8_length_func: v8__String__Utf8Length = 91 | std::mem::transmute(v8_string_utf8_length_ptr.0); 92 | 93 | v8_string_utf8_length_func(this, isolate) 94 | } 95 | 96 | pub(crate) unsafe fn v8_string_write_utf8( 97 | this: *const V8String, 98 | isolate: *const V8Isolate, 99 | buffer: *mut c_char, 100 | length: c_int, 101 | nchars_ref: *mut usize, 102 | options: c_int, 103 | ) -> c_int { 104 | let v8_string_write_utf8_ptr = SYMBOLS.V8_STRING_WRITE_UTF8.unwrap(); 105 | let v8_string_write_utf8_func: v8__String__WriteUtf8 = 106 | std::mem::transmute(v8_string_write_utf8_ptr.0); 107 | 108 | v8_string_write_utf8_func(this, isolate, buffer, length, nchars_ref, options) 109 | } 110 | 111 | pub(crate) unsafe fn v8_string_new_from_utf8( 112 | isolate: *const V8Isolate, 113 | data: *const c_char, 114 | new_type: i32, 115 | length: i32, 116 | ) -> V8Local { 117 | let v8_string_new_from_utf8_ptr = SYMBOLS.V8_STRING_NEW_FROM_UTF8.unwrap(); 118 | let v8_string_new_from_utf8_func: v8__String__NewFromUtf8 = 119 | std::mem::transmute(v8_string_new_from_utf8_ptr.0); 120 | 121 | #[cfg(any(target_os = "linux", target_os = "macos"))] 122 | { 123 | v8_string_new_from_utf8_func(isolate, data, new_type, length) 124 | } 125 | #[cfg(target_os = "windows")] 126 | { 127 | use std::ptr::null_mut; 128 | 129 | let mut arg0_value: *mut c_void = null_mut(); 130 | let arg0: *const *mut c_void = &mut arg0_value; 131 | v8_string_new_from_utf8_func(arg0, isolate, data, new_type, length); 132 | arg0_value 133 | } 134 | } 135 | 136 | pub(crate) fn string_from_local_string( 137 | isolate: *const V8Isolate, 138 | local_string: *const V8String, 139 | ) -> String { 140 | unsafe { 141 | let length = v8_string_utf8_length(local_string, isolate); 142 | // I don't know why +1 is needed, but without +1, it may SIGSEGV ¯\_(ツ)_/¯ 143 | // Anyway, it's not because of \0 144 | let mut buffer: Vec = vec![0; length + 1]; 145 | v8_string_write_utf8( 146 | local_string, 147 | isolate, 148 | buffer.as_mut_ptr(), 149 | -1, 150 | std::ptr::null_mut(), 151 | 0, 152 | ); 153 | std::ffi::CStr::from_ptr(buffer.as_ptr()) 154 | .to_str() 155 | .unwrap() 156 | .to_string() 157 | } 158 | } 159 | 160 | pub(crate) fn local_string_from_string( 161 | isolate: *const V8Isolate, 162 | string: String, 163 | ) -> V8Local { 164 | unsafe { 165 | let s_ptr = std::ffi::CString::new(string).unwrap().into_raw(); 166 | v8_string_new_from_utf8(isolate, s_ptr, 0, -1) 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /crates/launcher/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "launcher" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /crates/launcher/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "v8_killer_launcher" 3 | version.workspace = true 4 | edition.workspace = true 5 | authors.workspace = true 6 | 7 | [dependencies] 8 | clap = { workspace = true } 9 | tracing = { workspace = true } 10 | tracing-subscriber = { workspace = true, features = ["env-filter"] } 11 | 12 | [target.'cfg(target_os = "windows")'.dependencies] 13 | windows = { version = "0.61", features = [ 14 | "Win32_System_Threading", 15 | "Win32_System_Console", 16 | "Win32_System_Memory", 17 | "Win32_System_Diagnostics_Debug", 18 | "Win32_System_LibraryLoader", 19 | "Win32_Foundation", 20 | "Win32_Security", 21 | ] } 22 | -------------------------------------------------------------------------------- /crates/launcher/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::process::ExitStatus; 2 | 3 | pub fn default_lib_filename() -> &'static str { 4 | #[cfg(target_os = "linux")] 5 | return "libv8_killer_core.so"; 6 | 7 | #[cfg(target_os = "windows")] 8 | return "v8_killer_core.dll"; 9 | 10 | #[cfg(target_os = "macos")] 11 | return "libv8_killer_core.dylib"; 12 | 13 | // unsupported target_os leads to a compile-time error 14 | } 15 | 16 | #[cfg(target_os = "windows")] 17 | mod windows { 18 | use std::ffi::c_void; 19 | use std::os::windows::process::ExitStatusExt; 20 | use std::process::ExitStatus; 21 | use std::thread::sleep; 22 | use std::time::Duration; 23 | use tracing::*; 24 | use windows::core::PWSTR; 25 | use windows::core::{s, w}; 26 | use windows::Win32::Foundation::STILL_ACTIVE; 27 | use windows::Win32::System::Diagnostics::Debug::WriteProcessMemory; 28 | use windows::Win32::System::LibraryLoader::{GetModuleHandleW, GetProcAddress}; 29 | use windows::Win32::System::Memory::{VirtualAllocEx, MEM_COMMIT, MEM_RESERVE, PAGE_READWRITE}; 30 | use windows::Win32::System::Threading::GetExitCodeProcess; 31 | use windows::Win32::System::Threading::{ 32 | CreateProcessW, CreateRemoteThread, ResumeThread, WaitForSingleObject, CREATE_SUSPENDED, 33 | INFINITE, LPTHREAD_START_ROUTINE, PROCESS_INFORMATION, 34 | }; 35 | 36 | fn utf16_vec_from_str(str: String) -> Vec { 37 | let utf16 = str.encode_utf16().collect::>(); 38 | let mut ret = Vec::::with_capacity(utf16.len() + 1); 39 | ret.extend(utf16); 40 | ret.push(0u16); 41 | ret 42 | } 43 | 44 | fn get_pwstr_length(pwstr: PWSTR) -> usize { 45 | let ptr = pwstr.0; 46 | let mut len = 0usize; 47 | while unsafe { *ptr.add(len) } != 0 { 48 | len += 1; 49 | } 50 | len 51 | } 52 | 53 | pub(crate) fn launch_with_remote_thread_inject( 54 | executable: &str, 55 | args: &[&str], 56 | lib_path: &str, 57 | ) -> ExitStatus { 58 | let args_str: String = format!( 59 | "\"{}\" {}", 60 | executable, 61 | args.iter() 62 | .map(|arg| arg.to_string()) 63 | // .map(|arg| format!("\"{}\"", arg)) 64 | .collect::>() 65 | .join(" ") 66 | ); 67 | 68 | let mut args_utf16_vec = utf16_vec_from_str(args_str); 69 | let args_pwstr = PWSTR::from_raw(args_utf16_vec.as_mut_ptr()); 70 | let mut path_utf16_vec = utf16_vec_from_str(lib_path.to_string()); 71 | let path_pwstr = PWSTR::from_raw(path_utf16_vec.as_mut_ptr()); 72 | let path_utf16_zeroend_size = get_pwstr_length(path_pwstr) * 2 + 2; 73 | let mut process_info = PROCESS_INFORMATION::default(); 74 | debug!("Creating process."); 75 | unsafe { 76 | CreateProcessW( 77 | None, 78 | Some(args_pwstr), 79 | None, 80 | None, 81 | true, 82 | CREATE_SUSPENDED, 83 | None, 84 | None, 85 | &Default::default(), 86 | &mut process_info, 87 | ) 88 | .expect("CreateProcessW calling failed"); 89 | } 90 | info!("PID: {}", process_info.dwProcessId); 91 | debug!("Alloc core lib path memory."); 92 | let remote_lib_path_memory = unsafe { 93 | VirtualAllocEx( 94 | process_info.hProcess, 95 | None, 96 | path_utf16_zeroend_size, 97 | MEM_COMMIT | MEM_RESERVE, 98 | PAGE_READWRITE, 99 | ) 100 | }; 101 | assert!(!remote_lib_path_memory.is_null()); 102 | debug!( 103 | "Remote lib path memory Address: {:p}.", 104 | remote_lib_path_memory 105 | ); 106 | debug!("Writing core lib path to process."); 107 | unsafe { 108 | WriteProcessMemory( 109 | process_info.hProcess, 110 | remote_lib_path_memory, 111 | path_pwstr.0 as *const c_void, 112 | path_utf16_zeroend_size, 113 | None, 114 | ) 115 | .expect("WriteProcessMemory called failed"); 116 | } 117 | 118 | debug!("Getting LoadLibraryW address."); 119 | let kernel_handle = unsafe { GetModuleHandleW(w!("kernel32.dll")) }.unwrap(); 120 | // it means FARPROC but with a value, equivalent to FARPROC.unwrap() when FARPROC has a value 121 | #[allow(non_camel_case_types)] 122 | type FARPROC_Value = unsafe extern "system" fn() -> isize; 123 | let load_library_address: FARPROC_Value = 124 | unsafe { GetProcAddress(kernel_handle, s!("LoadLibraryW")) } 125 | .expect("GetProcAddress of LoadLibraryW failed"); 126 | debug!("Creating remote thread."); 127 | let load_remote_thread_handle = unsafe { 128 | CreateRemoteThread( 129 | process_info.hProcess, 130 | None, 131 | 0, 132 | LPTHREAD_START_ROUTINE::from(std::mem::transmute::< 133 | FARPROC_Value, 134 | unsafe extern "system" fn(*mut c_void) -> u32, 135 | >(load_library_address)), 136 | Some(remote_lib_path_memory), // LoadLibraryW(lpLibFileName) 137 | 0, 138 | None, 139 | ) 140 | } 141 | .unwrap(); 142 | info!("Core lib inject success. Waiting for thread end."); 143 | unsafe { 144 | WaitForSingleObject(load_remote_thread_handle, INFINITE); 145 | } 146 | info!("Thread ended. Resume original thread."); 147 | info!("--- Following is the original process output ---"); 148 | unsafe { 149 | ResumeThread(process_info.hThread); 150 | } 151 | unsafe { 152 | WaitForSingleObject(process_info.hProcess, INFINITE); 153 | } 154 | let mut exit_code: u32 = 0; 155 | loop { 156 | unsafe { 157 | GetExitCodeProcess(process_info.hProcess, &mut exit_code) 158 | .expect("GetExitCodeProcess failed"); 159 | } 160 | if exit_code != STILL_ACTIVE.0 as u32 { 161 | break; 162 | } 163 | warn!("Process is still running even after WaitForSingleObject. This should not happen. Waiting for 500ms."); 164 | sleep(Duration::from_millis(500)); // Why 500ms? Because I'm lazy 165 | } 166 | ExitStatus::from_raw(exit_code) 167 | } 168 | 169 | #[cfg(test)] 170 | mod tests { 171 | use super::*; 172 | 173 | #[test] 174 | fn utf16_vec_from_str_converts_ascii_string() { 175 | let input = String::from("hello"); 176 | let expected: [u16; 6] = [104, 101, 108, 108, 111, 0]; 177 | assert_eq!(utf16_vec_from_str(input), expected); 178 | } 179 | 180 | #[test] 181 | fn utf16_vec_from_str_converts_unicode_string() { 182 | let input = String::from("こんにちは"); 183 | let expected: [u16; 6] = [12371, 12435, 12395, 12385, 12399, 0]; 184 | assert_eq!(utf16_vec_from_str(input), expected); 185 | } 186 | 187 | #[test] 188 | fn utf16_vec_from_str_handles_empty_string() { 189 | let input = String::from(""); 190 | let expected: [u16; 1] = [0]; 191 | assert_eq!(utf16_vec_from_str(input), expected); 192 | } 193 | 194 | #[test] 195 | fn get_pwstr_length_calculates_correct_length() { 196 | let mut v = vec![104, 101, 108, 108, 111, 0]; 197 | let input = v.as_mut_slice(); 198 | let pwstr = PWSTR::from_raw(input.as_mut_ptr()); 199 | assert_eq!(get_pwstr_length(pwstr), 5); 200 | } 201 | 202 | #[test] 203 | fn get_pwstr_length_handles_empty_pwstr() { 204 | let mut v = vec![0]; 205 | let input = v.as_mut_slice(); 206 | let pwstr = PWSTR::from_raw(input.as_mut_ptr()); 207 | assert_eq!(get_pwstr_length(pwstr), 0); 208 | } 209 | 210 | #[test] 211 | fn get_pwstr_length_calculates_length_of_non_empty_pwstr() { 212 | let mut v = vec![104, 101, 108, 108, 111, 0]; 213 | let input = v.as_mut_slice(); 214 | let pwstr = PWSTR::from_raw(input.as_mut_ptr()); 215 | assert_eq!(get_pwstr_length(pwstr), 5); 216 | } 217 | 218 | #[test] 219 | fn get_pwstr_length_returns_zero_for_empty_pwstr() { 220 | let mut v = vec![0]; 221 | let input = v.as_mut_slice(); 222 | let pwstr = PWSTR::from_raw(input.as_mut_ptr()); 223 | assert_eq!(get_pwstr_length(pwstr), 0); 224 | } 225 | 226 | #[test] 227 | fn get_pwstr_length_handles_pwstr_with_only_null_terminator() { 228 | let mut v = vec![0, 0, 0]; 229 | let input = v.as_mut_slice(); 230 | let pwstr = PWSTR::from_raw(input.as_mut_ptr()); 231 | assert_eq!(get_pwstr_length(pwstr), 0); 232 | } 233 | 234 | #[test] 235 | fn get_pwstr_length_handles_pwstr_with_multiple_null_terminators() { 236 | let mut v = vec![104, 101, 108, 108, 111, 0, 0, 0]; 237 | let input = v.as_mut_slice(); 238 | let pwstr = PWSTR::from_raw(input.as_mut_ptr()); 239 | assert_eq!(get_pwstr_length(pwstr), 5); 240 | } 241 | } 242 | } 243 | 244 | #[cfg(any(target_os = "linux", target_os = "macos"))] 245 | mod linux_and_macos { 246 | use std::process::Command; 247 | use std::process::ExitStatus; 248 | use std::process::Stdio; 249 | 250 | pub(crate) fn launch_with_env( 251 | executable: &str, 252 | args: &[&str], 253 | env: &[(&str, &str)], 254 | ) -> ExitStatus { 255 | let mut command = Command::new(executable); 256 | command 257 | .args(args) 258 | .stdin(Stdio::inherit()) 259 | .stdout(Stdio::inherit()) 260 | .stderr(Stdio::inherit()); 261 | for (key, value) in env { 262 | command.env(key, value); 263 | } 264 | let mut child = command.spawn().expect("Failed to start command"); 265 | 266 | child.wait().expect("Failed to wait for child process") 267 | } 268 | } 269 | 270 | #[allow(unreachable_code)] 271 | pub fn launch(executable: &str, args: &[&str], lib_path: &str) -> ExitStatus { 272 | #[cfg(target_os = "windows")] 273 | { 274 | return windows::launch_with_remote_thread_inject(executable, args, lib_path); 275 | } 276 | #[cfg(target_os = "linux")] 277 | { 278 | return linux_and_macos::launch_with_env(executable, args, &[("LD_PRELOAD", lib_path)]); 279 | } 280 | #[cfg(target_os = "macos")] 281 | { 282 | return linux_and_macos::launch_with_env( 283 | executable, 284 | args, 285 | &[("DYLD_INSERT_LIBRARIES", lib_path)], 286 | ); 287 | } 288 | 289 | unreachable!("Unsupported platform."); 290 | } 291 | -------------------------------------------------------------------------------- /crates/launcher/src/main.rs: -------------------------------------------------------------------------------- 1 | use clap::*; 2 | use tracing::*; 3 | use tracing_subscriber::fmt::time::uptime; 4 | 5 | use std::env::current_exe; 6 | use std::process::exit; 7 | use tracing::level_filters::LevelFilter; 8 | use tracing_subscriber::EnvFilter; 9 | use v8_killer_launcher::{default_lib_filename, launch}; 10 | 11 | /// A simple launcher/injector for V8 Killer 12 | #[derive(Parser, Debug)] 13 | #[command(version, about, long_about = None)] 14 | struct Arguments { 15 | /// Custom dynamic library to inject 16 | #[arg(long)] 17 | lib_name: Option, 18 | /// Custom configuration file, will pass to the executable by environment variable `V8_KILLER_CONFIG_FILE_PATH` 19 | #[arg(long)] 20 | config: Option, 21 | /// The executable to launch and inject dynamic library 22 | executable: String, 23 | /// The arguments for the executable 24 | #[arg(last = true)] 25 | arguments: Vec, 26 | } 27 | 28 | fn main() { 29 | let filter = EnvFilter::builder() 30 | .with_default_directive(LevelFilter::INFO.into()) 31 | .from_env_lossy(); 32 | tracing_subscriber::fmt() 33 | .with_timer(uptime()) 34 | .with_env_filter(filter) 35 | .init(); 36 | let args = Arguments::parse(); 37 | if let Some(config) = &args.config { 38 | std::env::set_var("V8_KILLER_CONFIG_FILE_PATH", config); 39 | } 40 | let lib_filename = if let Some(lib_name) = args.lib_name { 41 | lib_name 42 | } else { 43 | default_lib_filename().to_owned() 44 | }; 45 | let lib_path = current_exe().unwrap().parent().unwrap().join(lib_filename); 46 | let lib_path_str = lib_path.to_str().unwrap(); 47 | 48 | info!("Executable: {}", args.executable); 49 | info!("Args: {:?}", args.arguments); 50 | info!("Core lib path: {}", lib_path_str); 51 | let command_args: Vec<&str> = args.arguments.iter().map(String::as_str).collect(); 52 | let exit_status = launch(&args.executable, command_args.as_slice(), lib_path_str); 53 | if exit_status.success() { 54 | info!("Process exited successfully"); 55 | } else { 56 | error!("Process exited with code: {:?}", exit_status.code()); 57 | exit(exit_status.code().unwrap_or(1)); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | /.venv/ 2 | /site/ 3 | -------------------------------------------------------------------------------- /docs/Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | url = "https://pypi.org/simple" 3 | verify_ssl = true 4 | name = "pypi" 5 | 6 | [packages] 7 | mkdocs = "~=1.6.1" 8 | mkdocs-material = "~=9.4.14" 9 | mkdocs-static-i18n = "~=1.2.3" 10 | 11 | [dev-packages] 12 | 13 | [requires] 14 | python_version = "3.13" 15 | -------------------------------------------------------------------------------- /docs/Pipfile.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_meta": { 3 | "hash": { 4 | "sha256": "88561c69da9387e16ba7b3a7bf9f31312c20e7273acc1c11f829b45660042602" 5 | }, 6 | "pipfile-spec": 6, 7 | "requires": { 8 | "python_version": "3.13" 9 | }, 10 | "sources": [ 11 | { 12 | "name": "pypi", 13 | "url": "https://pypi.org/simple", 14 | "verify_ssl": true 15 | } 16 | ] 17 | }, 18 | "default": { 19 | "babel": { 20 | "hashes": [ 21 | "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b", 22 | "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316" 23 | ], 24 | "markers": "python_version >= '3.8'", 25 | "version": "==2.16.0" 26 | }, 27 | "certifi": { 28 | "hashes": [ 29 | "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56", 30 | "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db" 31 | ], 32 | "markers": "python_version >= '3.6'", 33 | "version": "==2024.12.14" 34 | }, 35 | "charset-normalizer": { 36 | "hashes": [ 37 | "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537", 38 | "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa", 39 | "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a", 40 | "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294", 41 | "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b", 42 | "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", 43 | "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", 44 | "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd", 45 | "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4", 46 | "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", 47 | "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2", 48 | "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", 49 | "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd", 50 | "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", 51 | "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8", 52 | "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1", 53 | "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", 54 | "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496", 55 | "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d", 56 | "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", 57 | "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e", 58 | "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a", 59 | "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4", 60 | "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca", 61 | "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78", 62 | "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408", 63 | "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5", 64 | "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", 65 | "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", 66 | "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a", 67 | "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765", 68 | "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6", 69 | "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146", 70 | "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6", 71 | "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", 72 | "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd", 73 | "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c", 74 | "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", 75 | "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", 76 | "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176", 77 | "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770", 78 | "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824", 79 | "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f", 80 | "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf", 81 | "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487", 82 | "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d", 83 | "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd", 84 | "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", 85 | "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534", 86 | "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f", 87 | "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b", 88 | "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", 89 | "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd", 90 | "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125", 91 | "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9", 92 | "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de", 93 | "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", 94 | "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d", 95 | "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", 96 | "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f", 97 | "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", 98 | "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7", 99 | "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a", 100 | "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", 101 | "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8", 102 | "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41", 103 | "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", 104 | "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f", 105 | "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", 106 | "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", 107 | "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", 108 | "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77", 109 | "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76", 110 | "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247", 111 | "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", 112 | "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb", 113 | "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", 114 | "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e", 115 | "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6", 116 | "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037", 117 | "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", 118 | "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e", 119 | "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807", 120 | "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", 121 | "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c", 122 | "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12", 123 | "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3", 124 | "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089", 125 | "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", 126 | "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e", 127 | "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00", 128 | "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616" 129 | ], 130 | "markers": "python_version >= '3.7'", 131 | "version": "==3.4.1" 132 | }, 133 | "click": { 134 | "hashes": [ 135 | "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", 136 | "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a" 137 | ], 138 | "markers": "python_version >= '3.7'", 139 | "version": "==8.1.8" 140 | }, 141 | "colorama": { 142 | "hashes": [ 143 | "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", 144 | "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" 145 | ], 146 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", 147 | "version": "==0.4.6" 148 | }, 149 | "ghp-import": { 150 | "hashes": [ 151 | "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619", 152 | "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343" 153 | ], 154 | "version": "==2.1.0" 155 | }, 156 | "idna": { 157 | "hashes": [ 158 | "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", 159 | "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3" 160 | ], 161 | "markers": "python_version >= '3.6'", 162 | "version": "==3.10" 163 | }, 164 | "jinja2": { 165 | "hashes": [ 166 | "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb", 167 | "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb" 168 | ], 169 | "markers": "python_version >= '3.7'", 170 | "version": "==3.1.5" 171 | }, 172 | "markdown": { 173 | "hashes": [ 174 | "sha256:2ae2471477cfd02dbbf038d5d9bc226d40def84b4fe2986e49b59b6b472bbed2", 175 | "sha256:7eb6df5690b81a1d7942992c97fad2938e956e79df20cbc6186e9c3a77b1c803" 176 | ], 177 | "markers": "python_version >= '3.8'", 178 | "version": "==3.7" 179 | }, 180 | "markupsafe": { 181 | "hashes": [ 182 | "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", 183 | "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", 184 | "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0", 185 | "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", 186 | "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", 187 | "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13", 188 | "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", 189 | "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", 190 | "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", 191 | "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", 192 | "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0", 193 | "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b", 194 | "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579", 195 | "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", 196 | "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", 197 | "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff", 198 | "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", 199 | "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", 200 | "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", 201 | "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb", 202 | "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", 203 | "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", 204 | "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", 205 | "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", 206 | "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a", 207 | "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", 208 | "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8", 209 | "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", 210 | "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", 211 | "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144", 212 | "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f", 213 | "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", 214 | "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", 215 | "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", 216 | "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", 217 | "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158", 218 | "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", 219 | "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", 220 | "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", 221 | "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171", 222 | "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", 223 | "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", 224 | "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", 225 | "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d", 226 | "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", 227 | "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", 228 | "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", 229 | "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", 230 | "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29", 231 | "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", 232 | "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", 233 | "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c", 234 | "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", 235 | "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", 236 | "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", 237 | "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a", 238 | "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178", 239 | "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", 240 | "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", 241 | "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", 242 | "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50" 243 | ], 244 | "markers": "python_version >= '3.9'", 245 | "version": "==3.0.2" 246 | }, 247 | "mergedeep": { 248 | "hashes": [ 249 | "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8", 250 | "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307" 251 | ], 252 | "markers": "python_version >= '3.6'", 253 | "version": "==1.3.4" 254 | }, 255 | "mkdocs": { 256 | "hashes": [ 257 | "sha256:7b432f01d928c084353ab39c57282f29f92136665bdd6abf7c1ec8d822ef86f2", 258 | "sha256:db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e" 259 | ], 260 | "index": "pypi", 261 | "markers": "python_version >= '3.8'", 262 | "version": "==1.6.1" 263 | }, 264 | "mkdocs-get-deps": { 265 | "hashes": [ 266 | "sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c", 267 | "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134" 268 | ], 269 | "markers": "python_version >= '3.8'", 270 | "version": "==0.2.0" 271 | }, 272 | "mkdocs-material": { 273 | "hashes": [ 274 | "sha256:a511d3ff48fa8718b033e7e37d17abd9cc1de0fdf0244a625ca2ae2387e2416d", 275 | "sha256:dbc78a4fea97b74319a6aa9a2f0be575a6028be6958f813ba367188f7b8428f6" 276 | ], 277 | "index": "pypi", 278 | "markers": "python_version >= '3.8'", 279 | "version": "==9.4.14" 280 | }, 281 | "mkdocs-material-extensions": { 282 | "hashes": [ 283 | "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443", 284 | "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31" 285 | ], 286 | "markers": "python_version >= '3.8'", 287 | "version": "==1.3.1" 288 | }, 289 | "mkdocs-static-i18n": { 290 | "hashes": [ 291 | "sha256:7ccf4da6dd29570ec49cd863ebff6fef9cb82dbb1cb85249bdf744e8d839c914", 292 | "sha256:e6f2f3c53b657d7632015b32dea3c64d0b80a7a8d6cde0334ca8f66f9e33b52f" 293 | ], 294 | "index": "pypi", 295 | "markers": "python_version >= '3.8'", 296 | "version": "==1.2.3" 297 | }, 298 | "packaging": { 299 | "hashes": [ 300 | "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", 301 | "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f" 302 | ], 303 | "markers": "python_version >= '3.8'", 304 | "version": "==24.2" 305 | }, 306 | "paginate": { 307 | "hashes": [ 308 | "sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945", 309 | "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591" 310 | ], 311 | "version": "==0.5.7" 312 | }, 313 | "pathspec": { 314 | "hashes": [ 315 | "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", 316 | "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712" 317 | ], 318 | "markers": "python_version >= '3.8'", 319 | "version": "==0.12.1" 320 | }, 321 | "platformdirs": { 322 | "hashes": [ 323 | "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907", 324 | "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb" 325 | ], 326 | "markers": "python_version >= '3.8'", 327 | "version": "==4.3.6" 328 | }, 329 | "pygments": { 330 | "hashes": [ 331 | "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", 332 | "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c" 333 | ], 334 | "markers": "python_version >= '3.8'", 335 | "version": "==2.19.1" 336 | }, 337 | "pymdown-extensions": { 338 | "hashes": [ 339 | "sha256:202481f716cc8250e4be8fce997781ebf7917701b59652458ee47f2401f818b5", 340 | "sha256:741bd7c4ff961ba40b7528d32284c53bc436b8b1645e8e37c3e57770b8700a34" 341 | ], 342 | "markers": "python_version >= '3.8'", 343 | "version": "==10.14" 344 | }, 345 | "python-dateutil": { 346 | "hashes": [ 347 | "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", 348 | "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427" 349 | ], 350 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", 351 | "version": "==2.9.0.post0" 352 | }, 353 | "pyyaml": { 354 | "hashes": [ 355 | "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff", 356 | "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", 357 | "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", 358 | "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e", 359 | "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", 360 | "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", 361 | "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", 362 | "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", 363 | "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", 364 | "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", 365 | "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a", 366 | "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", 367 | "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", 368 | "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8", 369 | "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", 370 | "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19", 371 | "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", 372 | "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a", 373 | "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", 374 | "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", 375 | "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", 376 | "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631", 377 | "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d", 378 | "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", 379 | "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", 380 | "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", 381 | "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", 382 | "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", 383 | "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", 384 | "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706", 385 | "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", 386 | "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", 387 | "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", 388 | "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083", 389 | "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", 390 | "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", 391 | "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", 392 | "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f", 393 | "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725", 394 | "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", 395 | "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", 396 | "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", 397 | "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", 398 | "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", 399 | "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5", 400 | "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d", 401 | "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290", 402 | "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", 403 | "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", 404 | "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", 405 | "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", 406 | "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12", 407 | "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4" 408 | ], 409 | "markers": "python_version >= '3.8'", 410 | "version": "==6.0.2" 411 | }, 412 | "pyyaml-env-tag": { 413 | "hashes": [ 414 | "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb", 415 | "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069" 416 | ], 417 | "markers": "python_version >= '3.6'", 418 | "version": "==0.1" 419 | }, 420 | "regex": { 421 | "hashes": [ 422 | "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c", 423 | "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60", 424 | "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d", 425 | "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d", 426 | "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67", 427 | "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773", 428 | "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0", 429 | "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef", 430 | "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad", 431 | "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe", 432 | "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3", 433 | "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114", 434 | "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4", 435 | "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39", 436 | "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e", 437 | "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3", 438 | "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7", 439 | "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d", 440 | "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e", 441 | "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a", 442 | "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7", 443 | "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f", 444 | "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0", 445 | "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54", 446 | "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b", 447 | "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c", 448 | "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd", 449 | "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57", 450 | "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34", 451 | "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d", 452 | "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f", 453 | "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b", 454 | "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519", 455 | "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4", 456 | "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a", 457 | "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638", 458 | "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b", 459 | "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839", 460 | "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07", 461 | "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf", 462 | "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff", 463 | "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0", 464 | "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f", 465 | "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95", 466 | "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4", 467 | "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e", 468 | "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13", 469 | "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519", 470 | "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2", 471 | "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008", 472 | "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9", 473 | "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc", 474 | "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48", 475 | "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20", 476 | "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89", 477 | "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e", 478 | "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf", 479 | "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b", 480 | "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd", 481 | "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84", 482 | "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29", 483 | "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b", 484 | "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3", 485 | "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45", 486 | "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3", 487 | "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983", 488 | "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e", 489 | "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7", 490 | "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4", 491 | "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e", 492 | "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467", 493 | "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577", 494 | "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001", 495 | "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0", 496 | "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55", 497 | "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9", 498 | "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf", 499 | "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6", 500 | "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e", 501 | "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde", 502 | "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62", 503 | "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df", 504 | "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51", 505 | "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5", 506 | "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86", 507 | "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2", 508 | "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2", 509 | "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0", 510 | "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c", 511 | "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f", 512 | "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6", 513 | "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2", 514 | "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9", 515 | "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91" 516 | ], 517 | "markers": "python_version >= '3.8'", 518 | "version": "==2024.11.6" 519 | }, 520 | "requests": { 521 | "hashes": [ 522 | "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", 523 | "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6" 524 | ], 525 | "markers": "python_version >= '3.8'", 526 | "version": "==2.32.3" 527 | }, 528 | "six": { 529 | "hashes": [ 530 | "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", 531 | "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81" 532 | ], 533 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", 534 | "version": "==1.17.0" 535 | }, 536 | "urllib3": { 537 | "hashes": [ 538 | "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", 539 | "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d" 540 | ], 541 | "markers": "python_version >= '3.9'", 542 | "version": "==2.3.0" 543 | }, 544 | "watchdog": { 545 | "hashes": [ 546 | "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", 547 | "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", 548 | "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", 549 | "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", 550 | "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", 551 | "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c", 552 | "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0", 553 | "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", 554 | "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", 555 | "sha256:7a0e56874cfbc4b9b05c60c8a1926fedf56324bb08cfbc188969777940aef3aa", 556 | "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", 557 | "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", 558 | "sha256:90c8e78f3b94014f7aaae121e6b909674df5b46ec24d6bebc45c44c56729af2a", 559 | "sha256:9513f27a1a582d9808cf21a07dae516f0fab1cf2d7683a742c498b93eedabb11", 560 | "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", 561 | "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", 562 | "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", 563 | "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c", 564 | "sha256:bc64ab3bdb6a04d69d4023b29422170b74681784ffb9463ed4870cf2f3e66112", 565 | "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948", 566 | "sha256:c7ac31a19f4545dd92fc25d200694098f42c9a8e391bc00bdd362c5736dbf881", 567 | "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860", 568 | "sha256:c897ac1b55c5a1461e16dae288d22bb2e412ba9807df8397a635d88f671d36c3", 569 | "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", 570 | "sha256:d1cdb490583ebd691c012b3d6dae011000fe42edb7a82ece80965b42abd61f26", 571 | "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", 572 | "sha256:e6439e374fc012255b4ec786ae3c4bc838cd7309a540e5fe0952d03687d8804e", 573 | "sha256:e6f0e77c9417e7cd62af82529b10563db3423625c5fce018430b249bf977f9e8", 574 | "sha256:e7631a77ffb1f7d2eefa4445ebbee491c720a5661ddf6df3498ebecae5ed375c", 575 | "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2" 576 | ], 577 | "markers": "python_version >= '3.9'", 578 | "version": "==6.0.0" 579 | } 580 | }, 581 | "develop": {} 582 | } 583 | -------------------------------------------------------------------------------- /docs/docs/development.en.md: -------------------------------------------------------------------------------- 1 | ## Build 2 | TODO 3 | -------------------------------------------------------------------------------- /docs/docs/development.zh.md: -------------------------------------------------------------------------------- 1 | ## 构建 2 | 3 | 待更新 4 | -------------------------------------------------------------------------------- /docs/docs/getting-started.en.md: -------------------------------------------------------------------------------- 1 | This document assumes that you are already familiar with the related basic knowledge. 2 | 3 | ## Structure 4 | V8 Killer consists of a `core` part and a `launcher` part. 5 | The former part runs inside the target process and inline hooks the V8 engine's compilation-related functions when the module is loaded. The latter is responsible for starting the program and loading the `core` into the target program. 6 | 7 | ## Obtain Binary Files 8 | 9 | [//]: # (At present, we provide pre-built versions, released on [GitHub Releases][github-releases-url]{target=\_blank}) 10 | 11 | At present, we do not provide pre-built versions, but you can find continuously built binary files in [GitHub Actions][github-actions-build-url]{target=\_blank}. 12 | If you need to build it yourself, please refer to [Development](development.md). 13 | 14 | ## Writing Configuration Files 15 | 16 | The configuration file is a [TOML][toml-url]{target=\_blank} file, which includes function locators and injection rules. 17 | At present, we have not yet provided a JSON Schema for TOML files. Please refer to the example files given in [/examples/configs][config-examples-url]{target=\_blank}. 18 | 19 | ## Using the Launcher 20 | 21 | The launcher will look for the configuration file based on environment variables. You need to set the `V8_KILLER_CONFIG_FILE_PATH` environment variable and point its value to the **absolute path** of the configuration file. 22 | 23 | ### Linux / macOS 24 | Here is an example script that has been tested on Arch Linux: 25 | ```bash 26 | #!/usr/bin/env bash 27 | export V8_KILLER_CONFIG_FILE_PATH=/path/to/config/file/config.toml 28 | v8_killer_launcher "/usr/bin/node" "/path/to/js/main.js" 29 | ``` 30 | 31 | ### Windows 32 | You can use `PowerShell` scripts or `cmd` batch files to start the launcher: 33 | ```powershell 34 | # PowerShell 35 | $env:V8_KILLER_CONFIG_FILE_PATH = "C:\path\to\config\file\config.toml" 36 | Start-Process -FilePath "C:\path\to\executable\node.exe" -ArgumentList "C:\path\to\js\main.js" -NoNewWindow 37 | ``` 38 | ```batch 39 | :: cmd 40 | set V8_KILLER_CONFIG_FILE_PATH=C:\path\to\config\file\config.toml 41 | start "C:\path\to\executable\node.exe" "C:\path\to\js\main.js" 42 | ``` 43 | Please note that in Windows, it is allowed to configure global environment variables, but we don't need to do so. We only need to set temporary environment variables in the script. 44 | 45 | [toml-url]: https://toml.io/ 46 | [github-releases-url]: https://github.com/ShellWen/v8_killer/releases 47 | [github-actions-build-url]: https://github.com/ShellWen/v8_killer/actions/workflows/build.yaml 48 | [config-examples-url]: https://github.com/ShellWen/v8_killer/tree/master/examples/configs -------------------------------------------------------------------------------- /docs/docs/getting-started.zh.md: -------------------------------------------------------------------------------- 1 | 本文假设你已经对相关的基础知识有所了解。 2 | 3 | ## 结构 4 | V8 Killer 分为 `core` 核心部分,与 `launcher` 启动器部分。 5 | 前者为运行在目标进程中的部分,会在模块加载的时候 inline hook V8 引擎的编译相关函数,后者负责启动程序并将 `core` 加载进目标程序。 6 | 7 | ## 获取二进制文件 8 | 9 | [//]: # (目前,我们提供预构建版本,发布在 [GitHub Releases][github-releases-url]{target=\_blank} 中) 10 | 11 | 目前,我们不提供预构建版本,但你可以在 [GitHub Actions][github-actions-build-url]{target=\_blank} 中找到持续构建的二进制文件。 12 | 如需自行构建,请参考 [开发](development.md)。 13 | 14 | ## 编写配置文件 15 | 16 | 配置文件是一个 [TOML][toml-url]{target=\_blank} 文件,其中包括了函数定位器与注入规则。 17 | 我们目前暂时还未提供 TOML 文件的 JSON Schema,请参考 [/examples/configs][config-examples-url]{target=\_blank} 中给出的示例文件编写。 18 | 19 | ## 使用启动器启动 20 | 21 | 启动器会根据环境变量查找配置文件,你需要设置 `V8_KILLER_CONFIG_FILE_PATH` 环境变量,并将它的值指向配置文件的**绝对路径**。 22 | 23 | ### Linux / macOS 24 | 这是一段示例脚本,已在 Arch Linux 下测试通过: 25 | ```bash 26 | #!/usr/bin/env bash 27 | export V8_KILLER_CONFIG_FILE_PATH=/path/to/config/file/config.toml 28 | v8_killer_launcher "/usr/bin/node" "/path/to/js/main.js" 29 | ``` 30 | 31 | ### Windows 32 | 你可以通过 `PowerShell` 脚本,或 `cmd` 批处理启动 `launcher`: 33 | ```powershell 34 | # PowerShell 35 | $env:V8_KILLER_CONFIG_FILE_PATH = "C:\path\to\config\file\config.toml" 36 | Start-Process -FilePath "C:\path\to\executable\node.exe" -ArgumentList "C:\path\to\js\main.js" -NoNewWindow 37 | ``` 38 | ```batch 39 | :: cmd 40 | set V8_KILLER_CONFIG_FILE_PATH=C:\path\to\config\file\config.toml 41 | start "C:\path\to\executable\node.exe" "C:\path\to\js\main.js" 42 | ``` 43 | 请注意,在 Windows 中,允许配置全局环境变量,但我们不需要这么做,我们只需要在脚本中设置临时环境变量即可。 44 | 45 | [toml-url]: https://toml.io/ 46 | [github-releases-url]: https://github.com/ShellWen/v8_killer/releases 47 | [github-actions-build-url]: https://github.com/ShellWen/v8_killer/actions/workflows/build.yaml 48 | [config-examples-url]: https://github.com/ShellWen/v8_killer/tree/master/examples/configs 49 | -------------------------------------------------------------------------------- /docs/docs/index.en.md: -------------------------------------------------------------------------------- 1 | # V8 Killer 2 | 3 | A **powerful** and highly **customizable** **universal** V8 virtual machine injector. 4 | 5 | [![Contributors][contributors-shield]][contributors-url]{target=\_blank} 6 | [![Forks][forks-shield]][forks-url]{target=\_blank} 7 | [![Stargazers][stars-shield]][stars-url]{target=\_blank} 8 | [![Issues][issues-shield]][issues-url]{target=\_blank} 9 | [![MIT License][license-shield]][license-url]{target=\_blank} 10 | [![LinkedIn][linkedin-shield]][linkedin-url]{target=\_blank} 11 | [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/O5O4RNVHA){target=\_blank} 12 | 13 | ## What is V8 Killer 14 | 15 | This project ([V8 Killer][project-url]{target=\_blank}) developed by [ShellWen][shellwen-github-url]{target=\_blank} is 16 | a general script injection scheme for [V8 engine][v8-url]{target=\_blank}. 17 | Currently, we are mainly focusing on solving the injection problems of [Electron][electron-url]{target=\_blank} 18 | programs. 19 | 20 | ## Comparison of Electron Injection Solutions 21 | 22 | There are several common Electron injection solutions at present: 23 | 24 | | | Enable Debugging Port | Replacing Resource Files | V8 Killer | 25 | |------------------------------------|--------------------------------------------------------------------------------------|-------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------| 26 | | Principle | Enable Devtools debugging port by special command-line parameters or runtime signals | Replace scripts files / asar resource packages stored on disk | Inject dynamic link libraries inline hook after program runs, modify the logic of V8 engine script compilation | 27 | | Can pass integrity checks | ✅ | ❌ The modification of files will cause the digest value to change | ✅ | 28 | | No security issues | ❌ The debugging port cannot be protected, any program can be injected | ✅ | ✅ The contents of the injection are specified by the configuration file and do not expose the attack surface | 29 | | No need to re-adapt after updating | ✅ | ❌ | ⭕ Only need on Windows platform | 30 | | Allows modification of any script | ❌ | ✅ Supports substitution of original scripts | ✅ Supports substitution or **modification** of original scripts | 31 | 32 | Currently, V8 Killer is the only universal injection solution that won't break the integrity of Electron programs. 33 | 34 | The main disadvantages of V8 Killer: 35 | 36 | - For Electron builds under Windows platform, some symbol export information is removed by default, so you need to 37 | reverse and fill in the EVA of relevant functions yourself; 38 | - Some Electron programs may check the list of dynamically linked libraries loaded in memory, which may lead V8 Killer 39 | to be discovered in the target program. 40 | 41 | ## Getting Started 42 | 43 | Please go to [Getting Started](getting-started.md). 44 | 45 | ## Contribution 46 | 47 | If you find flaws / Bugs in the code, we welcome you to submit them to us via [GitHub Issues][issues-url]{target=\_blank}, or directly submit solutions to us through [GitHub Pull Requests][pull-requests-url]{target=\_blank}. 48 | If the existing code does not meet your needs, or if you have any new ideas, you can also tell us 49 | via [GitHub Issues][issues-url]{target=\_blank}, but we need to point out that the time of project maintainer is 50 | limited, we may not always be able to satisfy you. 51 | The translation of documents may be delayed or errors may occur due to negligence. If this happens, please report them to us via [GitHub Issues][issues-url]{target=\_blank}. 52 | If you know 53 | about Rust and hope to participate in the development of this project, please go to [Development](development.md). 54 | 55 | ## Community 56 | 57 | If you encounter problems while using V8 Killer, please go to our discussion page [GitHub Discussions][discussions-url]{target=\_blank}. 58 | 59 | **Please note: GitHub Issues are only used to submit code defects / Bugs, please do not post usage issues to Issues, 60 | which would distract developers.** 61 | 62 | ## User Notice & Disclaimer 63 | 64 | This project is only for learning and communication purposes, it is forbidden to use it for illegal purposes, or you 65 | will bear the consequences. 66 | This project does not contain any explicit or implied warranties for any purpose, and the 67 | contributors of this project are not responsible for any direct or indirect losses caused by anyone using this project. 68 | The users of this project must read this statement carefully while complying with the open source license. 69 | 70 | ## Technology Stack 71 | 72 | This project uses some open source code from the community, we would like to express our sincere gratitude to these 73 | contributors: 74 | 75 | - [frida-rust](https://github.com/frida/frida-rust){target=\_blank} 76 | - [lazy_static.rs](https://github.com/rust-lang-nursery/lazy-static.rs){target=\_blank} 77 | - [rust-ctor](https://github.com/mmastrac/rust-ctor){target=\_blank} 78 | - [toml-rs](https://github.com/toml-rs/toml){target=\_blank} 79 | - [serde-rs](https://github.com/serde-rs/serde){target=\_blank} 80 | 81 | Without their contributions, this project would not have been successfully completed. 82 | Thanks again for their contributions to the open source community. 83 | 84 | ## Licensing Agreement 85 | 86 | This project follows the MIT licensing agreement. 87 | For specifics, see the [LICENSE file][license-url]{target=\_blank} in the project root directory. 88 | 89 | [shellwen-github-url]: https://github.com/ShellWen 90 | [project-url]: https://github.com/ShellWen/v8_killer 91 | [contributors-shield]: https://img.shields.io/github/contributors/ShellWen/v8_killer.svg?style=for-the-badge 92 | [contributors-url]: https://github.com/ShellWen/v8_killer/graphs/contributors 93 | [forks-shield]: https://img.shields.io/github/forks/ShellWen/v8_killer.svg?style=for-the-badge 94 | [forks-url]: https://github.com/ShellWen/v8_killer/network/members 95 | [stars-shield]: https://img.shields.io/github/stars/ShellWen/v8_killer.svg?style=for-the-badge 96 | [stars-url]: https://github.com/ShellWen/v8_killer/stargazers 97 | [issues-shield]: https://img.shields.io/github/issues/ShellWen/v8_killer.svg?style=for-the-badge 98 | [issues-url]: https://github.com/ShellWen/v8_killer/issues 99 | [pull-requests-url]: https://github.com/ShellWen/v8_killer/pulls 100 | [license-shield]: https://img.shields.io/github/license/ShellWen/v8_killer.svg?style=for-the-badge 101 | [license-url]: https://github.com/ShellWen/v8_killer/blob/master/LICENSE 102 | [linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=for-the-badge&logo=linkedin&colorB=555 103 | [linkedin-url]: https://linkedin.com/in/ShellWen 104 | 105 | [rust-badge]: https://img.shields.io/badge/Rust-000000?style=for-the-badge&logo=rust&logoColor=white 106 | [rust-url]: https://www.rust-lang.org/ 107 | [v8-badge]: https://img.shields.io/badge/V8-4B8BF5?style=for-the-badge&logo=v8&logoColor=white 108 | [v8-url]: https://v8.dev/ 109 | 110 | [electron-url]: https://github.com/electron/electron 111 | 112 | [discussions-url]: https://github.com/ShellWen/v8_killer/discussions 113 | -------------------------------------------------------------------------------- /docs/docs/index.zh.md: -------------------------------------------------------------------------------- 1 | # V8 Killer 2 | **强大**且可高度**自定义**的**通用** V8 虚拟机注入器。 3 | 4 | [![Contributors][contributors-shield]][contributors-url]{target=\_blank} 5 | [![Forks][forks-shield]][forks-url]{target=\_blank} 6 | [![Stargazers][stars-shield]][stars-url]{target=\_blank} 7 | [![Issues][issues-shield]][issues-url]{target=\_blank} 8 | [![MIT License][license-shield]][license-url]{target=\_blank} 9 | [![LinkedIn][linkedin-shield]][linkedin-url]{target=\_blank} 10 | [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/O5O4RNVHA){target=\_blank} 11 | 12 | ## V8 Killer 是什么 13 | 14 | 该项目 ([V8 Killer][project-url]{target=\_blank}) 是由 [ShellWen][shellwen-github-url]{target=\_blank} 开发的 [V8 引擎][v8-url]{target=\_blank} 15 | 通用脚本注入方案,目前我们主要致力于解决 [Electron][electron-url]{target=\_blank} 程序的注入问题。 16 | 17 | ## Electron 注入方案比较 18 | 19 | 目前常见的 Electron 注入方案有以下几种: 20 | 21 | | | 开启调试端口 | 替换资源文件 | V8 Killer | 22 | |-------------|------------------------------------|--------------------------|-------------------------------------------| 23 | | 原理 | 通过特殊的命令行参数或运行时发送信号开启 Devtools 调试端口 | 替换存储在硬盘上的脚本文件 / asar 资源包 | 在程序运行后注入动态链接库 inline hook,修改 V8 引擎编译脚本的逻辑 | 24 | | 可通过完整性检查 | ✅ | ❌ 修改文件会导致文件摘要值改变 | ✅ | 25 | | 无安全性问题 | ❌ 调试端口无法添加保护,任何程序均可注入 | ✅ | ✅ 注入内容由配置文件指定,不对外暴露攻击面 | 26 | | 更新版本后无需重新适配 | ✅ | ❌ | ⭕ 一般仅 Windows 平台需要 | 27 | | 允许修改任意脚本 | ❌ | ✅ 支持对原脚本替换 | ✅ 支持对原脚本替换或**修改** | 28 | 29 | 目前 V8 Killer 是唯一一个通用且不会破坏 Electron 程序完整性的注入方案。 30 | 31 | V8 Killer 的缺点主要集中在以下几点: 32 | 33 | - Windows 平台下的 Electron 构建,默认会移除部分符号导出信息,所以需要自行逆向后填写相关函数的 EVA; 34 | - 部分 Electron 程序可能会检查内存中加载的动态链接库列表,这会使得 V8 Killer 在目标程序中被发现。 35 | 36 | ## 开始使用 37 | 请转到 [开始使用](getting-started.md)。 38 | 39 | ## 贡献 40 | 41 | 如果你发现了代码中存在的缺陷 / Bugs,欢迎你通过 [GitHub Issues][issues-url]{target=\_blank} 提交给我们,或是直接通过 42 | [GitHub Pull Requests][pull-requests-url]{target=\_blank} 将解决方案提交给我们。 43 | 如果现有的代码无法满足你的需求,或是你有什么新的创意,你也可以通过 [GitHub Issues][issues-url]{target=\_blank} 告诉我们,但 44 | 需要说明的是,项目维护者的精力有限,我们可能无法总是让你满意。 45 | 文档翻译可能存在滞后性,也可能因疏忽而发生错误,如果遇到这种情况,烦请通过 [GitHub Issues][issues-url]{target=\_blank} 提交给我们。 46 | 如果你对 Rust 有所了解,同时希望参与该项目的开发之中,请转到 [开发](development.md)。 47 | 48 | ## 社区 49 | 50 | 如果你在使用 V8 Killer 的时候碰到问题,请前往我们的讨论页 [GitHub Discussions][discussions-url]{target=\_blank}。 51 | 52 | **请注意:GitHub Issues 仅用于提交代码缺陷 / Bugs,请不要把使用中的问题发到 Issues,这会分散开发人员的精力。** 53 | 54 | ## 使用须知 & 免责声明 55 | 56 | 该项目仅供学习交流使用,禁止用于非法用途,否则后果自负。 57 | 该项目不包含任何明示或暗示的用于任何目的的担保,本项目及其贡献者不对任何人使用本项目产生的任何直接或间接损失负责。 58 | 该项目的使用者必须在遵守开源许可证的同时,仔细阅读并遵守本声明。 59 | 60 | ## 技术栈 61 | 62 | 该项目使用了一些来自社区的开源代码,我们对这些贡献者表示由衷的感谢: 63 | 64 | - [frida-rust](https://github.com/frida/frida-rust){target=\_blank} 65 | - [lazy_static.rs](https://github.com/rust-lang-nursery/lazy-static.rs){target=\_blank} 66 | - [rust-ctor](https://github.com/mmastrac/rust-ctor){target=\_blank} 67 | - [toml-rs](https://github.com/toml-rs/toml){target=\_blank} 68 | - [serde-rs](https://github.com/serde-rs/serde){target=\_blank} 69 | 70 | 没有他们的贡献,该项目便无法顺利完成。再次感谢他们对开源界的贡献。 71 | 72 | ## 许可协议 73 | 74 | 该项目遵循 MIT 许可协议。具体请见项目根目录下的 [LICENSE 文件][license-url]{target=\_blank}。 75 | 76 | [shellwen-github-url]: https://github.com/ShellWen 77 | [project-url]: https://github.com/ShellWen/v8_killer 78 | [contributors-shield]: https://img.shields.io/github/contributors/ShellWen/v8_killer.svg?style=for-the-badge 79 | [contributors-url]: https://github.com/ShellWen/v8_killer/graphs/contributors 80 | [forks-shield]: https://img.shields.io/github/forks/ShellWen/v8_killer.svg?style=for-the-badge 81 | [forks-url]: https://github.com/ShellWen/v8_killer/network/members 82 | [stars-shield]: https://img.shields.io/github/stars/ShellWen/v8_killer.svg?style=for-the-badge 83 | [stars-url]: https://github.com/ShellWen/v8_killer/stargazers 84 | [issues-shield]: https://img.shields.io/github/issues/ShellWen/v8_killer.svg?style=for-the-badge 85 | [issues-url]: https://github.com/ShellWen/v8_killer/issues 86 | [pull-requests-url]: https://github.com/ShellWen/v8_killer/pulls 87 | [license-shield]: https://img.shields.io/github/license/ShellWen/v8_killer.svg?style=for-the-badge 88 | [license-url]: https://github.com/ShellWen/v8_killer/blob/master/LICENSE 89 | [linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=for-the-badge&logo=linkedin&colorB=555 90 | [linkedin-url]: https://linkedin.com/in/ShellWen 91 | 92 | [rust-badge]: https://img.shields.io/badge/Rust-000000?style=for-the-badge&logo=rust&logoColor=white 93 | [rust-url]: https://www.rust-lang.org/ 94 | [v8-badge]: https://img.shields.io/badge/V8-4B8BF5?style=for-the-badge&logo=v8&logoColor=white 95 | [v8-url]: https://v8.dev/ 96 | 97 | [electron-url]: https://github.com/electron/electron 98 | 99 | [discussions-url]: https://github.com/ShellWen/v8_killer/discussions 100 | -------------------------------------------------------------------------------- /docs/mkdocs.yml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://squidfunk.github.io/mkdocs-material/schema.json 2 | 3 | site_name: V8 Killer Docs 4 | site_author: ShellWen 5 | site_description: Official Documentation of V8 Killer 6 | site_url: https://shellwen.github.io/v8_killer 7 | edit_uri: blob/master/docs/docs/ 8 | 9 | repo_name: shellwen/v8_killer 10 | repo_url: https://github.com/shellwen/v8_killer 11 | 12 | theme: 13 | name: material 14 | icon: 15 | edit: material/pencil 16 | view: material/eye 17 | features: 18 | - search.suggest 19 | - search.highlight 20 | - content.tabs.link 21 | - navigation.indexes 22 | - content.tooltips 23 | - navigation.path 24 | - content.code.annotate 25 | - content.code.copy 26 | - content.code.select 27 | - navigation.tabs 28 | - toc.follow 29 | - toc.integrate 30 | - navigation.top 31 | - content.action.edit 32 | palette: 33 | - scheme: default 34 | media: "(prefers-color-scheme: light)" 35 | primary: deep orange 36 | accent: orange 37 | toggle: 38 | icon: material/brightness-7 39 | # TODO: i18n 40 | name: Switch to dark mode 41 | 42 | - scheme: slate 43 | media: "(prefers-color-scheme: dark)" 44 | primary: deep orange 45 | accent: orange 46 | toggle: 47 | icon: material/brightness-4 48 | # TODO: i18n 49 | name: Switch to light mode 50 | 51 | # noinspection YAMLSchemaValidation 52 | plugins: 53 | - search 54 | - i18n: 55 | docs_structure: suffix 56 | languages: 57 | - locale: en 58 | default: true 59 | name: en - English 60 | build: true 61 | - locale: zh 62 | name: zh - 中文 63 | site_name: V8 Killer 文档 64 | site_description: V8 Killer 官方文档 65 | nav_translations: 66 | Home: 主页 67 | Getting started: 开始使用 68 | Development: 开发 69 | theme: 70 | palette: 71 | - toggle: 72 | name: 切换到深色模式 73 | - toggle: 74 | name: 切换到浅色模式 75 | build: true 76 | 77 | nav: 78 | - Home: index.md 79 | - Getting started: getting-started.md 80 | - Development: development.md 81 | 82 | 83 | extra: 84 | social: 85 | - icon: fontawesome/brands/github-alt 86 | link: https://github.com/ShellWen/v8_killer 87 | alternate: 88 | - link: /v8_killer/ 89 | lang: en 90 | name: en - English 91 | - link: /v8_killer/zh/ 92 | lang: zh 93 | name: zh - 汉语 94 | 95 | # noinspection YAMLSchemaValidation 96 | markdown_extensions: 97 | - attr_list 98 | - toc: 99 | permalink: "#" 100 | -------------------------------------------------------------------------------- /examples/configs/custom-identifiers.toml: -------------------------------------------------------------------------------- 1 | # We have built-in default values for identifiers, but if you manually specify identifiers, 2 | # we will not use the default values. So please ensure that you have **defined complete identifiers**. 3 | [identifiers] 4 | # There are two types of identifier: 5 | # One is `symbol`, which automatically looks up the target function based on the symbol table; 6 | # The other is `rva`, which directly specifies the function's RVA. 7 | # Below, I provide their respective syntax. 8 | 9 | # The type of identifiers is an array, and we will match functions based on the order in the array. 10 | 11 | #V8_SCRIPT_COMPILER_COMPILE_FUNCTION = [{ type = "symbol", symbols = [ 12 | # """_ZN2v814ScriptCompiler23CompileFunctionInternalENS_5LocalINS_\ 13 | # 7ContextEEEPNS0_6SourceEmPNS1_INS_6StringEEEmPNS1_INS_6ObjectEEE\ 14 | # NS0_14CompileOptionsENS0_13NoCacheReasonEPNS1_INS_14ScriptOrModu\ 15 | # leEEE""", 16 | # """?CompileFunctionInternal@ScriptCompiler@v8@@CA?AV?$MaybeLocal\ 17 | # @VFunction@v8@@@2@V?$Local@VContext@v8@@@2@PEAVSource@12@_KQEAV?\ 18 | # $Local@VString@v8@@@2@2QEAV?$Local@VObject@v8@@@2@W4CompileOptio\ 19 | # ns@12@W4NoCacheReason@12@PEAV?$Local@VScriptOrModule@v8@@@2@@Z"""] }] 20 | V8_SCRIPT_COMPILER_COMPILE_FUNCTION = [{ type = "rva", module_name = "node", rva = 0x00a3ffb0 }] 21 | V8_STRING_UTF8LENGTH = [{ type = "symbol", symbols = [ 22 | """_ZNK2v86String10Utf8LengthEPNS_7IsolateE""", 23 | """?Utf8Length@String@v8@@QEBAHPEAVIsolate@2@@Z"""] }] 24 | V8_STRING_WRITE_UTF8 = [{ type = "symbol", symbols = [ 25 | """_ZNK2v86String9WriteUtf8EPNS_7IsolateEPciPii""", 26 | """?WriteUtf8@String@v8@@QEBAHPEAVIsolate@2@PEADHPEAHH@Z"""] }] 27 | V8_CONTEXT_GET_ISOLATE = [{ type = "symbol", symbols = [ 28 | """_ZN2v87Context10GetIsolateEv""", 29 | """?GetIsolate@Context@v8@@QEAAPEAVIsolate@2@XZ"""] }] 30 | V8_STRING_NEW_FROM_UTF8 = [{ type = "symbol", symbols = [ 31 | """_ZN2v86String11NewFromUtf8EPNS_7IsolateEPKcNS_13NewStringTypeEi""", 32 | """?NewFromUtf8@String@v8@@SA?AV?$MaybeLocal@VString@v8@@@2@PEAV\ 33 | Isolate@2@PEBDW4NewStringType@2@H@Z"""] }] 34 | 35 | 36 | [rules.hook_console_log] 37 | matcher = { type = "resource-name-keyword", keyword = "hello_world.js" } 38 | 39 | processors = [ 40 | { type = "insert-before", content = """\ 41 | const originalConsoleLog = console.log 42 | console.log = function () { 43 | originalConsoleLog('now you see :)') 44 | return originalConsoleLog.apply(this, arguments) 45 | }""" }, 46 | { type = "insert-after", content = """\ 47 | console.log = originalConsoleLog 48 | """ } 49 | ] 50 | -------------------------------------------------------------------------------- /examples/configs/simple.toml: -------------------------------------------------------------------------------- 1 | [rules.hook_console_log] 2 | matcher = { type = "resource-name-keyword", keyword = "hello_world.js" } 3 | 4 | processors = [ 5 | { type = "insert-before", content = """\ 6 | const originalConsoleLog = console.log 7 | console.log = function () { 8 | originalConsoleLog('now you see :)') 9 | return originalConsoleLog.apply(this, arguments) 10 | }""" }, 11 | { type = "insert-after", content = """\ 12 | console.log = originalConsoleLog 13 | """ } 14 | ] 15 | --------------------------------------------------------------------------------