├── .cargo └── config ├── .gitattributes ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── README.en.md ├── README.md ├── api ├── Cargo.toml ├── build.rs ├── src │ ├── cache │ │ ├── cache.rs │ │ ├── emulator.rs │ │ └── mod.rs │ ├── emu.rs │ ├── lib.rs │ ├── lib.udl │ ├── mac_serial.rs │ ├── macho │ │ ├── emulator.rs │ │ ├── macho.rs │ │ └── mod.rs │ ├── main.rs │ ├── patch │ │ ├── emulator.rs │ │ ├── mod.rs │ │ ├── osx.rs │ │ └── patch.rs │ ├── service.rs │ └── uniffi-bindgen.rs └── uniffi.toml ├── bindings ├── generate.txt └── python │ ├── apple_cache.py │ └── register.py ├── blob ├── AssetCache ├── AssetCache~.x64 ├── cert.cer ├── reloc.bin └── reloc.txt ├── build.sh ├── cache.json ├── cast_tool ├── .gitignore ├── Cargo.toml └── src │ └── main.rs ├── mac.toml ├── serial ├── vmp ├── VMProtectLicense.ini └── libVMProtectSDK64.so └── vmp_cmd /.cargo/config: -------------------------------------------------------------------------------- 1 | [target.mips64-unknown-linux-gnuabi64] 2 | rustflags = [ 3 | "-C", "target-feature=+crt-static", 4 | "-C", "link-arg=-msoft-float", 5 | ] 6 | linker = "mips64-octeon-linux-gnu-gcc" 7 | 8 | [target.i686-pc-windows-msvc] 9 | rustflags = ["-C", "target-feature=+crt-static"] 10 | 11 | [target.x86_64-pc-windows-msvc] 12 | rustflags = ["-C", "target-feature=+crt-static"] 13 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | blob/** filter=lfs diff=lfs merge=lfs -text 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /openssl* 3 | Cargo.lock 4 | bindings/python/* 5 | !bindings/**/*.py -------------------------------------------------------------------------------- /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 = "addr2line" 7 | version = "0.21.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler" 16 | version = "1.0.2" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 19 | 20 | [[package]] 21 | name = "aho-corasick" 22 | version = "1.1.2" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" 25 | dependencies = [ 26 | "memchr", 27 | ] 28 | 29 | [[package]] 30 | name = "android-tzdata" 31 | version = "0.1.1" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" 34 | 35 | [[package]] 36 | name = "android_system_properties" 37 | version = "0.1.5" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" 40 | dependencies = [ 41 | "libc", 42 | ] 43 | 44 | [[package]] 45 | name = "anstream" 46 | version = "0.6.4" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" 49 | dependencies = [ 50 | "anstyle", 51 | "anstyle-parse", 52 | "anstyle-query", 53 | "anstyle-wincon", 54 | "colorchoice", 55 | "utf8parse", 56 | ] 57 | 58 | [[package]] 59 | name = "anstyle" 60 | version = "1.0.4" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" 63 | 64 | [[package]] 65 | name = "anstyle-parse" 66 | version = "0.2.2" 67 | source = "registry+https://github.com/rust-lang/crates.io-index" 68 | checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" 69 | dependencies = [ 70 | "utf8parse", 71 | ] 72 | 73 | [[package]] 74 | name = "anstyle-query" 75 | version = "1.0.0" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" 78 | dependencies = [ 79 | "windows-sys", 80 | ] 81 | 82 | [[package]] 83 | name = "anstyle-wincon" 84 | version = "3.0.1" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" 87 | dependencies = [ 88 | "anstyle", 89 | "windows-sys", 90 | ] 91 | 92 | [[package]] 93 | name = "anyhow" 94 | version = "1.0.75" 95 | source = "registry+https://github.com/rust-lang/crates.io-index" 96 | checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" 97 | 98 | [[package]] 99 | name = "api" 100 | version = "0.1.0" 101 | dependencies = [ 102 | "anyhow", 103 | "base64 0.13.1", 104 | "bincode 2.0.0-rc.3", 105 | "env_logger", 106 | "goblin", 107 | "hex", 108 | "libc", 109 | "log", 110 | "openssl", 111 | "region", 112 | "reqwest", 113 | "rust-embed", 114 | "serde", 115 | "serde_derive", 116 | "serde_json", 117 | "thiserror", 118 | "toml", 119 | "unicorn-engine", 120 | "uniffi", 121 | "vmprotect", 122 | ] 123 | 124 | [[package]] 125 | name = "askama" 126 | version = "0.12.1" 127 | source = "registry+https://github.com/rust-lang/crates.io-index" 128 | checksum = "b79091df18a97caea757e28cd2d5fda49c6cd4bd01ddffd7ff01ace0c0ad2c28" 129 | dependencies = [ 130 | "askama_derive", 131 | "askama_escape", 132 | ] 133 | 134 | [[package]] 135 | name = "askama_derive" 136 | version = "0.12.2" 137 | source = "registry+https://github.com/rust-lang/crates.io-index" 138 | checksum = "9a0fc7dcf8bd4ead96b1d36b41df47c14beedf7b0301fc543d8f2384e66a2ec0" 139 | dependencies = [ 140 | "askama_parser", 141 | "basic-toml", 142 | "mime", 143 | "mime_guess", 144 | "proc-macro2", 145 | "quote", 146 | "serde", 147 | "syn 2.0.38", 148 | ] 149 | 150 | [[package]] 151 | name = "askama_escape" 152 | version = "0.10.3" 153 | source = "registry+https://github.com/rust-lang/crates.io-index" 154 | checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341" 155 | 156 | [[package]] 157 | name = "askama_parser" 158 | version = "0.1.1" 159 | source = "registry+https://github.com/rust-lang/crates.io-index" 160 | checksum = "c268a96e01a4c47c8c5c2472aaa570707e006a875ea63e819f75474ceedaf7b4" 161 | dependencies = [ 162 | "nom", 163 | ] 164 | 165 | [[package]] 166 | name = "autocfg" 167 | version = "1.1.0" 168 | source = "registry+https://github.com/rust-lang/crates.io-index" 169 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 170 | 171 | [[package]] 172 | name = "backtrace" 173 | version = "0.3.69" 174 | source = "registry+https://github.com/rust-lang/crates.io-index" 175 | checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" 176 | dependencies = [ 177 | "addr2line", 178 | "cc", 179 | "cfg-if", 180 | "libc", 181 | "miniz_oxide", 182 | "object", 183 | "rustc-demangle", 184 | ] 185 | 186 | [[package]] 187 | name = "base64" 188 | version = "0.13.1" 189 | source = "registry+https://github.com/rust-lang/crates.io-index" 190 | checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" 191 | 192 | [[package]] 193 | name = "base64" 194 | version = "0.21.5" 195 | source = "registry+https://github.com/rust-lang/crates.io-index" 196 | checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" 197 | 198 | [[package]] 199 | name = "basic-toml" 200 | version = "0.1.7" 201 | source = "registry+https://github.com/rust-lang/crates.io-index" 202 | checksum = "2f2139706359229bfa8f19142ac1155b4b80beafb7a60471ac5dd109d4a19778" 203 | dependencies = [ 204 | "serde", 205 | ] 206 | 207 | [[package]] 208 | name = "bincode" 209 | version = "1.3.3" 210 | source = "registry+https://github.com/rust-lang/crates.io-index" 211 | checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" 212 | dependencies = [ 213 | "serde", 214 | ] 215 | 216 | [[package]] 217 | name = "bincode" 218 | version = "2.0.0-rc.3" 219 | source = "git+https://github.com/bincode-org/bincode.git#73258a773595d9c0b8367f8a63968a1e8a528849" 220 | dependencies = [ 221 | "bincode_derive", 222 | "serde", 223 | "unty", 224 | ] 225 | 226 | [[package]] 227 | name = "bincode_derive" 228 | version = "2.0.0-rc.3" 229 | source = "git+https://github.com/bincode-org/bincode.git#73258a773595d9c0b8367f8a63968a1e8a528849" 230 | dependencies = [ 231 | "virtue", 232 | ] 233 | 234 | [[package]] 235 | name = "bitflags" 236 | version = "1.3.2" 237 | source = "registry+https://github.com/rust-lang/crates.io-index" 238 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 239 | 240 | [[package]] 241 | name = "bitflags" 242 | version = "2.4.1" 243 | source = "registry+https://github.com/rust-lang/crates.io-index" 244 | checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" 245 | 246 | [[package]] 247 | name = "block-buffer" 248 | version = "0.10.4" 249 | source = "registry+https://github.com/rust-lang/crates.io-index" 250 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 251 | dependencies = [ 252 | "generic-array", 253 | ] 254 | 255 | [[package]] 256 | name = "bstr" 257 | version = "1.7.0" 258 | source = "registry+https://github.com/rust-lang/crates.io-index" 259 | checksum = "c79ad7fb2dd38f3dabd76b09c6a5a20c038fc0213ef1e9afd30eb777f120f019" 260 | dependencies = [ 261 | "memchr", 262 | "serde", 263 | ] 264 | 265 | [[package]] 266 | name = "bumpalo" 267 | version = "3.14.0" 268 | source = "registry+https://github.com/rust-lang/crates.io-index" 269 | checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" 270 | 271 | [[package]] 272 | name = "bytes" 273 | version = "1.5.0" 274 | source = "registry+https://github.com/rust-lang/crates.io-index" 275 | checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" 276 | 277 | [[package]] 278 | name = "camino" 279 | version = "1.1.6" 280 | source = "registry+https://github.com/rust-lang/crates.io-index" 281 | checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" 282 | dependencies = [ 283 | "serde", 284 | ] 285 | 286 | [[package]] 287 | name = "cargo-platform" 288 | version = "0.1.4" 289 | source = "registry+https://github.com/rust-lang/crates.io-index" 290 | checksum = "12024c4645c97566567129c204f65d5815a8c9aecf30fcbe682b2fe034996d36" 291 | dependencies = [ 292 | "serde", 293 | ] 294 | 295 | [[package]] 296 | name = "cargo_metadata" 297 | version = "0.15.4" 298 | source = "registry+https://github.com/rust-lang/crates.io-index" 299 | checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" 300 | dependencies = [ 301 | "camino", 302 | "cargo-platform", 303 | "semver", 304 | "serde", 305 | "serde_json", 306 | "thiserror", 307 | ] 308 | 309 | [[package]] 310 | name = "cast_tool" 311 | version = "0.1.0" 312 | dependencies = [ 313 | "anyhow", 314 | "bincode 2.0.0-rc.3", 315 | "serde", 316 | ] 317 | 318 | [[package]] 319 | name = "cc" 320 | version = "1.0.83" 321 | source = "registry+https://github.com/rust-lang/crates.io-index" 322 | checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" 323 | dependencies = [ 324 | "libc", 325 | ] 326 | 327 | [[package]] 328 | name = "cfg-if" 329 | version = "1.0.0" 330 | source = "registry+https://github.com/rust-lang/crates.io-index" 331 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 332 | 333 | [[package]] 334 | name = "chrono" 335 | version = "0.4.31" 336 | source = "registry+https://github.com/rust-lang/crates.io-index" 337 | checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" 338 | dependencies = [ 339 | "android-tzdata", 340 | "iana-time-zone", 341 | "js-sys", 342 | "num-traits 0.2.17", 343 | "wasm-bindgen", 344 | "windows-targets", 345 | ] 346 | 347 | [[package]] 348 | name = "clap" 349 | version = "4.4.7" 350 | source = "registry+https://github.com/rust-lang/crates.io-index" 351 | checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b" 352 | dependencies = [ 353 | "clap_builder", 354 | "clap_derive", 355 | ] 356 | 357 | [[package]] 358 | name = "clap_builder" 359 | version = "4.4.7" 360 | source = "registry+https://github.com/rust-lang/crates.io-index" 361 | checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663" 362 | dependencies = [ 363 | "anstream", 364 | "anstyle", 365 | "clap_lex", 366 | "strsim", 367 | ] 368 | 369 | [[package]] 370 | name = "clap_derive" 371 | version = "4.4.7" 372 | source = "registry+https://github.com/rust-lang/crates.io-index" 373 | checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" 374 | dependencies = [ 375 | "heck", 376 | "proc-macro2", 377 | "quote", 378 | "syn 2.0.38", 379 | ] 380 | 381 | [[package]] 382 | name = "clap_lex" 383 | version = "0.6.0" 384 | source = "registry+https://github.com/rust-lang/crates.io-index" 385 | checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" 386 | 387 | [[package]] 388 | name = "cmake" 389 | version = "0.1.50" 390 | source = "registry+https://github.com/rust-lang/crates.io-index" 391 | checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" 392 | dependencies = [ 393 | "cc", 394 | ] 395 | 396 | [[package]] 397 | name = "colorchoice" 398 | version = "1.0.0" 399 | source = "registry+https://github.com/rust-lang/crates.io-index" 400 | checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" 401 | 402 | [[package]] 403 | name = "cookie" 404 | version = "0.16.2" 405 | source = "registry+https://github.com/rust-lang/crates.io-index" 406 | checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" 407 | dependencies = [ 408 | "percent-encoding", 409 | "time", 410 | "version_check", 411 | ] 412 | 413 | [[package]] 414 | name = "cookie_store" 415 | version = "0.16.2" 416 | source = "registry+https://github.com/rust-lang/crates.io-index" 417 | checksum = "d606d0fba62e13cf04db20536c05cb7f13673c161cb47a47a82b9b9e7d3f1daa" 418 | dependencies = [ 419 | "cookie", 420 | "idna 0.2.3", 421 | "log", 422 | "publicsuffix", 423 | "serde", 424 | "serde_derive", 425 | "serde_json", 426 | "time", 427 | "url", 428 | ] 429 | 430 | [[package]] 431 | name = "core-foundation" 432 | version = "0.9.3" 433 | source = "registry+https://github.com/rust-lang/crates.io-index" 434 | checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" 435 | dependencies = [ 436 | "core-foundation-sys", 437 | "libc", 438 | ] 439 | 440 | [[package]] 441 | name = "core-foundation-sys" 442 | version = "0.8.4" 443 | source = "registry+https://github.com/rust-lang/crates.io-index" 444 | checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" 445 | 446 | [[package]] 447 | name = "cpufeatures" 448 | version = "0.2.10" 449 | source = "registry+https://github.com/rust-lang/crates.io-index" 450 | checksum = "3fbc60abd742b35f2492f808e1abbb83d45f72db402e14c55057edc9c7b1e9e4" 451 | dependencies = [ 452 | "libc", 453 | ] 454 | 455 | [[package]] 456 | name = "crypto-common" 457 | version = "0.1.6" 458 | source = "registry+https://github.com/rust-lang/crates.io-index" 459 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 460 | dependencies = [ 461 | "generic-array", 462 | "typenum", 463 | ] 464 | 465 | [[package]] 466 | name = "deranged" 467 | version = "0.3.9" 468 | source = "registry+https://github.com/rust-lang/crates.io-index" 469 | checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" 470 | dependencies = [ 471 | "powerfmt", 472 | ] 473 | 474 | [[package]] 475 | name = "digest" 476 | version = "0.10.7" 477 | source = "registry+https://github.com/rust-lang/crates.io-index" 478 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 479 | dependencies = [ 480 | "block-buffer", 481 | "crypto-common", 482 | ] 483 | 484 | [[package]] 485 | name = "encoding_rs" 486 | version = "0.8.33" 487 | source = "registry+https://github.com/rust-lang/crates.io-index" 488 | checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" 489 | dependencies = [ 490 | "cfg-if", 491 | ] 492 | 493 | [[package]] 494 | name = "enum_primitive" 495 | version = "0.1.1" 496 | source = "registry+https://github.com/rust-lang/crates.io-index" 497 | checksum = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180" 498 | dependencies = [ 499 | "num-traits 0.1.43", 500 | ] 501 | 502 | [[package]] 503 | name = "env_logger" 504 | version = "0.10.0" 505 | source = "registry+https://github.com/rust-lang/crates.io-index" 506 | checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" 507 | dependencies = [ 508 | "humantime", 509 | "is-terminal", 510 | "log", 511 | "regex", 512 | "termcolor", 513 | ] 514 | 515 | [[package]] 516 | name = "errno" 517 | version = "0.3.5" 518 | source = "registry+https://github.com/rust-lang/crates.io-index" 519 | checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" 520 | dependencies = [ 521 | "libc", 522 | "windows-sys", 523 | ] 524 | 525 | [[package]] 526 | name = "fastrand" 527 | version = "2.0.1" 528 | source = "registry+https://github.com/rust-lang/crates.io-index" 529 | checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" 530 | 531 | [[package]] 532 | name = "fnv" 533 | version = "1.0.7" 534 | source = "registry+https://github.com/rust-lang/crates.io-index" 535 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 536 | 537 | [[package]] 538 | name = "foreign-types" 539 | version = "0.3.2" 540 | source = "registry+https://github.com/rust-lang/crates.io-index" 541 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 542 | dependencies = [ 543 | "foreign-types-shared", 544 | ] 545 | 546 | [[package]] 547 | name = "foreign-types-shared" 548 | version = "0.1.1" 549 | source = "registry+https://github.com/rust-lang/crates.io-index" 550 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 551 | 552 | [[package]] 553 | name = "form_urlencoded" 554 | version = "1.2.0" 555 | source = "registry+https://github.com/rust-lang/crates.io-index" 556 | checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" 557 | dependencies = [ 558 | "percent-encoding", 559 | ] 560 | 561 | [[package]] 562 | name = "fs-err" 563 | version = "2.9.0" 564 | source = "registry+https://github.com/rust-lang/crates.io-index" 565 | checksum = "0845fa252299212f0389d64ba26f34fa32cfe41588355f21ed507c59a0f64541" 566 | 567 | [[package]] 568 | name = "futures-channel" 569 | version = "0.3.28" 570 | source = "registry+https://github.com/rust-lang/crates.io-index" 571 | checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" 572 | dependencies = [ 573 | "futures-core", 574 | ] 575 | 576 | [[package]] 577 | name = "futures-core" 578 | version = "0.3.28" 579 | source = "registry+https://github.com/rust-lang/crates.io-index" 580 | checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" 581 | 582 | [[package]] 583 | name = "futures-io" 584 | version = "0.3.28" 585 | source = "registry+https://github.com/rust-lang/crates.io-index" 586 | checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" 587 | 588 | [[package]] 589 | name = "futures-sink" 590 | version = "0.3.28" 591 | source = "registry+https://github.com/rust-lang/crates.io-index" 592 | checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" 593 | 594 | [[package]] 595 | name = "futures-task" 596 | version = "0.3.28" 597 | source = "registry+https://github.com/rust-lang/crates.io-index" 598 | checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" 599 | 600 | [[package]] 601 | name = "futures-util" 602 | version = "0.3.28" 603 | source = "registry+https://github.com/rust-lang/crates.io-index" 604 | checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" 605 | dependencies = [ 606 | "futures-core", 607 | "futures-io", 608 | "futures-task", 609 | "memchr", 610 | "pin-project-lite", 611 | "pin-utils", 612 | "slab", 613 | ] 614 | 615 | [[package]] 616 | name = "generator" 617 | version = "0.7.5" 618 | source = "registry+https://github.com/rust-lang/crates.io-index" 619 | checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" 620 | dependencies = [ 621 | "cc", 622 | "libc", 623 | "log", 624 | "rustversion", 625 | "windows", 626 | ] 627 | 628 | [[package]] 629 | name = "generic-array" 630 | version = "0.14.7" 631 | source = "registry+https://github.com/rust-lang/crates.io-index" 632 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 633 | dependencies = [ 634 | "typenum", 635 | "version_check", 636 | ] 637 | 638 | [[package]] 639 | name = "getrandom" 640 | version = "0.2.10" 641 | source = "registry+https://github.com/rust-lang/crates.io-index" 642 | checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" 643 | dependencies = [ 644 | "cfg-if", 645 | "libc", 646 | "wasi", 647 | ] 648 | 649 | [[package]] 650 | name = "gimli" 651 | version = "0.28.0" 652 | source = "registry+https://github.com/rust-lang/crates.io-index" 653 | checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" 654 | 655 | [[package]] 656 | name = "glob" 657 | version = "0.3.1" 658 | source = "registry+https://github.com/rust-lang/crates.io-index" 659 | checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" 660 | 661 | [[package]] 662 | name = "globset" 663 | version = "0.4.13" 664 | source = "registry+https://github.com/rust-lang/crates.io-index" 665 | checksum = "759c97c1e17c55525b57192c06a267cda0ac5210b222d6b82189a2338fa1c13d" 666 | dependencies = [ 667 | "aho-corasick", 668 | "bstr", 669 | "fnv", 670 | "log", 671 | "regex", 672 | ] 673 | 674 | [[package]] 675 | name = "goblin" 676 | version = "0.6.1" 677 | source = "registry+https://github.com/rust-lang/crates.io-index" 678 | checksum = "0d6b4de4a8eb6c46a8c77e1d3be942cb9a8bf073c22374578e5ba4b08ed0ff68" 679 | dependencies = [ 680 | "log", 681 | "plain", 682 | "scroll", 683 | ] 684 | 685 | [[package]] 686 | name = "h2" 687 | version = "0.3.21" 688 | source = "registry+https://github.com/rust-lang/crates.io-index" 689 | checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" 690 | dependencies = [ 691 | "bytes", 692 | "fnv", 693 | "futures-core", 694 | "futures-sink", 695 | "futures-util", 696 | "http", 697 | "indexmap", 698 | "slab", 699 | "tokio", 700 | "tokio-util", 701 | "tracing", 702 | ] 703 | 704 | [[package]] 705 | name = "hashbrown" 706 | version = "0.12.3" 707 | source = "registry+https://github.com/rust-lang/crates.io-index" 708 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 709 | 710 | [[package]] 711 | name = "heck" 712 | version = "0.4.1" 713 | source = "registry+https://github.com/rust-lang/crates.io-index" 714 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 715 | 716 | [[package]] 717 | name = "hermit-abi" 718 | version = "0.3.3" 719 | source = "registry+https://github.com/rust-lang/crates.io-index" 720 | checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" 721 | 722 | [[package]] 723 | name = "hex" 724 | version = "0.4.3" 725 | source = "registry+https://github.com/rust-lang/crates.io-index" 726 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 727 | 728 | [[package]] 729 | name = "http" 730 | version = "0.2.9" 731 | source = "registry+https://github.com/rust-lang/crates.io-index" 732 | checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" 733 | dependencies = [ 734 | "bytes", 735 | "fnv", 736 | "itoa", 737 | ] 738 | 739 | [[package]] 740 | name = "http-body" 741 | version = "0.4.5" 742 | source = "registry+https://github.com/rust-lang/crates.io-index" 743 | checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" 744 | dependencies = [ 745 | "bytes", 746 | "http", 747 | "pin-project-lite", 748 | ] 749 | 750 | [[package]] 751 | name = "httparse" 752 | version = "1.8.0" 753 | source = "registry+https://github.com/rust-lang/crates.io-index" 754 | checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" 755 | 756 | [[package]] 757 | name = "httpdate" 758 | version = "1.0.3" 759 | source = "registry+https://github.com/rust-lang/crates.io-index" 760 | checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" 761 | 762 | [[package]] 763 | name = "humantime" 764 | version = "2.1.0" 765 | source = "registry+https://github.com/rust-lang/crates.io-index" 766 | checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" 767 | 768 | [[package]] 769 | name = "hyper" 770 | version = "0.14.27" 771 | source = "registry+https://github.com/rust-lang/crates.io-index" 772 | checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" 773 | dependencies = [ 774 | "bytes", 775 | "futures-channel", 776 | "futures-core", 777 | "futures-util", 778 | "h2", 779 | "http", 780 | "http-body", 781 | "httparse", 782 | "httpdate", 783 | "itoa", 784 | "pin-project-lite", 785 | "socket2 0.4.10", 786 | "tokio", 787 | "tower-service", 788 | "tracing", 789 | "want", 790 | ] 791 | 792 | [[package]] 793 | name = "hyper-tls" 794 | version = "0.5.0" 795 | source = "registry+https://github.com/rust-lang/crates.io-index" 796 | checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" 797 | dependencies = [ 798 | "bytes", 799 | "hyper", 800 | "native-tls", 801 | "tokio", 802 | "tokio-native-tls", 803 | ] 804 | 805 | [[package]] 806 | name = "iana-time-zone" 807 | version = "0.1.58" 808 | source = "registry+https://github.com/rust-lang/crates.io-index" 809 | checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" 810 | dependencies = [ 811 | "android_system_properties", 812 | "core-foundation-sys", 813 | "iana-time-zone-haiku", 814 | "js-sys", 815 | "wasm-bindgen", 816 | "windows-core", 817 | ] 818 | 819 | [[package]] 820 | name = "iana-time-zone-haiku" 821 | version = "0.1.2" 822 | source = "registry+https://github.com/rust-lang/crates.io-index" 823 | checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" 824 | dependencies = [ 825 | "cc", 826 | ] 827 | 828 | [[package]] 829 | name = "idna" 830 | version = "0.2.3" 831 | source = "registry+https://github.com/rust-lang/crates.io-index" 832 | checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" 833 | dependencies = [ 834 | "matches", 835 | "unicode-bidi", 836 | "unicode-normalization", 837 | ] 838 | 839 | [[package]] 840 | name = "idna" 841 | version = "0.3.0" 842 | source = "registry+https://github.com/rust-lang/crates.io-index" 843 | checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" 844 | dependencies = [ 845 | "unicode-bidi", 846 | "unicode-normalization", 847 | ] 848 | 849 | [[package]] 850 | name = "idna" 851 | version = "0.4.0" 852 | source = "registry+https://github.com/rust-lang/crates.io-index" 853 | checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" 854 | dependencies = [ 855 | "unicode-bidi", 856 | "unicode-normalization", 857 | ] 858 | 859 | [[package]] 860 | name = "indexmap" 861 | version = "1.9.3" 862 | source = "registry+https://github.com/rust-lang/crates.io-index" 863 | checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" 864 | dependencies = [ 865 | "autocfg", 866 | "hashbrown", 867 | ] 868 | 869 | [[package]] 870 | name = "ipnet" 871 | version = "2.9.0" 872 | source = "registry+https://github.com/rust-lang/crates.io-index" 873 | checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" 874 | 875 | [[package]] 876 | name = "is-terminal" 877 | version = "0.4.9" 878 | source = "registry+https://github.com/rust-lang/crates.io-index" 879 | checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" 880 | dependencies = [ 881 | "hermit-abi", 882 | "rustix", 883 | "windows-sys", 884 | ] 885 | 886 | [[package]] 887 | name = "itoa" 888 | version = "1.0.9" 889 | source = "registry+https://github.com/rust-lang/crates.io-index" 890 | checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" 891 | 892 | [[package]] 893 | name = "js-sys" 894 | version = "0.3.64" 895 | source = "registry+https://github.com/rust-lang/crates.io-index" 896 | checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" 897 | dependencies = [ 898 | "wasm-bindgen", 899 | ] 900 | 901 | [[package]] 902 | name = "lazy_static" 903 | version = "1.4.0" 904 | source = "registry+https://github.com/rust-lang/crates.io-index" 905 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 906 | 907 | [[package]] 908 | name = "libc" 909 | version = "0.2.149" 910 | source = "registry+https://github.com/rust-lang/crates.io-index" 911 | checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" 912 | 913 | [[package]] 914 | name = "linux-raw-sys" 915 | version = "0.4.10" 916 | source = "registry+https://github.com/rust-lang/crates.io-index" 917 | checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" 918 | 919 | [[package]] 920 | name = "log" 921 | version = "0.4.20" 922 | source = "registry+https://github.com/rust-lang/crates.io-index" 923 | checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" 924 | 925 | [[package]] 926 | name = "loom" 927 | version = "0.5.6" 928 | source = "registry+https://github.com/rust-lang/crates.io-index" 929 | checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" 930 | dependencies = [ 931 | "cfg-if", 932 | "generator", 933 | "pin-utils", 934 | "scoped-tls", 935 | "tracing", 936 | "tracing-subscriber", 937 | ] 938 | 939 | [[package]] 940 | name = "mach" 941 | version = "0.3.2" 942 | source = "registry+https://github.com/rust-lang/crates.io-index" 943 | checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" 944 | dependencies = [ 945 | "libc", 946 | ] 947 | 948 | [[package]] 949 | name = "matchers" 950 | version = "0.1.0" 951 | source = "registry+https://github.com/rust-lang/crates.io-index" 952 | checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" 953 | dependencies = [ 954 | "regex-automata 0.1.10", 955 | ] 956 | 957 | [[package]] 958 | name = "matches" 959 | version = "0.1.10" 960 | source = "registry+https://github.com/rust-lang/crates.io-index" 961 | checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" 962 | 963 | [[package]] 964 | name = "memchr" 965 | version = "2.6.4" 966 | source = "registry+https://github.com/rust-lang/crates.io-index" 967 | checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" 968 | 969 | [[package]] 970 | name = "mime" 971 | version = "0.3.17" 972 | source = "registry+https://github.com/rust-lang/crates.io-index" 973 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 974 | 975 | [[package]] 976 | name = "mime_guess" 977 | version = "2.0.4" 978 | source = "registry+https://github.com/rust-lang/crates.io-index" 979 | checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" 980 | dependencies = [ 981 | "mime", 982 | "unicase", 983 | ] 984 | 985 | [[package]] 986 | name = "minimal-lexical" 987 | version = "0.2.1" 988 | source = "registry+https://github.com/rust-lang/crates.io-index" 989 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 990 | 991 | [[package]] 992 | name = "miniz_oxide" 993 | version = "0.7.1" 994 | source = "registry+https://github.com/rust-lang/crates.io-index" 995 | checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" 996 | dependencies = [ 997 | "adler", 998 | ] 999 | 1000 | [[package]] 1001 | name = "mio" 1002 | version = "0.8.9" 1003 | source = "registry+https://github.com/rust-lang/crates.io-index" 1004 | checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" 1005 | dependencies = [ 1006 | "libc", 1007 | "wasi", 1008 | "windows-sys", 1009 | ] 1010 | 1011 | [[package]] 1012 | name = "native-tls" 1013 | version = "0.2.11" 1014 | source = "registry+https://github.com/rust-lang/crates.io-index" 1015 | checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" 1016 | dependencies = [ 1017 | "lazy_static", 1018 | "libc", 1019 | "log", 1020 | "openssl", 1021 | "openssl-probe", 1022 | "openssl-sys", 1023 | "schannel", 1024 | "security-framework", 1025 | "security-framework-sys", 1026 | "tempfile", 1027 | ] 1028 | 1029 | [[package]] 1030 | name = "nom" 1031 | version = "7.1.3" 1032 | source = "registry+https://github.com/rust-lang/crates.io-index" 1033 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" 1034 | dependencies = [ 1035 | "memchr", 1036 | "minimal-lexical", 1037 | ] 1038 | 1039 | [[package]] 1040 | name = "nu-ansi-term" 1041 | version = "0.46.0" 1042 | source = "registry+https://github.com/rust-lang/crates.io-index" 1043 | checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" 1044 | dependencies = [ 1045 | "overload", 1046 | "winapi", 1047 | ] 1048 | 1049 | [[package]] 1050 | name = "num-traits" 1051 | version = "0.1.43" 1052 | source = "registry+https://github.com/rust-lang/crates.io-index" 1053 | checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" 1054 | dependencies = [ 1055 | "num-traits 0.2.17", 1056 | ] 1057 | 1058 | [[package]] 1059 | name = "num-traits" 1060 | version = "0.2.17" 1061 | source = "registry+https://github.com/rust-lang/crates.io-index" 1062 | checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" 1063 | dependencies = [ 1064 | "autocfg", 1065 | ] 1066 | 1067 | [[package]] 1068 | name = "num_cpus" 1069 | version = "1.16.0" 1070 | source = "registry+https://github.com/rust-lang/crates.io-index" 1071 | checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" 1072 | dependencies = [ 1073 | "hermit-abi", 1074 | "libc", 1075 | ] 1076 | 1077 | [[package]] 1078 | name = "object" 1079 | version = "0.32.1" 1080 | source = "registry+https://github.com/rust-lang/crates.io-index" 1081 | checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" 1082 | dependencies = [ 1083 | "memchr", 1084 | ] 1085 | 1086 | [[package]] 1087 | name = "once_cell" 1088 | version = "1.18.0" 1089 | source = "registry+https://github.com/rust-lang/crates.io-index" 1090 | checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" 1091 | 1092 | [[package]] 1093 | name = "oneshot" 1094 | version = "0.1.6" 1095 | source = "registry+https://github.com/rust-lang/crates.io-index" 1096 | checksum = "6f6640c6bda7731b1fdbab747981a0f896dd1fedaf9f4a53fa237a04a84431f4" 1097 | dependencies = [ 1098 | "loom", 1099 | ] 1100 | 1101 | [[package]] 1102 | name = "openssl" 1103 | version = "0.10.57" 1104 | source = "registry+https://github.com/rust-lang/crates.io-index" 1105 | checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" 1106 | dependencies = [ 1107 | "bitflags 2.4.1", 1108 | "cfg-if", 1109 | "foreign-types", 1110 | "libc", 1111 | "once_cell", 1112 | "openssl-macros", 1113 | "openssl-sys", 1114 | ] 1115 | 1116 | [[package]] 1117 | name = "openssl-macros" 1118 | version = "0.1.1" 1119 | source = "registry+https://github.com/rust-lang/crates.io-index" 1120 | checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" 1121 | dependencies = [ 1122 | "proc-macro2", 1123 | "quote", 1124 | "syn 2.0.38", 1125 | ] 1126 | 1127 | [[package]] 1128 | name = "openssl-probe" 1129 | version = "0.1.5" 1130 | source = "registry+https://github.com/rust-lang/crates.io-index" 1131 | checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" 1132 | 1133 | [[package]] 1134 | name = "openssl-src" 1135 | version = "300.1.5+3.1.3" 1136 | source = "registry+https://github.com/rust-lang/crates.io-index" 1137 | checksum = "559068e4c12950d7dcaa1857a61725c0d38d4fc03ff8e070ab31a75d6e316491" 1138 | dependencies = [ 1139 | "cc", 1140 | ] 1141 | 1142 | [[package]] 1143 | name = "openssl-sys" 1144 | version = "0.9.93" 1145 | source = "registry+https://github.com/rust-lang/crates.io-index" 1146 | checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" 1147 | dependencies = [ 1148 | "cc", 1149 | "libc", 1150 | "openssl-src", 1151 | "pkg-config", 1152 | "vcpkg", 1153 | ] 1154 | 1155 | [[package]] 1156 | name = "overload" 1157 | version = "0.1.1" 1158 | source = "registry+https://github.com/rust-lang/crates.io-index" 1159 | checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" 1160 | 1161 | [[package]] 1162 | name = "paste" 1163 | version = "1.0.14" 1164 | source = "registry+https://github.com/rust-lang/crates.io-index" 1165 | checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" 1166 | 1167 | [[package]] 1168 | name = "percent-encoding" 1169 | version = "2.3.0" 1170 | source = "registry+https://github.com/rust-lang/crates.io-index" 1171 | checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" 1172 | 1173 | [[package]] 1174 | name = "pin-project-lite" 1175 | version = "0.2.13" 1176 | source = "registry+https://github.com/rust-lang/crates.io-index" 1177 | checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" 1178 | 1179 | [[package]] 1180 | name = "pin-utils" 1181 | version = "0.1.0" 1182 | source = "registry+https://github.com/rust-lang/crates.io-index" 1183 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1184 | 1185 | [[package]] 1186 | name = "pkg-config" 1187 | version = "0.3.27" 1188 | source = "registry+https://github.com/rust-lang/crates.io-index" 1189 | checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" 1190 | 1191 | [[package]] 1192 | name = "plain" 1193 | version = "0.2.3" 1194 | source = "registry+https://github.com/rust-lang/crates.io-index" 1195 | checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" 1196 | 1197 | [[package]] 1198 | name = "powerfmt" 1199 | version = "0.2.0" 1200 | source = "registry+https://github.com/rust-lang/crates.io-index" 1201 | checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" 1202 | 1203 | [[package]] 1204 | name = "ppv-lite86" 1205 | version = "0.2.17" 1206 | source = "registry+https://github.com/rust-lang/crates.io-index" 1207 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 1208 | 1209 | [[package]] 1210 | name = "proc-macro2" 1211 | version = "1.0.69" 1212 | source = "registry+https://github.com/rust-lang/crates.io-index" 1213 | checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" 1214 | dependencies = [ 1215 | "unicode-ident", 1216 | ] 1217 | 1218 | [[package]] 1219 | name = "psl-types" 1220 | version = "2.0.11" 1221 | source = "registry+https://github.com/rust-lang/crates.io-index" 1222 | checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" 1223 | 1224 | [[package]] 1225 | name = "publicsuffix" 1226 | version = "2.2.3" 1227 | source = "registry+https://github.com/rust-lang/crates.io-index" 1228 | checksum = "96a8c1bda5ae1af7f99a2962e49df150414a43d62404644d98dd5c3a93d07457" 1229 | dependencies = [ 1230 | "idna 0.3.0", 1231 | "psl-types", 1232 | ] 1233 | 1234 | [[package]] 1235 | name = "quote" 1236 | version = "1.0.33" 1237 | source = "registry+https://github.com/rust-lang/crates.io-index" 1238 | checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" 1239 | dependencies = [ 1240 | "proc-macro2", 1241 | ] 1242 | 1243 | [[package]] 1244 | name = "rand" 1245 | version = "0.8.5" 1246 | source = "registry+https://github.com/rust-lang/crates.io-index" 1247 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1248 | dependencies = [ 1249 | "libc", 1250 | "rand_chacha", 1251 | "rand_core", 1252 | ] 1253 | 1254 | [[package]] 1255 | name = "rand_chacha" 1256 | version = "0.3.1" 1257 | source = "registry+https://github.com/rust-lang/crates.io-index" 1258 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1259 | dependencies = [ 1260 | "ppv-lite86", 1261 | "rand_core", 1262 | ] 1263 | 1264 | [[package]] 1265 | name = "rand_core" 1266 | version = "0.6.4" 1267 | source = "registry+https://github.com/rust-lang/crates.io-index" 1268 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 1269 | dependencies = [ 1270 | "getrandom", 1271 | ] 1272 | 1273 | [[package]] 1274 | name = "real_c_string" 1275 | version = "1.0.1" 1276 | source = "registry+https://github.com/rust-lang/crates.io-index" 1277 | checksum = "ae244cf1357665c9cf83bb4a8f35340c8a7e70eae29961c1758031bb8471af13" 1278 | dependencies = [ 1279 | "quote", 1280 | "syn 2.0.38", 1281 | ] 1282 | 1283 | [[package]] 1284 | name = "redox_syscall" 1285 | version = "0.3.5" 1286 | source = "registry+https://github.com/rust-lang/crates.io-index" 1287 | checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" 1288 | dependencies = [ 1289 | "bitflags 1.3.2", 1290 | ] 1291 | 1292 | [[package]] 1293 | name = "regex" 1294 | version = "1.10.2" 1295 | source = "registry+https://github.com/rust-lang/crates.io-index" 1296 | checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" 1297 | dependencies = [ 1298 | "aho-corasick", 1299 | "memchr", 1300 | "regex-automata 0.4.3", 1301 | "regex-syntax 0.8.2", 1302 | ] 1303 | 1304 | [[package]] 1305 | name = "regex-automata" 1306 | version = "0.1.10" 1307 | source = "registry+https://github.com/rust-lang/crates.io-index" 1308 | checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" 1309 | dependencies = [ 1310 | "regex-syntax 0.6.29", 1311 | ] 1312 | 1313 | [[package]] 1314 | name = "regex-automata" 1315 | version = "0.4.3" 1316 | source = "registry+https://github.com/rust-lang/crates.io-index" 1317 | checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" 1318 | dependencies = [ 1319 | "aho-corasick", 1320 | "memchr", 1321 | "regex-syntax 0.8.2", 1322 | ] 1323 | 1324 | [[package]] 1325 | name = "regex-syntax" 1326 | version = "0.6.29" 1327 | source = "registry+https://github.com/rust-lang/crates.io-index" 1328 | checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" 1329 | 1330 | [[package]] 1331 | name = "regex-syntax" 1332 | version = "0.8.2" 1333 | source = "registry+https://github.com/rust-lang/crates.io-index" 1334 | checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" 1335 | 1336 | [[package]] 1337 | name = "region" 1338 | version = "3.0.0" 1339 | source = "registry+https://github.com/rust-lang/crates.io-index" 1340 | checksum = "76e189c2369884dce920945e2ddf79b3dff49e071a167dd1817fa9c4c00d512e" 1341 | dependencies = [ 1342 | "bitflags 1.3.2", 1343 | "libc", 1344 | "mach", 1345 | "winapi", 1346 | ] 1347 | 1348 | [[package]] 1349 | name = "reqwest" 1350 | version = "0.11.22" 1351 | source = "registry+https://github.com/rust-lang/crates.io-index" 1352 | checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" 1353 | dependencies = [ 1354 | "base64 0.21.5", 1355 | "bytes", 1356 | "cookie", 1357 | "cookie_store", 1358 | "encoding_rs", 1359 | "futures-core", 1360 | "futures-util", 1361 | "h2", 1362 | "http", 1363 | "http-body", 1364 | "hyper", 1365 | "hyper-tls", 1366 | "ipnet", 1367 | "js-sys", 1368 | "log", 1369 | "mime", 1370 | "native-tls", 1371 | "once_cell", 1372 | "percent-encoding", 1373 | "pin-project-lite", 1374 | "serde", 1375 | "serde_json", 1376 | "serde_urlencoded", 1377 | "system-configuration", 1378 | "tokio", 1379 | "tokio-native-tls", 1380 | "tower-service", 1381 | "url", 1382 | "wasm-bindgen", 1383 | "wasm-bindgen-futures", 1384 | "web-sys", 1385 | "winreg", 1386 | ] 1387 | 1388 | [[package]] 1389 | name = "rust-embed" 1390 | version = "6.8.1" 1391 | source = "registry+https://github.com/rust-lang/crates.io-index" 1392 | checksum = "a36224c3276f8c4ebc8c20f158eca7ca4359c8db89991c4925132aaaf6702661" 1393 | dependencies = [ 1394 | "rust-embed-impl", 1395 | "rust-embed-utils", 1396 | "walkdir", 1397 | ] 1398 | 1399 | [[package]] 1400 | name = "rust-embed-impl" 1401 | version = "6.8.1" 1402 | source = "registry+https://github.com/rust-lang/crates.io-index" 1403 | checksum = "49b94b81e5b2c284684141a2fb9e2a31be90638caf040bf9afbc5a0416afe1ac" 1404 | dependencies = [ 1405 | "proc-macro2", 1406 | "quote", 1407 | "rust-embed-utils", 1408 | "syn 2.0.38", 1409 | "walkdir", 1410 | ] 1411 | 1412 | [[package]] 1413 | name = "rust-embed-utils" 1414 | version = "7.8.1" 1415 | source = "registry+https://github.com/rust-lang/crates.io-index" 1416 | checksum = "9d38ff6bf570dc3bb7100fce9f7b60c33fa71d80e88da3f2580df4ff2bdded74" 1417 | dependencies = [ 1418 | "globset", 1419 | "sha2", 1420 | "walkdir", 1421 | ] 1422 | 1423 | [[package]] 1424 | name = "rustc-demangle" 1425 | version = "0.1.23" 1426 | source = "registry+https://github.com/rust-lang/crates.io-index" 1427 | checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" 1428 | 1429 | [[package]] 1430 | name = "rustix" 1431 | version = "0.38.20" 1432 | source = "registry+https://github.com/rust-lang/crates.io-index" 1433 | checksum = "67ce50cb2e16c2903e30d1cbccfd8387a74b9d4c938b6a4c5ec6cc7556f7a8a0" 1434 | dependencies = [ 1435 | "bitflags 2.4.1", 1436 | "errno", 1437 | "libc", 1438 | "linux-raw-sys", 1439 | "windows-sys", 1440 | ] 1441 | 1442 | [[package]] 1443 | name = "rustversion" 1444 | version = "1.0.14" 1445 | source = "registry+https://github.com/rust-lang/crates.io-index" 1446 | checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" 1447 | 1448 | [[package]] 1449 | name = "ryu" 1450 | version = "1.0.15" 1451 | source = "registry+https://github.com/rust-lang/crates.io-index" 1452 | checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" 1453 | 1454 | [[package]] 1455 | name = "same-file" 1456 | version = "1.0.6" 1457 | source = "registry+https://github.com/rust-lang/crates.io-index" 1458 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 1459 | dependencies = [ 1460 | "winapi-util", 1461 | ] 1462 | 1463 | [[package]] 1464 | name = "schannel" 1465 | version = "0.1.22" 1466 | source = "registry+https://github.com/rust-lang/crates.io-index" 1467 | checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" 1468 | dependencies = [ 1469 | "windows-sys", 1470 | ] 1471 | 1472 | [[package]] 1473 | name = "scoped-tls" 1474 | version = "1.0.1" 1475 | source = "registry+https://github.com/rust-lang/crates.io-index" 1476 | checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" 1477 | 1478 | [[package]] 1479 | name = "scroll" 1480 | version = "0.11.0" 1481 | source = "registry+https://github.com/rust-lang/crates.io-index" 1482 | checksum = "04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da" 1483 | dependencies = [ 1484 | "scroll_derive", 1485 | ] 1486 | 1487 | [[package]] 1488 | name = "scroll_derive" 1489 | version = "0.11.1" 1490 | source = "registry+https://github.com/rust-lang/crates.io-index" 1491 | checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" 1492 | dependencies = [ 1493 | "proc-macro2", 1494 | "quote", 1495 | "syn 2.0.38", 1496 | ] 1497 | 1498 | [[package]] 1499 | name = "security-framework" 1500 | version = "2.9.2" 1501 | source = "registry+https://github.com/rust-lang/crates.io-index" 1502 | checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" 1503 | dependencies = [ 1504 | "bitflags 1.3.2", 1505 | "core-foundation", 1506 | "core-foundation-sys", 1507 | "libc", 1508 | "security-framework-sys", 1509 | ] 1510 | 1511 | [[package]] 1512 | name = "security-framework-sys" 1513 | version = "2.9.1" 1514 | source = "registry+https://github.com/rust-lang/crates.io-index" 1515 | checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" 1516 | dependencies = [ 1517 | "core-foundation-sys", 1518 | "libc", 1519 | ] 1520 | 1521 | [[package]] 1522 | name = "semver" 1523 | version = "1.0.20" 1524 | source = "registry+https://github.com/rust-lang/crates.io-index" 1525 | checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" 1526 | dependencies = [ 1527 | "serde", 1528 | ] 1529 | 1530 | [[package]] 1531 | name = "serde" 1532 | version = "1.0.192" 1533 | source = "registry+https://github.com/rust-lang/crates.io-index" 1534 | checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" 1535 | dependencies = [ 1536 | "serde_derive", 1537 | ] 1538 | 1539 | [[package]] 1540 | name = "serde_derive" 1541 | version = "1.0.192" 1542 | source = "registry+https://github.com/rust-lang/crates.io-index" 1543 | checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" 1544 | dependencies = [ 1545 | "proc-macro2", 1546 | "quote", 1547 | "syn 2.0.38", 1548 | ] 1549 | 1550 | [[package]] 1551 | name = "serde_json" 1552 | version = "1.0.107" 1553 | source = "registry+https://github.com/rust-lang/crates.io-index" 1554 | checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" 1555 | dependencies = [ 1556 | "itoa", 1557 | "ryu", 1558 | "serde", 1559 | ] 1560 | 1561 | [[package]] 1562 | name = "serde_urlencoded" 1563 | version = "0.7.1" 1564 | source = "registry+https://github.com/rust-lang/crates.io-index" 1565 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 1566 | dependencies = [ 1567 | "form_urlencoded", 1568 | "itoa", 1569 | "ryu", 1570 | "serde", 1571 | ] 1572 | 1573 | [[package]] 1574 | name = "sha2" 1575 | version = "0.10.8" 1576 | source = "registry+https://github.com/rust-lang/crates.io-index" 1577 | checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" 1578 | dependencies = [ 1579 | "cfg-if", 1580 | "cpufeatures", 1581 | "digest", 1582 | ] 1583 | 1584 | [[package]] 1585 | name = "sharded-slab" 1586 | version = "0.1.7" 1587 | source = "registry+https://github.com/rust-lang/crates.io-index" 1588 | checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" 1589 | dependencies = [ 1590 | "lazy_static", 1591 | ] 1592 | 1593 | [[package]] 1594 | name = "siphasher" 1595 | version = "0.3.11" 1596 | source = "registry+https://github.com/rust-lang/crates.io-index" 1597 | checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" 1598 | 1599 | [[package]] 1600 | name = "slab" 1601 | version = "0.4.9" 1602 | source = "registry+https://github.com/rust-lang/crates.io-index" 1603 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 1604 | dependencies = [ 1605 | "autocfg", 1606 | ] 1607 | 1608 | [[package]] 1609 | name = "smallvec" 1610 | version = "1.11.1" 1611 | source = "registry+https://github.com/rust-lang/crates.io-index" 1612 | checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" 1613 | 1614 | [[package]] 1615 | name = "socket2" 1616 | version = "0.4.10" 1617 | source = "registry+https://github.com/rust-lang/crates.io-index" 1618 | checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" 1619 | dependencies = [ 1620 | "libc", 1621 | "winapi", 1622 | ] 1623 | 1624 | [[package]] 1625 | name = "socket2" 1626 | version = "0.5.5" 1627 | source = "registry+https://github.com/rust-lang/crates.io-index" 1628 | checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" 1629 | dependencies = [ 1630 | "libc", 1631 | "windows-sys", 1632 | ] 1633 | 1634 | [[package]] 1635 | name = "static_assertions" 1636 | version = "1.1.0" 1637 | source = "registry+https://github.com/rust-lang/crates.io-index" 1638 | checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 1639 | 1640 | [[package]] 1641 | name = "strsim" 1642 | version = "0.10.0" 1643 | source = "registry+https://github.com/rust-lang/crates.io-index" 1644 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 1645 | 1646 | [[package]] 1647 | name = "syn" 1648 | version = "1.0.109" 1649 | source = "registry+https://github.com/rust-lang/crates.io-index" 1650 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 1651 | dependencies = [ 1652 | "proc-macro2", 1653 | "quote", 1654 | "unicode-ident", 1655 | ] 1656 | 1657 | [[package]] 1658 | name = "syn" 1659 | version = "2.0.38" 1660 | source = "registry+https://github.com/rust-lang/crates.io-index" 1661 | checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" 1662 | dependencies = [ 1663 | "proc-macro2", 1664 | "quote", 1665 | "unicode-ident", 1666 | ] 1667 | 1668 | [[package]] 1669 | name = "system-configuration" 1670 | version = "0.5.1" 1671 | source = "registry+https://github.com/rust-lang/crates.io-index" 1672 | checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" 1673 | dependencies = [ 1674 | "bitflags 1.3.2", 1675 | "core-foundation", 1676 | "system-configuration-sys", 1677 | ] 1678 | 1679 | [[package]] 1680 | name = "system-configuration-sys" 1681 | version = "0.5.0" 1682 | source = "registry+https://github.com/rust-lang/crates.io-index" 1683 | checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" 1684 | dependencies = [ 1685 | "core-foundation-sys", 1686 | "libc", 1687 | ] 1688 | 1689 | [[package]] 1690 | name = "tempfile" 1691 | version = "3.8.0" 1692 | source = "registry+https://github.com/rust-lang/crates.io-index" 1693 | checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" 1694 | dependencies = [ 1695 | "cfg-if", 1696 | "fastrand", 1697 | "redox_syscall", 1698 | "rustix", 1699 | "windows-sys", 1700 | ] 1701 | 1702 | [[package]] 1703 | name = "termcolor" 1704 | version = "1.3.0" 1705 | source = "registry+https://github.com/rust-lang/crates.io-index" 1706 | checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" 1707 | dependencies = [ 1708 | "winapi-util", 1709 | ] 1710 | 1711 | [[package]] 1712 | name = "thiserror" 1713 | version = "1.0.50" 1714 | source = "registry+https://github.com/rust-lang/crates.io-index" 1715 | checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" 1716 | dependencies = [ 1717 | "thiserror-impl", 1718 | ] 1719 | 1720 | [[package]] 1721 | name = "thiserror-impl" 1722 | version = "1.0.50" 1723 | source = "registry+https://github.com/rust-lang/crates.io-index" 1724 | checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" 1725 | dependencies = [ 1726 | "proc-macro2", 1727 | "quote", 1728 | "syn 2.0.38", 1729 | ] 1730 | 1731 | [[package]] 1732 | name = "thread_local" 1733 | version = "1.1.7" 1734 | source = "registry+https://github.com/rust-lang/crates.io-index" 1735 | checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" 1736 | dependencies = [ 1737 | "cfg-if", 1738 | "once_cell", 1739 | ] 1740 | 1741 | [[package]] 1742 | name = "time" 1743 | version = "0.3.30" 1744 | source = "registry+https://github.com/rust-lang/crates.io-index" 1745 | checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" 1746 | dependencies = [ 1747 | "deranged", 1748 | "itoa", 1749 | "powerfmt", 1750 | "serde", 1751 | "time-core", 1752 | "time-macros", 1753 | ] 1754 | 1755 | [[package]] 1756 | name = "time-core" 1757 | version = "0.1.2" 1758 | source = "registry+https://github.com/rust-lang/crates.io-index" 1759 | checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" 1760 | 1761 | [[package]] 1762 | name = "time-macros" 1763 | version = "0.2.15" 1764 | source = "registry+https://github.com/rust-lang/crates.io-index" 1765 | checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" 1766 | dependencies = [ 1767 | "time-core", 1768 | ] 1769 | 1770 | [[package]] 1771 | name = "tinyvec" 1772 | version = "1.6.0" 1773 | source = "registry+https://github.com/rust-lang/crates.io-index" 1774 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 1775 | dependencies = [ 1776 | "tinyvec_macros", 1777 | ] 1778 | 1779 | [[package]] 1780 | name = "tinyvec_macros" 1781 | version = "0.1.1" 1782 | source = "registry+https://github.com/rust-lang/crates.io-index" 1783 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 1784 | 1785 | [[package]] 1786 | name = "tokio" 1787 | version = "1.33.0" 1788 | source = "registry+https://github.com/rust-lang/crates.io-index" 1789 | checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" 1790 | dependencies = [ 1791 | "backtrace", 1792 | "bytes", 1793 | "libc", 1794 | "mio", 1795 | "num_cpus", 1796 | "pin-project-lite", 1797 | "socket2 0.5.5", 1798 | "windows-sys", 1799 | ] 1800 | 1801 | [[package]] 1802 | name = "tokio-native-tls" 1803 | version = "0.3.1" 1804 | source = "registry+https://github.com/rust-lang/crates.io-index" 1805 | checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" 1806 | dependencies = [ 1807 | "native-tls", 1808 | "tokio", 1809 | ] 1810 | 1811 | [[package]] 1812 | name = "tokio-util" 1813 | version = "0.7.9" 1814 | source = "registry+https://github.com/rust-lang/crates.io-index" 1815 | checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d" 1816 | dependencies = [ 1817 | "bytes", 1818 | "futures-core", 1819 | "futures-sink", 1820 | "pin-project-lite", 1821 | "tokio", 1822 | "tracing", 1823 | ] 1824 | 1825 | [[package]] 1826 | name = "toml" 1827 | version = "0.5.11" 1828 | source = "registry+https://github.com/rust-lang/crates.io-index" 1829 | checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" 1830 | dependencies = [ 1831 | "serde", 1832 | ] 1833 | 1834 | [[package]] 1835 | name = "tower-service" 1836 | version = "0.3.2" 1837 | source = "registry+https://github.com/rust-lang/crates.io-index" 1838 | checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" 1839 | 1840 | [[package]] 1841 | name = "tracing" 1842 | version = "0.1.40" 1843 | source = "registry+https://github.com/rust-lang/crates.io-index" 1844 | checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" 1845 | dependencies = [ 1846 | "pin-project-lite", 1847 | "tracing-attributes", 1848 | "tracing-core", 1849 | ] 1850 | 1851 | [[package]] 1852 | name = "tracing-attributes" 1853 | version = "0.1.27" 1854 | source = "registry+https://github.com/rust-lang/crates.io-index" 1855 | checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" 1856 | dependencies = [ 1857 | "proc-macro2", 1858 | "quote", 1859 | "syn 2.0.38", 1860 | ] 1861 | 1862 | [[package]] 1863 | name = "tracing-core" 1864 | version = "0.1.32" 1865 | source = "registry+https://github.com/rust-lang/crates.io-index" 1866 | checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" 1867 | dependencies = [ 1868 | "once_cell", 1869 | "valuable", 1870 | ] 1871 | 1872 | [[package]] 1873 | name = "tracing-log" 1874 | version = "0.1.4" 1875 | source = "registry+https://github.com/rust-lang/crates.io-index" 1876 | checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" 1877 | dependencies = [ 1878 | "log", 1879 | "once_cell", 1880 | "tracing-core", 1881 | ] 1882 | 1883 | [[package]] 1884 | name = "tracing-subscriber" 1885 | version = "0.3.17" 1886 | source = "registry+https://github.com/rust-lang/crates.io-index" 1887 | checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" 1888 | dependencies = [ 1889 | "matchers", 1890 | "nu-ansi-term", 1891 | "once_cell", 1892 | "regex", 1893 | "sharded-slab", 1894 | "smallvec", 1895 | "thread_local", 1896 | "tracing", 1897 | "tracing-core", 1898 | "tracing-log", 1899 | ] 1900 | 1901 | [[package]] 1902 | name = "try-lock" 1903 | version = "0.2.4" 1904 | source = "registry+https://github.com/rust-lang/crates.io-index" 1905 | checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" 1906 | 1907 | [[package]] 1908 | name = "twox-hash" 1909 | version = "1.6.3" 1910 | source = "registry+https://github.com/rust-lang/crates.io-index" 1911 | checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" 1912 | dependencies = [ 1913 | "cfg-if", 1914 | "rand", 1915 | "static_assertions", 1916 | ] 1917 | 1918 | [[package]] 1919 | name = "typenum" 1920 | version = "1.17.0" 1921 | source = "registry+https://github.com/rust-lang/crates.io-index" 1922 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 1923 | 1924 | [[package]] 1925 | name = "unicase" 1926 | version = "2.7.0" 1927 | source = "registry+https://github.com/rust-lang/crates.io-index" 1928 | checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" 1929 | dependencies = [ 1930 | "version_check", 1931 | ] 1932 | 1933 | [[package]] 1934 | name = "unicode-bidi" 1935 | version = "0.3.13" 1936 | source = "registry+https://github.com/rust-lang/crates.io-index" 1937 | checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" 1938 | 1939 | [[package]] 1940 | name = "unicode-ident" 1941 | version = "1.0.12" 1942 | source = "registry+https://github.com/rust-lang/crates.io-index" 1943 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 1944 | 1945 | [[package]] 1946 | name = "unicode-normalization" 1947 | version = "0.1.22" 1948 | source = "registry+https://github.com/rust-lang/crates.io-index" 1949 | checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" 1950 | dependencies = [ 1951 | "tinyvec", 1952 | ] 1953 | 1954 | [[package]] 1955 | name = "unicorn-engine" 1956 | version = "2.0.1" 1957 | source = "registry+https://github.com/rust-lang/crates.io-index" 1958 | checksum = "f3b881bfd9837ff4f62e81a1e64b40a584604375ae0a73d0d5f09b7a72350b96" 1959 | dependencies = [ 1960 | "bitflags 1.3.2", 1961 | "cc", 1962 | "cmake", 1963 | "libc", 1964 | "pkg-config", 1965 | ] 1966 | 1967 | [[package]] 1968 | name = "uniffi" 1969 | version = "0.25.0" 1970 | source = "registry+https://github.com/rust-lang/crates.io-index" 1971 | checksum = "1f8995f4440e0e8e27435016e2bdec264445a830a3af91a40fe3ba34b69075c5" 1972 | dependencies = [ 1973 | "anyhow", 1974 | "camino", 1975 | "clap", 1976 | "uniffi_bindgen", 1977 | "uniffi_build", 1978 | "uniffi_core", 1979 | "uniffi_macros", 1980 | ] 1981 | 1982 | [[package]] 1983 | name = "uniffi_bindgen" 1984 | version = "0.25.0" 1985 | source = "registry+https://github.com/rust-lang/crates.io-index" 1986 | checksum = "6fb3dfb794733803cdfeff4c09cb4e2bcecb91df6928343a18c8ee679a5772a4" 1987 | dependencies = [ 1988 | "anyhow", 1989 | "askama", 1990 | "camino", 1991 | "cargo_metadata", 1992 | "clap", 1993 | "fs-err", 1994 | "glob", 1995 | "goblin", 1996 | "heck", 1997 | "once_cell", 1998 | "paste", 1999 | "serde", 2000 | "toml", 2001 | "uniffi_meta", 2002 | "uniffi_testing", 2003 | "uniffi_udl", 2004 | ] 2005 | 2006 | [[package]] 2007 | name = "uniffi_build" 2008 | version = "0.25.0" 2009 | source = "registry+https://github.com/rust-lang/crates.io-index" 2010 | checksum = "f2334eb7cf951fb80e4883593ac8d4f09f4df522f7703fc929ae34af2cf9487b" 2011 | dependencies = [ 2012 | "anyhow", 2013 | "camino", 2014 | "uniffi_bindgen", 2015 | ] 2016 | 2017 | [[package]] 2018 | name = "uniffi_checksum_derive" 2019 | version = "0.25.0" 2020 | source = "registry+https://github.com/rust-lang/crates.io-index" 2021 | checksum = "819bd46e5afff09738fbd493e58c26dca0b38bca8f206ffc9a7bc2dfd7e1c11d" 2022 | dependencies = [ 2023 | "quote", 2024 | "syn 2.0.38", 2025 | ] 2026 | 2027 | [[package]] 2028 | name = "uniffi_core" 2029 | version = "0.25.0" 2030 | source = "registry+https://github.com/rust-lang/crates.io-index" 2031 | checksum = "883166644d32c2e5c615c7917c8065eee1dd6ce00286b57d5ac0b362a0790422" 2032 | dependencies = [ 2033 | "anyhow", 2034 | "bytes", 2035 | "camino", 2036 | "log", 2037 | "once_cell", 2038 | "oneshot", 2039 | "paste", 2040 | "static_assertions", 2041 | ] 2042 | 2043 | [[package]] 2044 | name = "uniffi_macros" 2045 | version = "0.25.0" 2046 | source = "registry+https://github.com/rust-lang/crates.io-index" 2047 | checksum = "44b8de841c6b746e03e59b8476b2fa265c52f10cdad24906ec32503efe9a2421" 2048 | dependencies = [ 2049 | "bincode 1.3.3", 2050 | "camino", 2051 | "fs-err", 2052 | "once_cell", 2053 | "proc-macro2", 2054 | "quote", 2055 | "serde", 2056 | "syn 2.0.38", 2057 | "toml", 2058 | "uniffi_build", 2059 | "uniffi_meta", 2060 | ] 2061 | 2062 | [[package]] 2063 | name = "uniffi_meta" 2064 | version = "0.25.0" 2065 | source = "registry+https://github.com/rust-lang/crates.io-index" 2066 | checksum = "3dc021ae8f8c12f69022f1502537687df59045e1c16f5d1eafdb657ecdb7cdf1" 2067 | dependencies = [ 2068 | "anyhow", 2069 | "bytes", 2070 | "siphasher", 2071 | "uniffi_checksum_derive", 2072 | ] 2073 | 2074 | [[package]] 2075 | name = "uniffi_testing" 2076 | version = "0.25.0" 2077 | source = "registry+https://github.com/rust-lang/crates.io-index" 2078 | checksum = "40fe383aca04dfbdf6a5039a9e76bb21ebb13e03e38cf1459f17c62eedee7b6c" 2079 | dependencies = [ 2080 | "anyhow", 2081 | "camino", 2082 | "cargo_metadata", 2083 | "fs-err", 2084 | "once_cell", 2085 | ] 2086 | 2087 | [[package]] 2088 | name = "uniffi_udl" 2089 | version = "0.25.0" 2090 | source = "registry+https://github.com/rust-lang/crates.io-index" 2091 | checksum = "6040dd1410fcb1a2795ef426f698107c12e295cc11e44a2b040934f786a35d82" 2092 | dependencies = [ 2093 | "anyhow", 2094 | "uniffi_meta", 2095 | "uniffi_testing", 2096 | "weedle2", 2097 | ] 2098 | 2099 | [[package]] 2100 | name = "unty" 2101 | version = "0.0.3" 2102 | source = "registry+https://github.com/rust-lang/crates.io-index" 2103 | checksum = "a1a88342087869553c259588a3ec9ca73ce9b2d538b7051ba5789ff236b6c129" 2104 | 2105 | [[package]] 2106 | name = "url" 2107 | version = "2.4.1" 2108 | source = "registry+https://github.com/rust-lang/crates.io-index" 2109 | checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" 2110 | dependencies = [ 2111 | "form_urlencoded", 2112 | "idna 0.4.0", 2113 | "percent-encoding", 2114 | ] 2115 | 2116 | [[package]] 2117 | name = "utf8parse" 2118 | version = "0.2.1" 2119 | source = "registry+https://github.com/rust-lang/crates.io-index" 2120 | checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" 2121 | 2122 | [[package]] 2123 | name = "valuable" 2124 | version = "0.1.0" 2125 | source = "registry+https://github.com/rust-lang/crates.io-index" 2126 | checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" 2127 | 2128 | [[package]] 2129 | name = "vcpkg" 2130 | version = "0.2.15" 2131 | source = "registry+https://github.com/rust-lang/crates.io-index" 2132 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 2133 | 2134 | [[package]] 2135 | name = "version_check" 2136 | version = "0.9.4" 2137 | source = "registry+https://github.com/rust-lang/crates.io-index" 2138 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 2139 | 2140 | [[package]] 2141 | name = "virtue" 2142 | version = "0.0.15" 2143 | source = "registry+https://github.com/rust-lang/crates.io-index" 2144 | checksum = "3cd009c378216fd105fc950574281d279dcaf049ebd4ba5c61670521385cd1f6" 2145 | 2146 | [[package]] 2147 | name = "vmprotect" 2148 | version = "0.2.0" 2149 | source = "git+https://github.com/CertainLach/vmprotect.git#40023e0e82cfb8e3f2bd3351f975b54f49897bda" 2150 | dependencies = [ 2151 | "bitflags 1.3.2", 2152 | "chrono", 2153 | "enum_primitive", 2154 | "num-traits 0.2.17", 2155 | "real_c_string", 2156 | "vmprotect-macros", 2157 | "vmprotect-sys", 2158 | "widestring", 2159 | ] 2160 | 2161 | [[package]] 2162 | name = "vmprotect-macros" 2163 | version = "0.1.0" 2164 | source = "git+https://github.com/CertainLach/vmprotect.git#40023e0e82cfb8e3f2bd3351f975b54f49897bda" 2165 | dependencies = [ 2166 | "hex", 2167 | "quote", 2168 | "syn 1.0.109", 2169 | "twox-hash", 2170 | ] 2171 | 2172 | [[package]] 2173 | name = "vmprotect-sys" 2174 | version = "0.1.1" 2175 | source = "git+https://github.com/CertainLach/vmprotect.git#40023e0e82cfb8e3f2bd3351f975b54f49897bda" 2176 | 2177 | [[package]] 2178 | name = "walkdir" 2179 | version = "2.4.0" 2180 | source = "registry+https://github.com/rust-lang/crates.io-index" 2181 | checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" 2182 | dependencies = [ 2183 | "same-file", 2184 | "winapi-util", 2185 | ] 2186 | 2187 | [[package]] 2188 | name = "want" 2189 | version = "0.3.1" 2190 | source = "registry+https://github.com/rust-lang/crates.io-index" 2191 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 2192 | dependencies = [ 2193 | "try-lock", 2194 | ] 2195 | 2196 | [[package]] 2197 | name = "wasi" 2198 | version = "0.11.0+wasi-snapshot-preview1" 2199 | source = "registry+https://github.com/rust-lang/crates.io-index" 2200 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 2201 | 2202 | [[package]] 2203 | name = "wasm-bindgen" 2204 | version = "0.2.87" 2205 | source = "registry+https://github.com/rust-lang/crates.io-index" 2206 | checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" 2207 | dependencies = [ 2208 | "cfg-if", 2209 | "wasm-bindgen-macro", 2210 | ] 2211 | 2212 | [[package]] 2213 | name = "wasm-bindgen-backend" 2214 | version = "0.2.87" 2215 | source = "registry+https://github.com/rust-lang/crates.io-index" 2216 | checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" 2217 | dependencies = [ 2218 | "bumpalo", 2219 | "log", 2220 | "once_cell", 2221 | "proc-macro2", 2222 | "quote", 2223 | "syn 2.0.38", 2224 | "wasm-bindgen-shared", 2225 | ] 2226 | 2227 | [[package]] 2228 | name = "wasm-bindgen-futures" 2229 | version = "0.4.37" 2230 | source = "registry+https://github.com/rust-lang/crates.io-index" 2231 | checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" 2232 | dependencies = [ 2233 | "cfg-if", 2234 | "js-sys", 2235 | "wasm-bindgen", 2236 | "web-sys", 2237 | ] 2238 | 2239 | [[package]] 2240 | name = "wasm-bindgen-macro" 2241 | version = "0.2.87" 2242 | source = "registry+https://github.com/rust-lang/crates.io-index" 2243 | checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" 2244 | dependencies = [ 2245 | "quote", 2246 | "wasm-bindgen-macro-support", 2247 | ] 2248 | 2249 | [[package]] 2250 | name = "wasm-bindgen-macro-support" 2251 | version = "0.2.87" 2252 | source = "registry+https://github.com/rust-lang/crates.io-index" 2253 | checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" 2254 | dependencies = [ 2255 | "proc-macro2", 2256 | "quote", 2257 | "syn 2.0.38", 2258 | "wasm-bindgen-backend", 2259 | "wasm-bindgen-shared", 2260 | ] 2261 | 2262 | [[package]] 2263 | name = "wasm-bindgen-shared" 2264 | version = "0.2.87" 2265 | source = "registry+https://github.com/rust-lang/crates.io-index" 2266 | checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" 2267 | 2268 | [[package]] 2269 | name = "web-sys" 2270 | version = "0.3.64" 2271 | source = "registry+https://github.com/rust-lang/crates.io-index" 2272 | checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" 2273 | dependencies = [ 2274 | "js-sys", 2275 | "wasm-bindgen", 2276 | ] 2277 | 2278 | [[package]] 2279 | name = "weedle2" 2280 | version = "4.0.0" 2281 | source = "registry+https://github.com/rust-lang/crates.io-index" 2282 | checksum = "2e79c5206e1f43a2306fd64bdb95025ee4228960f2e6c5a8b173f3caaf807741" 2283 | dependencies = [ 2284 | "nom", 2285 | ] 2286 | 2287 | [[package]] 2288 | name = "widestring" 2289 | version = "0.4.3" 2290 | source = "registry+https://github.com/rust-lang/crates.io-index" 2291 | checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" 2292 | 2293 | [[package]] 2294 | name = "winapi" 2295 | version = "0.3.9" 2296 | source = "registry+https://github.com/rust-lang/crates.io-index" 2297 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 2298 | dependencies = [ 2299 | "winapi-i686-pc-windows-gnu", 2300 | "winapi-x86_64-pc-windows-gnu", 2301 | ] 2302 | 2303 | [[package]] 2304 | name = "winapi-i686-pc-windows-gnu" 2305 | version = "0.4.0" 2306 | source = "registry+https://github.com/rust-lang/crates.io-index" 2307 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 2308 | 2309 | [[package]] 2310 | name = "winapi-util" 2311 | version = "0.1.6" 2312 | source = "registry+https://github.com/rust-lang/crates.io-index" 2313 | checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" 2314 | dependencies = [ 2315 | "winapi", 2316 | ] 2317 | 2318 | [[package]] 2319 | name = "winapi-x86_64-pc-windows-gnu" 2320 | version = "0.4.0" 2321 | source = "registry+https://github.com/rust-lang/crates.io-index" 2322 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 2323 | 2324 | [[package]] 2325 | name = "windows" 2326 | version = "0.48.0" 2327 | source = "registry+https://github.com/rust-lang/crates.io-index" 2328 | checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" 2329 | dependencies = [ 2330 | "windows-targets", 2331 | ] 2332 | 2333 | [[package]] 2334 | name = "windows-core" 2335 | version = "0.51.1" 2336 | source = "registry+https://github.com/rust-lang/crates.io-index" 2337 | checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" 2338 | dependencies = [ 2339 | "windows-targets", 2340 | ] 2341 | 2342 | [[package]] 2343 | name = "windows-sys" 2344 | version = "0.48.0" 2345 | source = "registry+https://github.com/rust-lang/crates.io-index" 2346 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 2347 | dependencies = [ 2348 | "windows-targets", 2349 | ] 2350 | 2351 | [[package]] 2352 | name = "windows-targets" 2353 | version = "0.48.5" 2354 | source = "registry+https://github.com/rust-lang/crates.io-index" 2355 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 2356 | dependencies = [ 2357 | "windows_aarch64_gnullvm", 2358 | "windows_aarch64_msvc", 2359 | "windows_i686_gnu", 2360 | "windows_i686_msvc", 2361 | "windows_x86_64_gnu", 2362 | "windows_x86_64_gnullvm", 2363 | "windows_x86_64_msvc", 2364 | ] 2365 | 2366 | [[package]] 2367 | name = "windows_aarch64_gnullvm" 2368 | version = "0.48.5" 2369 | source = "registry+https://github.com/rust-lang/crates.io-index" 2370 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 2371 | 2372 | [[package]] 2373 | name = "windows_aarch64_msvc" 2374 | version = "0.48.5" 2375 | source = "registry+https://github.com/rust-lang/crates.io-index" 2376 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 2377 | 2378 | [[package]] 2379 | name = "windows_i686_gnu" 2380 | version = "0.48.5" 2381 | source = "registry+https://github.com/rust-lang/crates.io-index" 2382 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 2383 | 2384 | [[package]] 2385 | name = "windows_i686_msvc" 2386 | version = "0.48.5" 2387 | source = "registry+https://github.com/rust-lang/crates.io-index" 2388 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 2389 | 2390 | [[package]] 2391 | name = "windows_x86_64_gnu" 2392 | version = "0.48.5" 2393 | source = "registry+https://github.com/rust-lang/crates.io-index" 2394 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 2395 | 2396 | [[package]] 2397 | name = "windows_x86_64_gnullvm" 2398 | version = "0.48.5" 2399 | source = "registry+https://github.com/rust-lang/crates.io-index" 2400 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 2401 | 2402 | [[package]] 2403 | name = "windows_x86_64_msvc" 2404 | version = "0.48.5" 2405 | source = "registry+https://github.com/rust-lang/crates.io-index" 2406 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 2407 | 2408 | [[package]] 2409 | name = "winreg" 2410 | version = "0.50.0" 2411 | source = "registry+https://github.com/rust-lang/crates.io-index" 2412 | checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" 2413 | dependencies = [ 2414 | "cfg-if", 2415 | "windows-sys", 2416 | ] 2417 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "api", 4 | "cast_tool", 5 | ] 6 | 7 | default-members = ["api"] 8 | 9 | [profile.release] 10 | panic = "abort" 11 | opt-level = "z" 12 | lto = true 13 | strip = true -------------------------------------------------------------------------------- /README.en.md: -------------------------------------------------------------------------------- 1 | #### Project Description 2 | 3 | This project reverse-engineers the signature algorithm for Apple's caching server and can successfully register as a caching service. The algorithm runs in two modes. 4 | 5 | #### Running Modes 6 | 7 | 1. **Direct Execution (x64)**: Highly efficient but only supports 64-bit CPUs. Tested to work on Windows/Linux/macOS. 8 | 2. **Emulator Execution**: Extremely compatible and supports all CPU architectures, including arm64/mips64/riscv64. May be slightly slower. 9 | 10 | #### Compilation 11 | 12 | - Direct Execution: `cargo build --release` 13 | - Emulator Execution: `cargo build --release --features=emu` 14 | 15 | #### Configuration Files 16 | 17 | - `cache.json`: Used for setting up IP ranges, similar to macOS options. 18 | - `mac.toml`: Stores machine code information and can be reused on a new Mac machine. Ensure that all five codes are unified. 19 | 20 | #### Third-Party Bindings 21 | 22 | - Python bindings are supported; you can directly run `register.py`` to use them. 23 | - For `Kotlin/Swift`, please generate the bindings accordingly. 24 | 25 | #### Future Plans 26 | 27 | 1. Expose easy-to-use APIs via cxx for other programming languages (e.g., C++). 28 | 2. Transcompile the code by simulating the traces to llvm-ir, and then lifting it to C code. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [View as English](./README.en.md) 4 | 5 | #### 项目描述 6 | 7 | 本项目通过逆向得到苹果缓存服务器的签名算法,并可以成功注册缓存服务。算法分为两种运行模式。 8 | 9 | #### 运行模式 10 | 11 | 1. **直接运行(x64)**: 效率较高,但只支持64位CPU。已测试可运行在Windows/Linux/macOS上。 12 | 2. **模拟器运行**: 兼容性极高,支持所有CPU架构,包括arm64/mips64/riscv64等。速度可能稍慢。 13 | 14 | #### 编译方式 15 | 16 | - 直接运行: `cargo build --release` 17 | - 模拟运行: `cargo build --release --features=emu` 18 | 19 | #### 配置文件 20 | 21 | - `cache.json`: 用于设置IP段,与macOS选项相同。 22 | - `mac.toml`: 存储机器码信息,可以通过相关注释在一台新的Mac上使用。注意五码必须合一。 23 | 24 | #### 第三方绑定 25 | 26 | - 支持`python`绑定,直接运行`register.py`即可 27 | - `Kotlin/Swift`类似,请自行生成绑定即可. 28 | 29 | #### 未来计划 30 | 31 | 1. 通过cxx暴露易用的调用接口,支持多种编程语言(如C++)。 32 | 2. 转译相关代码,通过模拟轨迹转换成llvm-ir,然后提升成C代码。 -------------------------------------------------------------------------------- /api/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "api" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | goblin = "0.6.0" 8 | anyhow = "1.0" 9 | region = "3.0.0" 10 | libc = "0.2" 11 | hex = "0.4.3" 12 | log = "0.4" 13 | rust-embed = { version = "6.4.2", features = ["include-exclude"] } 14 | serde = { version = "1.0", features = ["derive"] } 15 | serde_derive = "1.0" 16 | bincode = { git = "https://github.com/bincode-org/bincode.git" } 17 | base64 = "0.13.1" 18 | reqwest = { version = "0.11", features = ["blocking", "json", "cookies"] } 19 | serde_json = "1.0" 20 | vmprotect = { git = "https://github.com/CertainLach/vmprotect.git", optional = true } 21 | unicorn-engine = { version = "2.0.1", optional = true } 22 | openssl = { version = "0.10", features = ["vendored"] } 23 | env_logger = "0.10.0" 24 | toml = "0.5.10" 25 | uniffi = { version = "0.25.0", features = ["cli"]} 26 | thiserror = "1.0.50" 27 | 28 | [features] 29 | default = [] 30 | rel = ["vmprotect"] 31 | emu = ["unicorn-engine"] 32 | osx = [] 33 | 34 | [build-dependencies] 35 | uniffi = { version = "0.25", features = [ "build" ] } 36 | 37 | [lib] 38 | crate-type = ["cdylib"] 39 | name = "apple_cache" 40 | 41 | [[bin]] 42 | name = "uniffi-bindgen" 43 | path = "src/uniffi-bindgen.rs" 44 | -------------------------------------------------------------------------------- /api/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | uniffi::generate_scaffolding("src/lib.udl").unwrap(); 3 | } -------------------------------------------------------------------------------- /api/src/cache/cache.rs: -------------------------------------------------------------------------------- 1 | use crate::{macho::MachoLoader, patch}; 2 | use anyhow::{Result, Context}; 3 | use rust_embed::RustEmbed; 4 | use bincode::config; 5 | use std::ffi::c_void; 6 | 7 | #[derive(RustEmbed)] 8 | #[folder = "../blob"] 9 | #[include = "AssetCache~.x64"] 10 | #[include = "cert.cer"] 11 | #[include = "reloc.bin"] 12 | struct Asset; 13 | 14 | pub struct Cache 15 | { 16 | loader: MachoLoader, 17 | } 18 | 19 | impl Cache 20 | { 21 | pub fn new() -> Result 22 | { 23 | // read from memory. 24 | let file = Asset::get("AssetCache~.x64").context("")?; 25 | let loader = MachoLoader::new(&file.data, patch::register_fn)?; 26 | // TODO: 等待移除 27 | let config = config::standard(); 28 | let file = Asset::get("reloc.bin").context("")?; 29 | let (relocs,_ ): (Vec, usize) = bincode::decode_from_slice(&file.data, config)?; 30 | unsafe { loader.fixup_relocs(&relocs) } 31 | Ok(Cache { loader }) 32 | } 33 | 34 | pub fn offset(&self, addr: usize) -> usize 35 | { 36 | self.loader.get_offset(addr) 37 | } 38 | 39 | pub fn create(&self, _cert: Option<&[u8]>) -> Result<(usize, Vec)> 40 | { 41 | let cert = Asset::get("cert.cer").context("")?; 42 | let pcert = &cert.data; 43 | let func: extern "sysv64" fn(*const u8, usize, *mut usize, *mut *const c_void, *mut i32) -> i32 = 44 | unsafe { core::mem::transmute(self.offset(0x1000d2f30))}; 45 | 46 | let mut ctx: usize = 0; 47 | let mut data: *const c_void = 0 as _; 48 | let mut data_len: i32 = 0; 49 | let result = func(pcert.as_ptr(), pcert.len(), &mut ctx, &mut data, &mut data_len); 50 | 51 | if result != 0 { 52 | unreachable!() 53 | } else { 54 | let data = unsafe { std::slice::from_raw_parts(data as *const u8, data_len as usize).to_owned() }; 55 | Ok((ctx, data)) 56 | } 57 | } 58 | 59 | pub fn obtain(&self, ctx: usize, session: &[u8]) -> Result<()> 60 | { 61 | let func: extern "sysv64" fn(usize, *const c_void, i32) -> i32 = 62 | unsafe { core::mem::transmute(self.offset(0x100125a50))}; 63 | let result = func(ctx, session.as_ptr() as _, session.len() as i32); 64 | 65 | if result != 0 { 66 | unreachable!() 67 | } else { 68 | Ok(()) 69 | } 70 | } 71 | 72 | pub fn sign(&self, ctx: usize, data: &[u8]) -> Result> 73 | { 74 | let func: extern "sysv64" fn(usize, *const c_void, i32, *mut *const c_void, *mut i32) -> i32 = 75 | unsafe { core::mem::transmute(self.offset(0x1000c5860))}; 76 | let mut ret_data: *const c_void = 0 as _; 77 | let mut data_len: i32 = 0; 78 | let result = func(ctx, data.as_ptr() as _, data.len() as i32, &mut ret_data, &mut data_len); 79 | 80 | if result != 0 { 81 | unreachable!() 82 | } else { 83 | let data = unsafe { std::slice::from_raw_parts(ret_data as *const u8, data_len as usize).to_owned() }; 84 | Ok(data) 85 | } 86 | } 87 | } -------------------------------------------------------------------------------- /api/src/cache/emulator.rs: -------------------------------------------------------------------------------- 1 | use crate::{macho::MachoLoader, patch}; 2 | use anyhow::{Result, Context}; 3 | use rust_embed::RustEmbed; 4 | use unicorn_engine::{Unicorn, unicorn_const::{Arch, Mode}}; 5 | 6 | #[derive(RustEmbed)] 7 | #[folder = "../blob"] 8 | #[include = "AssetCache~.x64"] 9 | #[include = "cert.cer"] 10 | struct Asset; 11 | 12 | pub struct Cache<'a> 13 | { 14 | loader: MachoLoader, 15 | uc: Unicorn<'a, ()>, 16 | } 17 | 18 | impl <'a>Cache<'a> 19 | { 20 | pub fn new() -> Result> 21 | { 22 | // read from memory. 23 | let file = Asset::get("AssetCache~.x64").context("")?; 24 | let data = file.data; 25 | let mut uc = Unicorn::new(Arch::X86, Mode::LITTLE_ENDIAN | Mode::MODE_64).unwrap(); 26 | let loader = MachoLoader::new(&data, &mut uc, patch::register_fn)?; 27 | // install function hook 28 | patch::regiser_init(&mut uc); 29 | Ok(Cache { loader, uc }) 30 | } 31 | 32 | pub fn offset(&self, addr: u64) -> u64 33 | { 34 | self.loader.get_offset(addr) 35 | } 36 | 37 | pub fn create(&mut self, _cert: Option<&[u8]>) -> Result<(u64, Vec)> 38 | { 39 | let cert = Asset::get("cert.cer").context("")?; 40 | let pcert = &cert.data; 41 | patch::call_0(&mut self.uc, &pcert) 42 | } 43 | 44 | pub fn obtain(&mut self, ctx: u64, session: &[u8]) -> Result<()> 45 | { 46 | patch::call_1(&mut self.uc, ctx, session) 47 | } 48 | 49 | pub fn sign(&mut self, ctx: u64, data: &[u8]) -> Result> 50 | { 51 | patch::call_2(&mut self.uc, ctx, data) 52 | } 53 | } -------------------------------------------------------------------------------- /api/src/cache/mod.rs: -------------------------------------------------------------------------------- 1 | 2 | 3 | #[cfg(feature = "emu")] 4 | mod emulator; 5 | #[cfg(feature = "emu")] 6 | pub use self::emulator::*; 7 | 8 | #[cfg(not(feature = "emu"))] 9 | mod cache; 10 | #[cfg(not(feature = "emu"))] 11 | pub use self::cache::*; -------------------------------------------------------------------------------- /api/src/emu.rs: -------------------------------------------------------------------------------- 1 | use core::slice::memchr::memchr; 2 | use std::ffi::CString; 3 | 4 | use unicorn_engine::{Unicorn, unicorn_const::{Permission, uc_error}, RegisterX86}; 5 | use anyhow::Result; 6 | 7 | fn align(a: u64, v: u64) -> u64 8 | { 9 | ((a - 1) & !(v - 1)) + v 10 | } 11 | 12 | fn alignb(a: u64, v: u64) -> u64 13 | { 14 | a & !(v - 1) 15 | } 16 | 17 | pub fn emu_map<'a>(uc: &mut Unicorn<'a, ()>, 18 | address: u64, 19 | size: libc::size_t, 20 | perms: Permission) -> Result<(), uc_error> 21 | { 22 | let start = alignb(address, 0x1000u64); 23 | let end = align(address + size as u64, 0x1000u64); 24 | uc.mem_map(start, (end - start) as usize, perms) 25 | } 26 | 27 | pub fn emu_writep<'a>(uc: &mut Unicorn<'a, ()>, address: u64, ptr: u64) 28 | -> Result<(), uc_error> 29 | { 30 | let ptr = ptr.to_le(); 31 | if let Err(e) = uc.mem_write(address, as_u8_slice(&ptr)) { 32 | return Err(e) 33 | } else { 34 | Ok(()) 35 | } 36 | } 37 | 38 | pub fn emu_readp<'a>(uc: &mut Unicorn<'a, ()>, address: u64) 39 | -> Result 40 | { 41 | let mut ret: u64 = 0; 42 | if let Err(e) = uc.mem_read(address, as_u8_slice_mut(&mut ret)) { 43 | return Err(e) 44 | } else { 45 | Ok(u64::from_le(ret)) 46 | } 47 | } 48 | 49 | pub fn emu_reads<'a>(uc: &mut Unicorn<'a, ()>, address: u64) 50 | -> Result 51 | { 52 | let mut v = vec![0u8; 1024]; 53 | // TODO: use resize to get more. 54 | if let Err(e) = uc.mem_read(address, &mut v) { 55 | return Err(e) 56 | } else { 57 | let len = memchr(0, &v).unwrap_or(v.len()); 58 | let s = unsafe { CString::from_vec_unchecked(v[..len].to_vec()) }.into_string().unwrap(); 59 | Ok(s) 60 | } 61 | } 62 | 63 | pub fn emu_writes<'a>(uc: &mut Unicorn<'a, ()>, address: u64, s: String) 64 | -> Result<(), uc_error> 65 | { 66 | emu_writev(uc, address, s.as_bytes()) 67 | } 68 | 69 | pub fn emu_writev<'a>(uc: &mut Unicorn<'a, ()>, address: u64, v: &[u8]) 70 | -> Result<(), uc_error> 71 | { 72 | if let Err(e) = uc.mem_write(address, v) { 73 | return Err(e) 74 | } else { 75 | Ok(()) 76 | } 77 | } 78 | 79 | pub fn as_u8_slice(p: &T) -> &[u8] { 80 | unsafe { 81 | ::std::slice::from_raw_parts( 82 | (p as *const T) as *const u8, 83 | ::std::mem::size_of::(), 84 | ) 85 | } 86 | } 87 | 88 | pub fn as_u8_slice_mut(p: &mut T) -> &mut [u8] { 89 | unsafe { 90 | ::std::slice::from_raw_parts_mut( 91 | (p as *mut T) as *mut u8, 92 | ::std::mem::size_of::(), 93 | ) 94 | } 95 | } 96 | 97 | pub fn emu_set_param<'a>(uc: &mut Unicorn<'a, ()>, idx: u32, ptr: u64) -> Result<(), uc_error> 98 | { 99 | if idx < 6 { 100 | let regid = match idx { 101 | 0 => RegisterX86::RDI, 102 | 1 => RegisterX86::RSI, 103 | 2 => RegisterX86::RDX, 104 | 3 => RegisterX86::RCX, 105 | 4 => RegisterX86::R8, 106 | 5 => RegisterX86::R9, 107 | // TODO: error 108 | _ => RegisterX86::RAX, 109 | }; 110 | uc.reg_write(regid, ptr) 111 | } else { 112 | match uc.reg_read(RegisterX86::RSP) 113 | { 114 | Ok(rsp) => { 115 | emu_writep(uc, rsp + 8 * (idx as u64 - 5), ptr) 116 | }, 117 | Err(e) => { 118 | Err(e) 119 | } 120 | } 121 | } 122 | } 123 | 124 | pub fn emu_get_param<'a>(uc: &mut Unicorn<'a, ()>, idx: u32) -> Result 125 | { 126 | if idx < 6 { 127 | let regid = match idx { 128 | // TODO: error 129 | 0 => RegisterX86::RDI, 130 | 1 => RegisterX86::RSI, 131 | 2 => RegisterX86::RDX, 132 | 3 => RegisterX86::RCX, 133 | 4 => RegisterX86::R8, 134 | 5 => RegisterX86::R9, 135 | _ => RegisterX86::RAX, 136 | }; 137 | uc.reg_read(regid) 138 | } else { 139 | match uc.reg_read(RegisterX86::RSP) 140 | { 141 | Ok(rsp) => { 142 | emu_readp(uc, rsp + 8 * (idx as u64 - 5)) 143 | }, 144 | Err(e) => { 145 | Err(e) 146 | } 147 | } 148 | } 149 | } -------------------------------------------------------------------------------- /api/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(non_snake_case)] 2 | #![feature(exclusive_range_pattern)] 3 | #![feature(slice_internals)] 4 | 5 | use cache::Cache; 6 | 7 | mod patch; 8 | mod macho; 9 | mod cache; 10 | mod mac_serial; 11 | 12 | #[cfg(feature = "emu")] 13 | mod emu; 14 | 15 | #[derive(Debug, thiserror::Error)] 16 | pub enum CacheError { 17 | #[error("failed. {0}!")] 18 | HandleFailed(String), 19 | } 20 | 21 | #[derive(Debug, Clone)] 22 | pub struct CacheResult { 23 | ctx: u64, 24 | data: Vec, 25 | } 26 | 27 | type Result = std::result::Result; 28 | 29 | pub struct CacheApi { 30 | c: Cache, 31 | } 32 | 33 | impl CacheApi { 34 | pub fn new() -> Result { 35 | match Cache::new() { 36 | Ok(c) => Ok(Self { c }), 37 | Err(e) => Err(CacheError::HandleFailed(e.to_string())) 38 | } 39 | } 40 | 41 | pub fn create(&self, cert: Option>) -> Result { 42 | match self.c.create(Some(&cert.unwrap_or_default())) { 43 | Ok((ctx, data)) => { 44 | Ok(CacheResult { ctx: ctx as u64, data }) 45 | }, 46 | Err(e) => Err(CacheError::HandleFailed(e.to_string())) 47 | } 48 | } 49 | 50 | pub fn obtain(&self, ctx: u64, session: Vec) -> Result<(), CacheError> { 51 | match self.c.obtain(ctx as usize, &session) { 52 | Ok(_) => { 53 | Ok(()) 54 | }, 55 | Err(e) => Err(CacheError::HandleFailed(e.to_string())) 56 | } 57 | } 58 | 59 | pub fn sign(&self, ctx: u64, data: Vec) -> Result, CacheError> { 60 | match self.c.sign(ctx as usize, &data) { 61 | Ok(d) => { 62 | Ok(d) 63 | }, 64 | Err(e) => Err(CacheError::HandleFailed(e.to_string())) 65 | } 66 | } 67 | } 68 | 69 | pub fn init_serial(serial: String) -> Result<()> { 70 | if let Err(e) = mac_serial::MacSerial::instance().init_from_json(&serial) { 71 | return Err(CacheError::HandleFailed(e.to_string())); 72 | } 73 | Ok(()) 74 | } 75 | 76 | unsafe impl Send for CacheApi {} 77 | 78 | uniffi::include_scaffolding!("lib"); -------------------------------------------------------------------------------- /api/src/lib.udl: -------------------------------------------------------------------------------- 1 | namespace apple_cache { 2 | [Throws=CacheError] 3 | void init_serial(string serial); 4 | }; 5 | 6 | [Error] 7 | enum CacheError { 8 | "HandleFailed", 9 | }; 10 | 11 | dictionary CacheResult { 12 | u64 ctx; 13 | sequence data; 14 | }; 15 | 16 | interface CacheApi { 17 | [Throws=CacheError] 18 | constructor(); 19 | [Throws=CacheError] 20 | CacheResult create(sequence? cert); 21 | [Throws=CacheError] 22 | void obtain(u64 ctx, sequence session); 23 | [Throws=CacheError] 24 | sequence sign(u64 ctx, sequence data); 25 | }; 26 | -------------------------------------------------------------------------------- /api/src/mac_serial.rs: -------------------------------------------------------------------------------- 1 | use std::fs; 2 | use serde::Deserialize; 3 | 4 | use anyhow::Result; 5 | 6 | #[derive(Default, Deserialize, Debug)] 7 | pub(crate) 8 | struct MacSerial 9 | { 10 | pub osversion: String, 11 | pub osrevision: u32, 12 | pub board_id: String, 13 | pub product_name: String, 14 | pub boot_uuid: String, 15 | pub serial_number: String, 16 | pub uuid: String, 17 | pub mac_address: String, 18 | pub rom: String, 19 | pub mlb: String, 20 | #[serde(rename = "Gq3489ugfi")] 21 | pub gq_serial: String, 22 | #[serde(rename = "Fyp98tpgj")] 23 | pub fy_serial: String, 24 | #[serde(rename = "kbjfrfpoJU")] 25 | pub kb_serial: String, 26 | #[serde(rename = "oycqAZloTNDm")] 27 | pub oy_serial: String, 28 | #[serde(rename = "abKPld1EcMni")] 29 | pub ab_serial: String, 30 | } 31 | 32 | impl MacSerial 33 | { 34 | fn new() -> Self 35 | { 36 | MacSerial { .. Default::default() } 37 | } 38 | 39 | pub fn instance() -> &'static mut MacSerial { 40 | static mut MACSERIAL: Option = None; 41 | unsafe { 42 | match MACSERIAL { 43 | Some(ref mut s) => s, 44 | None => { 45 | let s = MacSerial::new(); 46 | MACSERIAL = Some(s); 47 | MACSERIAL.as_mut().unwrap() 48 | } 49 | } 50 | } 51 | } 52 | 53 | fn zero(s: String) -> String 54 | { 55 | format!("{}\x00", s) 56 | } 57 | 58 | pub fn init(&mut self) -> Result<()> 59 | { 60 | let s = fs::read("mac.toml")?; 61 | let conf: MacSerial = toml::from_slice(&s)?; 62 | 63 | self.copy_from_str(conf) 64 | } 65 | 66 | fn copy_from_str(&mut self, conf: MacSerial) -> Result<()> { 67 | self.osversion = Self::zero(conf.osversion); 68 | self.osrevision = conf.osrevision; 69 | 70 | self.board_id = Self::zero(hex::encode(Self::zero(conf.board_id))); 71 | self.product_name = Self::zero(hex::encode(Self::zero(conf.product_name))); 72 | self.boot_uuid = Self::zero(hex::encode(Self::zero(conf.boot_uuid))); 73 | self.serial_number = Self::zero(conf.serial_number); 74 | self.uuid = Self::zero(conf.uuid); 75 | self.mac_address = Self::zero(conf.mac_address); 76 | self.rom = Self::zero(conf.rom); 77 | self.mlb = Self::zero(hex::encode(conf.mlb)); 78 | self.gq_serial = Self::zero(conf.gq_serial.to_lowercase()); 79 | self.fy_serial = Self::zero(conf.fy_serial.to_lowercase()); 80 | self.kb_serial = Self::zero(conf.kb_serial.to_lowercase()); 81 | self.oy_serial = Self::zero(conf.oy_serial.to_lowercase()); 82 | self.ab_serial = Self::zero(conf.ab_serial.to_lowercase()); 83 | 84 | Ok(()) 85 | } 86 | 87 | pub fn init_from_json(&mut self, json: &str) -> Result<()> { 88 | let conf: MacSerial = serde_json::from_str(json)?; 89 | self.copy_from_str(conf) 90 | } 91 | } -------------------------------------------------------------------------------- /api/src/macho/emulator.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use goblin::mach; 3 | use unicorn_engine::{Unicorn, unicorn_const::Permission}; 4 | 5 | use crate::emu::{emu_map, emu_writep}; 6 | 7 | pub struct MachoLoader 8 | { 9 | image_base: u64, 10 | base_addr: u64, 11 | } 12 | 13 | pub type SymbolCallback = fn (dylib: &str, name: &str) -> u64; 14 | 15 | impl MachoLoader 16 | { 17 | pub fn new(file: &[u8], uc: &mut Unicorn<()>, callback: SymbolCallback) -> Result 18 | { 19 | let macho = mach::Mach::parse(&file)?; 20 | let loader = match macho { 21 | mach::Mach::Fat(_bin) => { 22 | // TODO: use Fat. 23 | log::error!("+ does not support fat yet"); 24 | unreachable!() 25 | } 26 | mach::Mach::Binary(bin) => { 27 | let mut loader = MachoLoader { image_base: 0x100000000u64, base_addr: 0x100000000u64 }; 28 | loader.init(&bin, &file, uc, callback)?; 29 | loader 30 | } 31 | }; 32 | Ok(loader) 33 | } 34 | pub fn get_offset(&self, addr: u64) -> u64 35 | { 36 | addr 37 | } 38 | 39 | fn init(&mut self, macho: &mach::MachO, file: &[u8], uc: &mut Unicorn<()>, callback: SymbolCallback) -> Result<()> 40 | { 41 | // 计算镜像大小 42 | let mut image_end = self.image_base; 43 | for sec in &macho.segments { 44 | if sec.filesize == 0 { 45 | continue; 46 | } 47 | let end = sec.vmaddr + sec.filesize; 48 | if end > image_end { 49 | image_end = end; 50 | } 51 | } 52 | let image_size = image_end - self.image_base; 53 | log::info!("+ alloc image size {:x}", image_size); 54 | // 映射内存 55 | if let Err(e) = emu_map(uc, self.base_addr, image_size as usize, Permission::ALL) { 56 | log::error!("+ failed map: {:x} {:?}", self.base_addr, e); 57 | } 58 | 59 | // 写入数据 60 | for sec in &macho.segments { 61 | // TODO: padding 62 | if let Err(e) = uc.mem_write(sec.vmaddr, &file[sec.fileoff as usize .. (sec.fileoff + sec.filesize) as usize]) { 63 | log::error!("+ failed write: {:x} {:?}", sec.vmaddr, e); 64 | } 65 | } 66 | log::info!("+ write done."); 67 | 68 | // 导入符号 69 | for imp in macho.imports()? { 70 | // TODO: may use 71 | if imp.is_lazy { 72 | continue; 73 | } 74 | let new_addr = (callback(imp.dylib, imp.name) as i64 + imp.addend) as u64; 75 | let addr = self.get_offset(imp.address); 76 | if let Err(e) = emu_writep(uc, addr, new_addr) { 77 | log::error!("+ failed write: {:x} {:x?}, {:?}", addr, new_addr, e); 78 | } 79 | } 80 | log::info!("+ done."); 81 | Ok(()) 82 | } 83 | } -------------------------------------------------------------------------------- /api/src/macho/macho.rs: -------------------------------------------------------------------------------- 1 | use std::ffi::c_void; 2 | use anyhow::Result; 3 | use goblin::mach; 4 | use region::Allocation; 5 | 6 | #[derive(Default)] 7 | pub struct MachoLoader 8 | { 9 | image_base: usize, 10 | base_addr: usize, 11 | page: Option, 12 | } 13 | 14 | pub type SymbolCallback = fn (dylib: &str, name: &str) -> usize; 15 | 16 | impl MachoLoader 17 | { 18 | pub fn new(file: &[u8], callback: SymbolCallback) -> Result 19 | { 20 | let macho = mach::Mach::parse(&file)?; 21 | let loader = match macho { 22 | mach::Mach::Fat(_bin) => { 23 | // TODO: use Fat. 24 | log::error!("+ does not support fat yet"); 25 | unreachable!() 26 | } 27 | mach::Mach::Binary(bin) => { 28 | let mut loader = MachoLoader { .. Default::default() }; 29 | loader.init(&bin, file, callback)?; 30 | loader 31 | } 32 | }; 33 | Ok(loader) 34 | } 35 | pub fn get_offset(&self, addr: usize) -> usize 36 | { 37 | self.base_addr - self.image_base + addr 38 | } 39 | 40 | fn init(&mut self, macho: &mach::MachO, file: &[u8], callback: SymbolCallback) -> Result<()> 41 | { 42 | // TODO: read from macho 43 | self.image_base = 0x100000000usize; 44 | // 计算镜像大小 45 | let mut image_end = self.image_base; 46 | for sec in &macho.segments { 47 | if sec.filesize == 0 { 48 | continue; 49 | } 50 | let end = (sec.vmaddr + sec.filesize) as usize; 51 | if end > image_end { 52 | image_end = end; 53 | } 54 | } 55 | let image_size = image_end - self.image_base; 56 | log::info!("+ alloc image size {:x}", image_size); 57 | // 映射内存 58 | let page = region::alloc(image_size, region::Protection::READ_WRITE_EXECUTE)?; 59 | self.base_addr = page.as_ptr() as *const c_void as usize; 60 | self.set_allocation(Box::new(page)); 61 | 62 | // 写入数据 63 | for sec in &macho.segments { 64 | // TODO: padding 65 | unsafe { 66 | core::ptr::copy_nonoverlapping( 67 | (file.as_ptr() as *mut u8).offset(sec.fileoff as isize), self.get_offset(sec.vmaddr as usize) as _, sec.filesize as usize 68 | ); 69 | } 70 | } 71 | 72 | // 导入符号 73 | for imp in macho.imports()? { 74 | // TODO: may use 75 | if imp.is_lazy { 76 | continue; 77 | } 78 | let new_addr = (callback(imp.dylib, imp.name) as i64 + imp.addend) as usize; 79 | let addr = self.get_offset(imp.address as usize); 80 | unsafe { core::ptr::write(addr as *mut usize, new_addr) }; 81 | } 82 | Ok(()) 83 | } 84 | 85 | // TODO: Removed after repairing the relocation table 86 | pub unsafe fn fixup_relocs(&self, relocs: &[usize]) 87 | { 88 | for v in relocs { 89 | let ptr: *mut usize = self.get_offset(v + self.image_base) as _; 90 | if *ptr > self.image_base { 91 | *ptr -= self.image_base; 92 | } 93 | *ptr += self.base_addr; 94 | } 95 | } 96 | 97 | pub fn set_allocation(&mut self, allocation: Box) { 98 | let allocation_ptr = Box::into_raw(allocation) as *mut Allocation as usize; 99 | self.page = Some(allocation_ptr); 100 | } 101 | 102 | pub fn release_allocation(&mut self) { 103 | if let Some(allocation_ptr) = self.page { 104 | unsafe { 105 | let _allocation = Box::from_raw(allocation_ptr as *mut Allocation); 106 | } 107 | } 108 | self.page = None; 109 | } 110 | } 111 | 112 | impl Drop for MachoLoader 113 | { 114 | fn drop(&mut self) { 115 | self.release_allocation() 116 | } 117 | } -------------------------------------------------------------------------------- /api/src/macho/mod.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "emu")] 2 | mod emulator; 3 | #[cfg(feature = "emu")] 4 | pub use self::emulator::*; 5 | 6 | #[cfg(not(feature = "emu"))] 7 | mod macho; 8 | #[cfg(not(feature = "emu"))] 9 | pub use self::macho::*; -------------------------------------------------------------------------------- /api/src/main.rs: -------------------------------------------------------------------------------- 1 | #![allow(non_snake_case)] 2 | #![feature(exclusive_range_pattern)] 3 | #![feature(slice_internals)] 4 | use std::fs; 5 | use anyhow::{Result, Context}; 6 | #[cfg(feature = "rel")] 7 | use vmprotect::licensing::{set_serial_number, get_hwid}; 8 | 9 | // use crate::osx::register_fn; 10 | // mod osx; 11 | 12 | mod patch; 13 | 14 | mod macho; 15 | mod cache; 16 | 17 | #[cfg(feature = "emu")] 18 | mod emu; 19 | 20 | mod mac_serial; 21 | fn main() -> Result<()> { 22 | // init log 23 | env_logger::init(); 24 | // init serial 25 | mac_serial::MacSerial::instance().init()?; 26 | // check vmp 27 | #[cfg(feature = "rel")] 28 | { 29 | let serial = fs::read("serial")?; 30 | let license = set_serial_number(serial)?; 31 | if !license.is_success() { 32 | println!("hwid: {}", get_hwid()); 33 | return Err(anyhow::anyhow!("License Failed, {:?}", license)); 34 | } 35 | } 36 | 37 | let mut template: serde_json::Value = serde_json::from_slice(&fs::read("cache.json")?)?; 38 | let mut c = cache::Cache::new()?; 39 | let (ctx, res) = c.create(None)?; 40 | let data = base64::encode(res); 41 | println!("+ res: {:x}, {}", ctx, data); 42 | let mut headers = reqwest::header::HeaderMap::new(); 43 | headers.insert(reqwest::header::USER_AGENT, "AssetCache/243 CFNetwork/1111 Darwin/19.0.0 (x86_64)".parse()?); 44 | headers.insert("X-Protocol-Version", "3".parse()?); 45 | let client = reqwest::blocking::Client::builder() 46 | .default_headers(headers) 47 | .cookie_store(true) 48 | .danger_accept_invalid_certs(true) 49 | .build()?; 50 | let resp = client.post("https://lcdn-registration.apple.com/lcdn/session") 51 | .body(data) 52 | .send()?; 53 | // Got cookies 54 | let lcdn = resp.cookies().find_map(|c| 55 | if c.name() == "LCDN-Session" { 56 | Some(c.value().to_owned()) 57 | } else { None } ).context("cookies Not found.")?; 58 | println!("+ LCDN: {}", lcdn); 59 | 60 | let data = resp.text()?; 61 | println!("+ Got {}", data); 62 | 63 | let data = data.trim_matches('"'); 64 | let data = data.replace("\\u003d", "="); 65 | let data = base64::decode(data)?; 66 | println!("+ Obtain: {:?}", c.obtain(ctx, &data)); 67 | 68 | // json data 69 | if let serde_json::Value::Object(ref mut map) = template { 70 | map.insert("session-token".to_owned(), lcdn.into()); 71 | } 72 | let data = template.to_string(); 73 | 74 | // Register 75 | let data = c.sign(ctx, data.as_bytes())?; 76 | let data = base64::encode(data); 77 | println!("+ Sign: {}", data); 78 | 79 | let resp = client.post("https://lcdn-registration.apple.com/lcdn/register") 80 | .body(data) 81 | .send()?; 82 | let text = resp.text()?; 83 | println!("+ Register: {}", text); 84 | 85 | // // 获取心跳延迟 86 | 87 | 88 | Ok(()) 89 | } 90 | -------------------------------------------------------------------------------- /api/src/patch/emulator.rs: -------------------------------------------------------------------------------- 1 | use std::ffi::CString; 2 | 3 | use unicorn_engine::{Unicorn, unicorn_const::{Permission, MemType, HookType}, RegisterX86}; 4 | use anyhow::Result; 5 | use crate::emu::{emu_map, emu_readp, emu_writep, as_u8_slice, emu_get_param, emu_set_param, emu_reads, as_u8_slice_mut}; 6 | 7 | const SYSCALL_BASE: u64 = 0x200000000u64; 8 | const SYSCALL_SIZE: u32 = 0x04; 9 | const HEAP_STACK_BASE: u64 = 0x300000000u64; 10 | const HEAP_STACK_SIZE: u32 = 0x30000; 11 | const SYSCALL_MAX: u32 = 48; 12 | const GLOBAL_EXIT_TAG:u64 = 0x1234123412341234u64; 13 | const DATA_BASE: u64 = HEAP_STACK_BASE + HEAP_STACK_SIZE as u64; 14 | const DATA_SIZE: u32 = 0x3000; 15 | const STACK_CHK_GUARD: u64 = 0x1234567812345678; 16 | const PARAM_BASE: u64 = DATA_BASE + DATA_SIZE as u64; 17 | const PARAM_SIZE: u32 = 0x3000; 18 | 19 | const MALLOC_BASE: u64 = PARAM_BASE + PARAM_SIZE as u64; 20 | const MALLOC_SIZE: u32 = 0x20000; 21 | 22 | // static SYSCALL_TAB: Vec = vec![ 23 | // emulator_exit as usize, 24 | 25 | // ]; 26 | 27 | static mut GLOBAL_M: u64 = 0; 28 | static mut GLOBAL_V: Vec<(u8, Vec)> = Vec::new(); 29 | static mut DEBUG: bool = false; 30 | 31 | pub const fn data_offset(offset: u32) -> u64 32 | { 33 | DATA_BASE + offset as u64 * 8 34 | } 35 | 36 | // ptr as str 37 | fn cf_to_str<'a>(uc: &mut Unicorn<'a, ()>, ptr: u64) -> String 38 | { 39 | let max = unsafe { GLOBAL_V.len() as u64 }; 40 | if ptr <= max { 41 | unsafe { 42 | if let Some((_t, v)) = GLOBAL_V.get(ptr as usize - 1) { 43 | // default t == 1 44 | String::from_utf8(v.to_vec()).unwrap() 45 | } else { 46 | todo!() 47 | } 48 | } 49 | } else { 50 | let ptr = emu_readp(uc, ptr + 0x10).unwrap(); 51 | let s = emu_reads(uc, ptr).unwrap(); 52 | s 53 | } 54 | } 55 | 56 | // str as ptr 57 | fn str_to_cf<'a>(uc: &mut Unicorn<'a, ()>, s: &str) -> u64 58 | { 59 | unsafe { 60 | GLOBAL_V.push((1, s.as_bytes().to_vec())); 61 | GLOBAL_V.len() as u64 62 | } 63 | } 64 | 65 | // 66 | fn cf_to_bytes<'a>(uc: &mut Unicorn<'a, ()>, ptr: u64) -> Vec 67 | { 68 | unsafe { 69 | if let Some((_t, v)) = GLOBAL_V.get(ptr as usize - 1) { 70 | // default t == 2 71 | v.to_vec() 72 | } else { 73 | todo!() 74 | } 75 | } 76 | } 77 | 78 | // data as ptr 79 | fn vec_to_cf<'a>(uc: &mut Unicorn<'a, ()>, v: Vec) -> u64 80 | { 81 | unsafe { 82 | GLOBAL_V.push((2, v)); 83 | GLOBAL_V.len() as u64 84 | } 85 | } 86 | 87 | // cf 88 | fn cf_str_id<'a>(uc: &mut Unicorn<'a, ()>, from: u64) { uc.reg_write(RegisterX86::RAX, 1).unwrap(); } 89 | fn cf_data_id<'a>(uc: &mut Unicorn<'a, ()>, from: u64) { uc.reg_write(RegisterX86::RAX, 2).unwrap(); } 90 | 91 | fn cf_id<'a>(uc: &mut Unicorn<'a, ()>, from: u64) 92 | { 93 | let cf = emu_get_param(uc, 0).unwrap(); 94 | let id = unsafe { 95 | GLOBAL_V.get(cf as usize - 1).unwrap().0 96 | }; 97 | uc.reg_write(RegisterX86::RAX, id as u64).unwrap(); 98 | } 99 | 100 | fn cf_len<'a>(uc: &mut Unicorn<'a, ()>, from: u64) 101 | { 102 | let cf = emu_get_param(uc, 0).unwrap(); 103 | let len = unsafe { 104 | GLOBAL_V.get(cf as usize - 1).unwrap().1.len() 105 | }; 106 | uc.reg_write(RegisterX86::RAX, len as u64).unwrap(); 107 | } 108 | 109 | fn cf_maxlen<'a>(uc: &mut Unicorn<'a, ()>, from: u64) 110 | { 111 | let len = emu_get_param(uc, 0).unwrap(); 112 | uc.reg_write(RegisterX86::RAX, len as u64).unwrap(); 113 | } 114 | 115 | fn cf_getcstr<'a>(uc: &mut Unicorn<'a, ()>, from: u64) 116 | { 117 | let ptr = emu_get_param(uc, 0).unwrap(); 118 | let s = cf_to_str(uc, ptr); 119 | log::info!("+ get cstr: {}", s); 120 | let ptr = emu_get_param(uc, 1).unwrap(); 121 | let cs = CString::new(s).unwrap(); 122 | uc.mem_write(ptr, cs.as_bytes_with_nul()).unwrap(); 123 | uc.reg_write(RegisterX86::RAX, 1).unwrap(); 124 | } 125 | 126 | fn cf_getbytes<'a>(uc: &mut Unicorn<'a, ()>, from: u64) 127 | { 128 | let ptr = emu_get_param(uc, 0).unwrap(); 129 | let bytes = cf_to_bytes(uc, ptr); 130 | log::info!("+ get bytes: {}", hex::encode(&bytes)); 131 | let start = emu_get_param(uc, 1).unwrap() as usize; 132 | let len = emu_get_param(uc, 2).unwrap() as usize; 133 | let ptr = emu_get_param(uc, 3).unwrap(); 134 | log::info!("+ write to {:x}", ptr); 135 | uc.mem_write(ptr, &bytes[start..start+len]).unwrap(); 136 | uc.reg_write(RegisterX86::RAX, 1).unwrap(); 137 | } 138 | 139 | static mut GLOBAL_ETH: bool = false; 140 | 141 | // io 142 | fn eth_reset<'a>(uc: &mut Unicorn<'a, ()>, from: u64) 143 | { 144 | unsafe { GLOBAL_ETH = false }; 145 | } 146 | 147 | fn eth_next<'a>(uc: &mut Unicorn<'a, ()>, from: u64) 148 | { 149 | if unsafe { GLOBAL_ETH } { 150 | uc.reg_write(RegisterX86::RAX, 0).unwrap(); 151 | } else { 152 | unsafe { GLOBAL_ETH = true } ; 153 | uc.reg_write(RegisterX86::RAX, 1).unwrap(); 154 | } 155 | } 156 | 157 | fn not_implement<'a>(uc: &mut Unicorn<'a, ()>, from: u64) 158 | { 159 | log::warn!("+ not implement. {:x}", from); 160 | uc.reg_write(RegisterX86::RAX, 0).unwrap(); 161 | } 162 | 163 | fn emulator_exit<'a>(uc: &mut Unicorn<'a, ()>, from: u64) 164 | { 165 | log::info!("+ token: {:x}", from); 166 | uc.emu_stop().unwrap(); 167 | } 168 | 169 | fn emulator_malloc<'a>(uc: &mut Unicorn<'a, ()>, from: u64) 170 | { 171 | let size: u64 = emu_get_param(uc, 0).unwrap(); 172 | log::info!("+ malloc: {} from {:x}", size, from); 173 | let offset = unsafe { 174 | let old = GLOBAL_M; 175 | let new = GLOBAL_M + size; 176 | GLOBAL_M = new; 177 | old 178 | }; 179 | log::info!("+ new: {:x}", MALLOC_BASE + offset); 180 | if (offset + size) > MALLOC_SIZE as u64 { 181 | log::error!("FIXME: Not enough malloc space {:x}. {:x}", offset, offset + size); 182 | } 183 | uc.reg_write(RegisterX86::RAX, MALLOC_BASE + offset).unwrap(); 184 | } 185 | 186 | fn emulator_free<'a>(uc: &mut Unicorn<'a, ()>, from: u64) 187 | { 188 | let ptr: u64 = emu_get_param(uc, 0).unwrap(); 189 | log::info!("+ free: {:x}", ptr); 190 | } 191 | 192 | fn emulator_memcpy<'a>(uc: &mut Unicorn<'a, ()>, from: u64) 193 | { 194 | let dst = emu_get_param(uc, 0).unwrap(); 195 | let src = emu_get_param(uc, 1).unwrap(); 196 | let len = emu_get_param(uc, 2).unwrap(); 197 | let v = uc.mem_read_as_vec(src, len as usize).unwrap(); 198 | uc.mem_write(dst, &v).unwrap(); 199 | uc.reg_write(RegisterX86::RAX, src).unwrap(); 200 | } 201 | 202 | fn emulator_memset<'a>(uc: &mut Unicorn<'a, ()>, from: u64) 203 | { 204 | let dst = emu_get_param(uc, 0).unwrap(); 205 | let val = emu_get_param(uc, 1).unwrap(); 206 | let len = emu_get_param(uc, 2).unwrap(); 207 | let v = vec![val as u8; len as usize]; 208 | uc.mem_write(dst, &v).unwrap(); 209 | uc.reg_write(RegisterX86::RAX, dst).unwrap(); 210 | } 211 | 212 | fn emulator_time<'a>(uc: &mut Unicorn<'a, ()>, from: u64) 213 | { 214 | let c = emu_get_param(uc, 0).unwrap(); 215 | if c != 0 { 216 | todo!() 217 | } 218 | let tm = unsafe { 219 | libc::time(0 as _) as u64 220 | }; 221 | uc.reg_write(RegisterX86::RAX, tm).unwrap(); 222 | } 223 | 224 | fn emulator_pthread_once<'a>(uc: &mut Unicorn<'a, ()>, from: u64) 225 | { 226 | // just call it 227 | let c = emu_get_param(uc, 1).unwrap(); 228 | let rip = uc.reg_read(RegisterX86::RIP).unwrap(); 229 | let rsp = uc.reg_read(RegisterX86::RSP).unwrap() - 8; 230 | uc.reg_write(RegisterX86::RSP, rsp).unwrap(); 231 | emu_writep(uc, rsp, rip).unwrap(); 232 | uc.set_pc(c).unwrap(); 233 | } 234 | 235 | fn emulator_arc4random<'a>(uc: &mut Unicorn<'a, ()>, from: u64) 236 | { 237 | let rax = unsafe { 238 | libc::rand() as u64 239 | }; 240 | uc.reg_write(RegisterX86::RAX, rax).unwrap(); 241 | } 242 | 243 | fn emulator_sysctlbyname<'a>(uc: &mut Unicorn<'a, ()>, from: u64) 244 | { 245 | let ptr = emu_get_param(uc, 0).unwrap(); 246 | let oldp = emu_get_param(uc, 1).unwrap(); 247 | let name = emu_reads(uc, ptr).unwrap(); 248 | 249 | match name.as_str() 250 | { 251 | "kern.osversion" => { 252 | let cs = CString::new("20G527").unwrap(); 253 | uc.mem_write(oldp, cs.as_bytes_with_nul()).unwrap(); 254 | } 255 | "kern.osrevision" => { 256 | uc.mem_write(oldp, as_u8_slice(&199506u32)).unwrap(); 257 | } 258 | _ => {} 259 | } 260 | uc.reg_write(RegisterX86::RAX, 0).unwrap(); 261 | } 262 | 263 | fn emulator_release<'a>(uc: &mut Unicorn<'a, ()>, from: u64) 264 | { 265 | log::info!("FIXME: release."); 266 | } 267 | 268 | fn emulator_skip_1<'a>(uc: &mut Unicorn<'a, ()>, from: u64) 269 | { 270 | uc.reg_write(RegisterX86::RAX, 1).unwrap(); 271 | } 272 | 273 | fn emulator_skip_0<'a>(uc: &mut Unicorn<'a, ()>, from: u64) 274 | { 275 | uc.reg_write(RegisterX86::RAX, 0).unwrap(); 276 | } 277 | 278 | fn emulator_create_with_cstr<'a>(uc: &mut Unicorn<'a, ()>, from: u64) 279 | { 280 | let ptr = emu_get_param(uc, 1).unwrap(); 281 | let s = emu_reads(uc, ptr).unwrap(); 282 | let ptr = str_to_cf(uc, &s); 283 | uc.reg_write(RegisterX86::RAX, ptr).unwrap(); 284 | } 285 | 286 | fn emulator_service_matching<'a>(uc: &mut Unicorn<'a, ()>, from: u64) 287 | { 288 | let ptr = emu_get_param(uc, 0).unwrap(); 289 | let s = emu_reads(uc, ptr).unwrap(); 290 | let ptr = str_to_cf(uc, &s); 291 | uc.reg_write(RegisterX86::RAX, ptr).unwrap(); 292 | } 293 | 294 | fn emulator_io_reg<'a>(uc: &mut Unicorn<'a, ()>, from: u64) 295 | { 296 | let ptr = emu_get_param(uc, 1).unwrap(); 297 | log::info!("+ io reg: {:?}", ptr); 298 | let s = cf_to_str(uc, ptr); 299 | 300 | let ret = match s.as_str() 301 | { 302 | "board-id" => vec_to_cf(uc, hex::decode("433234362d5755342d434600").unwrap()), 303 | "product-name" => vec_to_cf(uc, hex::decode("564d77617265372c3100").unwrap()), 304 | "boot-uuid" => vec_to_cf(uc, hex::decode("32453143463230452d414631332d344634432d414446312d34443431464142423836423500").unwrap()), 305 | "IOPlatformSerialNumber" => str_to_cf(uc, "VMxd6muhRqce"), 306 | "IOPlatformUUID" => str_to_cf(uc, "564D125C-23F9-7095-9EC9-983BCB8F2FD6"), 307 | "Gq3489ugfi" => vec_to_cf(uc, hex::decode("1548b8e035649e797e918931cab812aec7").unwrap()), 308 | "Fyp98tpgj" => vec_to_cf(uc, hex::decode("17bc9f170d6a2ae075299ae220ea43e2a7").unwrap()), 309 | "kbjfrfpoJU" => vec_to_cf(uc, hex::decode("18d9b7a86702cc6a8fab8f73c0ba2c2aed").unwrap()), 310 | "IOMACAddress" => vec_to_cf(uc, hex::decode("000c298f2fd6").unwrap()), 311 | "4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:ROM" => vec_to_cf(uc, hex::decode("564d125c23f9").unwrap()), 312 | "4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:MLB" => vec_to_cf(uc, hex::decode("634a5765795a67377934387631672e2e2e").unwrap()), 313 | "oycqAZloTNDm" => vec_to_cf(uc, hex::decode("55d0143a2eab41e70afa29de95b04cdffb").unwrap()), 314 | "abKPld1EcMni" => vec_to_cf(uc, hex::decode("e83ddc6931b80d867d0432225d8dc1a347").unwrap()), 315 | _ => 0 as _ 316 | }; 317 | uc.reg_write(RegisterX86::RAX, ret).unwrap(); 318 | } 319 | 320 | fn emulator_cf_<'a>(uc: &mut Unicorn<'a, ()>, from: u64) 321 | { 322 | log::warn!("+ cf not implement. {:x}", from); 323 | uc.emu_stop().unwrap(); 324 | } 325 | 326 | fn emulator_syscall<'a>(uc: &mut Unicorn<'a, ()>) 327 | { 328 | let rip = uc.reg_read(RegisterX86::RIP).unwrap(); 329 | let rsp = uc.reg_read(RegisterX86::RSP).unwrap(); 330 | let _return_address = emu_readp(uc, rsp).unwrap(); 331 | let col = ((rip - SYSCALL_BASE - 1) / 4) as u32; 332 | let func = match col 333 | { 334 | 0 => { emulator_exit } 335 | 1 => { emulator_malloc } 336 | 2 => { emulator_free } 337 | 3 => { emulator_memcpy } 338 | 4 => { emulator_memset } 339 | 5 => { emulator_time } 340 | 6 => { emulator_pthread_once } 341 | 7 => { emulator_arc4random } 342 | 8 => { emulator_sysctlbyname } 343 | 9 | 21 => { emulator_release } 344 | 10 | 23 | 29 => { emulator_skip_1 } 345 | 11 => { emulator_create_with_cstr } 346 | 22 => { emulator_service_matching } 347 | 12 => { emulator_io_reg } 348 | 13 => { cf_id } 349 | 14 => { cf_str_id } 350 | 15 | 19 => { cf_len } 351 | 16 => { cf_maxlen } 352 | 17 => { cf_getcstr } 353 | 18 => { cf_data_id } 354 | 20 => { cf_getbytes } 355 | 24 | 28 => { emulator_skip_0 } 356 | 25 => { emulator_skip_0 } // TODO: _IOServiceGetMatchingServices 357 | 26 => { eth_reset } 358 | 27 => { eth_next } 359 | _ => { not_implement } 360 | }; 361 | 362 | func(uc, _return_address); 363 | } 364 | 365 | fn heap_init<'a>(uc: &mut Unicorn<'a, ()>) 366 | { 367 | let mut stack_top = HEAP_STACK_BASE + HEAP_STACK_SIZE as u64; 368 | stack_top -= 8; 369 | emu_writep(uc, stack_top, GLOBAL_EXIT_TAG).unwrap(); 370 | stack_top -= 8; 371 | emu_writep(uc, stack_top, SYSCALL_BASE).unwrap(); 372 | uc.reg_write(RegisterX86::RSP, stack_top).unwrap(); 373 | } 374 | 375 | pub fn call_0<'a>(uc: &mut Unicorn<'a, ()>, cert: &[u8]) -> Result<(u64, Vec)> 376 | { 377 | heap_init(uc); 378 | // param 379 | if let Err(e) = emu_map(uc, PARAM_BASE, PARAM_SIZE as usize, Permission::READ | Permission::WRITE) { 380 | log::error!("+ failed: {:x} {:?}", PARAM_BASE, e); 381 | } 382 | // pass 383 | uc.mem_write(PARAM_BASE, &vec![0u8; 32]).unwrap(); 384 | uc.mem_write(PARAM_BASE + 32, cert).unwrap(); 385 | emu_set_param(uc, 0, PARAM_BASE + 32).unwrap(); 386 | emu_set_param(uc, 1, cert.len() as u64).unwrap(); 387 | emu_set_param(uc, 2, PARAM_BASE).unwrap(); 388 | emu_set_param(uc, 3, PARAM_BASE + 8).unwrap(); 389 | emu_set_param(uc, 4, PARAM_BASE + 16).unwrap(); 390 | 391 | uc.emu_start(0x1000d2f30, 0, 0, 0).unwrap(); 392 | let result = uc.reg_read(RegisterX86::RAX).unwrap(); 393 | log::info!("+ result: {:x}", result); 394 | 395 | let params = uc.mem_read_as_vec(PARAM_BASE, 24).unwrap(); 396 | let ctx = u64::from_le_bytes(params[..8].try_into().unwrap()); 397 | let ptr = u64::from_le_bytes(params[8..16].try_into().unwrap()); 398 | let len = u64::from_le_bytes(params[16..24].try_into().unwrap()); 399 | log::info!("+ return {:x}, {:x}, {:x}", ctx, ptr, len); 400 | 401 | Ok((ctx, uc.mem_read_as_vec(ptr, len as usize).unwrap())) 402 | } 403 | 404 | pub fn call_1<'a>(uc: &mut Unicorn<'a, ()>, ctx: u64, session: &[u8]) -> Result<()> 405 | { 406 | heap_init(uc); 407 | // pass 408 | uc.mem_write(PARAM_BASE, &vec![0u8; 32]).unwrap(); 409 | uc.mem_write(PARAM_BASE + 32, session).unwrap(); 410 | emu_set_param(uc, 0, ctx).unwrap(); 411 | emu_set_param(uc, 1, PARAM_BASE + 32).unwrap(); 412 | emu_set_param(uc, 2, session.len() as _).unwrap(); 413 | 414 | uc.emu_start(0x100125a50, 0, 0, 0).unwrap(); 415 | let result = uc.reg_read(RegisterX86::RAX).unwrap(); 416 | log::info!("+ result: {:x}", result); 417 | 418 | Ok(()) 419 | } 420 | 421 | pub fn call_2<'a>(uc: &mut Unicorn<'a, ()>, ctx: u64, data: &[u8]) -> Result> 422 | { 423 | heap_init(uc); 424 | // pass 425 | uc.mem_write(PARAM_BASE, &vec![0u8; 32]).unwrap(); 426 | uc.mem_write(PARAM_BASE + 32, data).unwrap(); 427 | emu_set_param(uc, 0, ctx).unwrap(); 428 | emu_set_param(uc, 1, PARAM_BASE + 32).unwrap(); 429 | emu_set_param(uc, 2, data.len() as _).unwrap(); 430 | emu_set_param(uc, 3, PARAM_BASE).unwrap(); 431 | emu_set_param(uc, 4, PARAM_BASE + 8).unwrap(); 432 | uc.emu_start(0x1000c5860, 0, 0, 0).unwrap(); 433 | let result = uc.reg_read(RegisterX86::RAX).unwrap(); 434 | log::info!("+ result: {:x}", result); 435 | let params = uc.mem_read_as_vec(PARAM_BASE, 16).unwrap(); 436 | let ptr = u64::from_le_bytes(params[..8].try_into().unwrap()); 437 | let len = u64::from_le_bytes(params[8..16].try_into().unwrap()); 438 | 439 | Ok(uc.mem_read_as_vec(ptr, len as usize).unwrap()) 440 | } 441 | 442 | fn debug_code<'a>(uc: &mut Unicorn<'a, ()>, address: u64, size: u32) 443 | { 444 | if unsafe { DEBUG } { 445 | log::info!("+ code: {:x} RDX:{:x}", address, uc.reg_read(RegisterX86::RDX).unwrap()); 446 | } 447 | } 448 | 449 | fn mem_invalid<'a>(uc: &mut Unicorn<'a, ()>, mem_type: MemType, addr: u64, size: usize, value: i64) -> bool 450 | { 451 | let rip = uc.reg_read(RegisterX86::RIP).unwrap(); 452 | log::error!("+ mem invalid: {:x} - {:?}. {:x}", addr, mem_type, rip); 453 | false 454 | } 455 | 456 | pub fn regiser_init<'a>(uc: &mut Unicorn<'a, ()>) 457 | { 458 | log::info!("+ start register init."); 459 | let size = (SYSCALL_SIZE * SYSCALL_MAX) as usize; 460 | if let Err(e) = emu_map(uc, SYSCALL_BASE, size, Permission::ALL) { 461 | log::error!("+ failed: {:x} {:?}", SYSCALL_BASE, e); 462 | } 463 | 464 | // register heap 465 | if let Err(e) = emu_map(uc, HEAP_STACK_BASE, HEAP_STACK_SIZE as usize, Permission::READ | Permission::WRITE) { 466 | log::error!("+ failed: {:x} {:?}", HEAP_STACK_BASE, e); 467 | } 468 | 469 | let code:Vec = vec![0x90, 0x0f, 0x05, 0xc3]; 470 | let mut codes: Vec = Vec::new(); 471 | for _ in 0 .. SYSCALL_MAX { 472 | codes.extend(code.iter()); 473 | } 474 | if let Err(e) = uc.mem_write(SYSCALL_BASE, &codes) { 475 | log::error!("+ failed: {:?}", e); 476 | } 477 | 478 | // register callback 479 | if let Err(e) = uc.add_insn_sys_hook(unicorn_engine::InsnSysX86::SYSCALL, SYSCALL_BASE, SYSCALL_BASE + size as u64, emulator_syscall) { 480 | log::error!("+ failed: {:?}", e); 481 | } 482 | 483 | // init .data 484 | if let Err(e) = emu_map(uc, DATA_BASE, DATA_SIZE as usize, Permission::READ | Permission::WRITE) { 485 | log::error!("+ failed: {:x} {:?}", DATA_BASE, e); 486 | } 487 | 488 | // 固定数据写入 489 | let mut data: Vec = Vec::new(); 490 | data.push(STACK_CHK_GUARD.to_le()); 491 | data.push(data_offset(0).to_le()); 492 | for i in 0 .. 10 { 493 | data.push(data_offset(i + 2).to_le()); 494 | } 495 | if let Err(e) = uc.mem_write(DATA_BASE, as_u8_slice(&data)) { 496 | log::error!("+ failed: {:?}", e); 497 | } 498 | 499 | // if let Err(e) = uc.add_code_hook(1, 0, debug_code) { 500 | // println!("+ failed: {:?}", e); 501 | // } 502 | 503 | if let Err(e) = uc.add_mem_hook(HookType::MEM_UNMAPPED, 1, 0, mem_invalid) { 504 | log::error!("+ failed: {:?}", e); 505 | } 506 | 507 | // TODO: malloc 508 | if let Err(e) = emu_map(uc, MALLOC_BASE, MALLOC_SIZE as usize, Permission::READ | Permission::WRITE) { 509 | log::error!("+ failed: {:x} {:?}", MALLOC_BASE, e); 510 | } 511 | 512 | log::info!("+ register init done."); 513 | } 514 | 515 | pub fn register_fn(_dylib: &str, name: &str) -> u64 516 | { 517 | // data 518 | let data = match name { 519 | "____chkstk_darwin" => Some(0), 520 | "___CFConstantStringClassReference" => Some(data_offset(0)), 521 | "___stack_chk_guard" => Some(data_offset(1)), 522 | "_kIOMasterPortDefault" => Some(data_offset(2)), 523 | "_kCFAllocatorDefault" => Some(data_offset(3)), 524 | "_kCFAllocatorNull" => Some(data_offset(4)), 525 | "_kCFTypeDictionaryKeyCallBacks" => Some(data_offset(5)), 526 | "_kCFTypeDictionaryValueCallBacks" => Some(data_offset(6)), 527 | "_kCFBooleanTrue" => Some(data_offset(7)), 528 | "_kCFBooleanFalse" => Some(data_offset(8)), 529 | "___kCFBooleanFalse" => Some(data_offset(9)), 530 | "___kCFBooleanTrue" => Some(data_offset(10)), 531 | _ => None, 532 | }; 533 | if let Some(data) = data { 534 | return data; 535 | } 536 | let col = match name 537 | { 538 | "_malloc" => 1, 539 | "_free" => 2, 540 | // "_stack_chk_fail" => 5, 541 | "___memcpy_chk" => 3, 542 | "___memset_chk" => 4, 543 | "_time" => 5, 544 | "_pthread_once" => 6, 545 | "_arc4random" => 7, 546 | // start to patch 547 | "_sysctlbyname" => 8, 548 | "_IOObjectRelease" => 9, 549 | "_IORegistryEntryFromPath" => 10, 550 | "_CFStringCreateWithCStringNoCopy" => 11, 551 | "_IORegistryEntryCreateCFProperty" => 12, 552 | "_CFGetTypeID" => 13, 553 | "_CFStringGetTypeID" => 14, 554 | "_CFStringGetLength" => 15, 555 | "_CFStringGetMaximumSizeForEncoding" => 16, 556 | "_CFStringGetCString" => 17, 557 | "_CFDataGetTypeID" => 18, 558 | "_CFDataGetLength" => 19, 559 | "_CFDataGetBytes" => 20, 560 | "_CFRelease" => 21, 561 | "_IOServiceMatching" => 22, 562 | // 网卡 563 | "_CFDictionaryCreateMutable" => 23, 564 | "_CFDictionarySetValue" => 24, 565 | "_IOServiceGetMatchingServices" => 25, 566 | "_IOIteratorReset" => 26, 567 | "_IOIteratorNext" => 27, 568 | "_IORegistryEntryGetParentEntry" => 28, 569 | "_CFStringGetSystemEncoding" => 29, 570 | _ => SYSCALL_MAX - 1, 571 | } as u32; 572 | 573 | SYSCALL_BASE + (SYSCALL_SIZE * col) as u64 574 | } -------------------------------------------------------------------------------- /api/src/patch/mod.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "emu")] 2 | mod emulator; 3 | #[cfg(feature = "emu")] 4 | pub use self::emulator::*; 5 | 6 | #[cfg(not(feature = "emu"))] 7 | mod patch; 8 | #[cfg(not(feature = "emu"))] 9 | pub use self::patch::*; 10 | 11 | // TODO: use osx -------------------------------------------------------------------------------- /api/src/patch/osx.rs: -------------------------------------------------------------------------------- 1 | use std::ffi::{c_void, c_int, c_char, CStr, c_uint, CString}; 2 | 3 | use libc::size_t; 4 | 5 | unsafe extern "sysv64" 6 | fn malloc(size: libc::size_t) -> *mut c_void 7 | { 8 | let ptr = libc::malloc(size); 9 | println!("+ malloc: {:x}|{:x}", ptr as usize, size); 10 | ptr 11 | } 12 | 13 | unsafe extern "sysv64" 14 | fn time(tm: *mut i64) -> i64 15 | { 16 | libc::time(tm) 17 | } 18 | 19 | unsafe extern "sysv64" 20 | fn free(ptr: *mut c_void) 21 | { 22 | println!("+ free: {:x}", ptr as usize); 23 | libc::free(ptr) 24 | } 25 | 26 | unsafe extern "sysv64" 27 | fn memcpy( 28 | dest: *mut c_void, 29 | src: *const c_void, 30 | len: libc::size_t, 31 | _destlen: libc::size_t, 32 | ) -> *mut c_void 33 | { 34 | libc::memcpy(dest, src, len) 35 | } 36 | 37 | unsafe extern "sysv64" 38 | fn memset(dest: *mut c_void, val: c_int, len: libc::size_t) -> *mut c_void 39 | { 40 | libc::memset(dest, val, len) 41 | } 42 | 43 | unsafe extern "sysv64" 44 | fn _stack_chk_fail() 45 | { 46 | println!("+ stack chk fail."); 47 | } 48 | 49 | static STACK_CHK_GUARD: u64 = 0x1234567812345678; 50 | 51 | unsafe extern "sysv64" 52 | fn not_implement() 53 | { 54 | println!("+ not implement."); 55 | } 56 | 57 | // dynamic load function 58 | fn get_dynamic(dylib: &str, name: &str) -> usize 59 | { 60 | let dylib = CString::new(dylib).unwrap(); 61 | let name = CString::new(name).unwrap(); 62 | let func = unsafe { 63 | let handle = libc::dlopen(dylib.as_ptr(), libc::RTLD_NOW); 64 | libc::dlsym(handle, name.as_ptr()) as usize 65 | }; 66 | if func == 0 { 67 | println!("+ not found func: {:?}, {:?}", dylib, name); 68 | not_implement as usize 69 | } else { 70 | func 71 | } 72 | } 73 | 74 | pub fn register_fn(dylib: &str, name: &str) -> usize 75 | { 76 | match name 77 | { 78 | "_malloc" => malloc as usize, 79 | "_free" => free as usize, 80 | "____chkstk_darwin" => 0usize, 81 | "___stack_chk_guard" => &STACK_CHK_GUARD as *const u64 as usize, 82 | "_stack_chk_fail" => _stack_chk_fail as usize, 83 | "___memcpy_chk" => memcpy as usize, 84 | "___memset_chk" => memset as usize, 85 | "_time" => time as usize, 86 | "_pthread_once" => get_dynamic(dylib, "pthread_once"), 87 | "_arc4random" => libc::arc4random as usize, 88 | // forward 89 | "_sysctlbyname" | "_IOObjectRelease" | "_IORegistryEntryFromPath" | 90 | "_kIOMasterPortDefault" | "_kCFAllocatorDefault" | "_kCFAllocatorNull" | 91 | "_CFStringCreateWithCStringNoCopy" | "_IORegistryEntryCreateCFProperty" | 92 | "_CFGetTypeID" | "_CFStringGetTypeID" | "_CFStringGetLength" | 93 | "_CFStringGetMaximumSizeForEncoding" | "_CFStringGetCString" | 94 | "_CFDataGetTypeID" | "_CFDataGetLength" | "_CFDataGetBytes" | 95 | "_CFRelease" | "_IOServiceMatching" | "_CFDictionaryCreateMutable" | 96 | "_CFDictionarySetValue" | "_IOServiceGetMatchingServices" | 97 | "_IOIteratorReset" | "_IOIteratorNext" | "_IORegistryEntryGetParentEntry" | 98 | "_CFStringGetSystemEncoding" | "_kCFTypeDictionaryKeyCallBacks" | "_kCFTypeDictionaryValueCallBacks" | 99 | "_kCFBooleanTrue" | "_kCFBooleanFalse" | 100 | "___kCFBooleanFalse" | "___kCFBooleanTrue" | 101 | "___CFConstantStringClassReference" => { 102 | get_dynamic(dylib, &name[1..]) 103 | } 104 | // last 105 | _ => not_implement as usize, 106 | } 107 | } -------------------------------------------------------------------------------- /api/src/patch/patch.rs: -------------------------------------------------------------------------------- 1 | use std::ffi::{c_void, c_int, c_char, CStr, c_uint}; 2 | use crate::mac_serial::MacSerial; 3 | use libc::size_t; 4 | 5 | unsafe extern "sysv64" 6 | fn malloc(size: libc::size_t) -> *mut c_void 7 | { 8 | let ptr = libc::malloc(size); 9 | log::info!("+ malloc: {:x}|{:x}", ptr as usize, size); 10 | ptr 11 | } 12 | 13 | unsafe extern "sysv64" 14 | fn time(tm: *mut i64) -> i64 15 | { 16 | libc::time(tm) 17 | } 18 | 19 | unsafe extern "sysv64" 20 | fn free(ptr: *mut c_void) 21 | { 22 | log::info!("+ free: {:x}", ptr as usize); 23 | libc::free(ptr) 24 | } 25 | 26 | unsafe extern "sysv64" 27 | fn memcpy( 28 | dest: *mut c_void, 29 | src: *const c_void, 30 | len: libc::size_t, 31 | _destlen: libc::size_t, 32 | ) -> *mut c_void 33 | { 34 | libc::memcpy(dest, src, len) 35 | } 36 | 37 | unsafe extern "sysv64" 38 | fn memset(dest: *mut c_void, val: c_int, len: libc::size_t) -> *mut c_void 39 | { 40 | libc::memset(dest, val, len) 41 | } 42 | 43 | unsafe extern "sysv64" 44 | fn _stack_chk_fail() 45 | { 46 | log::error!("+ stack check fail."); 47 | } 48 | 49 | #[repr(C)] 50 | pub struct pthread_once_t { 51 | pub state: c_int, 52 | pub mutex: *mut c_void, 53 | } 54 | 55 | unsafe extern "sysv64" 56 | fn pthread_once( 57 | _once_control: *mut pthread_once_t, 58 | init_routine: extern "sysv64" fn() 59 | ) -> c_int 60 | { 61 | init_routine(); 62 | 0 63 | } 64 | 65 | unsafe extern "sysv64" 66 | fn not_implement() 67 | { 68 | log::error!("+ not implement."); 69 | } 70 | 71 | // for windows/linux 72 | unsafe extern "sysv64" 73 | fn arc4random() -> u32 74 | { 75 | libc::rand() as u32 76 | } 77 | 78 | static STACK_CHK_GUARD: u64 = 0x1234567812345678; 79 | static CFSTR_TAG: u64 = 0xabababababababab; 80 | static PATCH_TAG: u64 = 0x2cacacac; 81 | static PATCH_TAG2: u64 = 0xacacacac; 82 | static KNULL: usize = 0x11111111; 83 | static KTRUE: usize = 0x22222222; 84 | static KFALSE:usize = 0x33333333; 85 | static KALLOC:usize = 0x44444444; 86 | static CF_TYPE_STRING:u32 = 1; 87 | static CF_TYPE_DATA:u32 = 2; 88 | 89 | #[repr(C)] 90 | struct patch_data 91 | { 92 | tag: *const u64, 93 | data: *const c_char, 94 | } 95 | 96 | impl patch_data 97 | { 98 | pub extern "sysv64" fn new_str(s: *const c_char) -> *const patch_data 99 | { 100 | let ptr = patch_data { 101 | tag: &PATCH_TAG, 102 | data: s, 103 | }; 104 | Box::leak(Box::new(ptr)) as *const patch_data 105 | } 106 | 107 | pub extern "sysv64" fn new_data(s: *const c_char) -> *const patch_data 108 | { 109 | let ptr = patch_data { 110 | tag: &PATCH_TAG2, 111 | data: s, 112 | }; 113 | Box::leak(Box::new(ptr)) as *const patch_data 114 | } 115 | 116 | pub unsafe extern "sysv64" fn is_patch(d: *const patch_data) -> bool 117 | { 118 | *(*d).tag & 0x7fffffff == PATCH_TAG 119 | } 120 | 121 | pub unsafe extern "sysv64" fn get_from_cf(d: *const patch_data) -> *const c_char 122 | { 123 | // tag 为地址 124 | if *(*d).tag != CFSTR_TAG { 125 | log::error!("+ Got failed cf. {:x} | {:x}\n", *(*d).tag, d as usize); 126 | 0 as _ 127 | } else { 128 | *((d as *const u8).offset(16) as *const *const c_char) 129 | } 130 | } 131 | 132 | pub unsafe extern "sysv64" fn is_str(d: *const patch_data) -> bool 133 | { 134 | *(*d).tag != PATCH_TAG2 135 | } 136 | 137 | pub unsafe extern "sysv64" fn get_len(d: *const patch_data) -> usize 138 | { 139 | if Self::is_patch(d) { 140 | let len = libc::strlen((*d).data); 141 | if Self::is_str(d) { 142 | len 143 | } else { 144 | len / 2 145 | } 146 | } 147 | else { 148 | libc::strlen(Self::get_from_cf(d)) 149 | } 150 | } 151 | 152 | pub unsafe extern "sysv64" fn get_ptr(d: *const patch_data) -> *const i8 153 | { 154 | if Self::is_patch(d) { 155 | unsafe { (*d).data as _ } 156 | } 157 | else { 158 | Self::get_from_cf(d) as _ 159 | } 160 | } 161 | } 162 | 163 | // 字符串转换 164 | #[repr(C)] 165 | pub struct CFRange { 166 | pub location: isize, 167 | pub length: isize, 168 | } 169 | unsafe extern "sysv64" fn CFStringGetTypeID() -> u32 { CF_TYPE_STRING } 170 | unsafe extern "sysv64" fn CFDataGetTypeID() -> u32 { CF_TYPE_DATA } 171 | unsafe extern "sysv64" 172 | fn CFGetTypeID(cf: *const patch_data) -> u32 173 | { 174 | let ret = 175 | if patch_data::is_str(cf) { 176 | CF_TYPE_STRING 177 | } else { 178 | CF_TYPE_DATA 179 | }; 180 | ret 181 | } 182 | unsafe extern "sysv64" 183 | fn CFGetLength(cf: *const patch_data) -> u32 184 | { 185 | let ret = patch_data::get_len(cf) as u32; 186 | ret 187 | } 188 | unsafe extern "sysv64" 189 | fn CFStringGetMaximumSizeForEncoding(length: u32, _encoding: u32) -> u32 190 | { 191 | length 192 | } 193 | unsafe extern "sysv64" 194 | fn CFStringGetCString( 195 | cf: *const patch_data, 196 | buffer: *mut c_char, 197 | _buffer_size: i32, 198 | _encoding: u32 199 | ) -> bool 200 | { 201 | // fixup zero. 202 | let len = patch_data::get_len(cf); 203 | libc::memcpy(buffer as _, patch_data::get_ptr(cf) as _, len); 204 | *buffer.offset(len as isize) = 0; 205 | true 206 | } 207 | unsafe extern "sysv64" 208 | fn CFDataGetBytes( 209 | cf: *const patch_data, 210 | range: CFRange, 211 | buffer: *mut u8 212 | ) 213 | { 214 | let s = CStr::from_ptr(patch_data::get_ptr(cf) as _).to_str().unwrap_unchecked(); 215 | let d = hex::decode(s).unwrap_unchecked(); 216 | libc::memcpy(buffer as _, (&d).as_ptr().offset(range.location) as _, range.length as usize); 217 | } 218 | 219 | // 特殊补丁 220 | unsafe extern "sysv64" 221 | fn sysctlbyname(name: *const c_char, oldp: *mut c_void, _oldlenp: *mut size_t, _newp: *mut c_void, _newlen: size_t) -> c_int 222 | { 223 | let s = CStr::from_ptr(name).to_str().unwrap_unchecked(); 224 | log::info!("sysctl: {}", s); 225 | 226 | match s 227 | { 228 | "kern.osversion" => { 229 | libc::strcpy(oldp as *mut i8, MacSerial::instance().osversion.as_ptr() as _); 230 | } 231 | "kern.osrevision" => { 232 | *(oldp as *mut u32) = MacSerial::instance().osrevision; 233 | } 234 | _ => {} 235 | } 236 | 0 237 | } 238 | 239 | unsafe extern "sysv64" fn 240 | IOServiceMatching(name: *const c_char) -> *const patch_data 241 | { 242 | patch_data::new_str(name) 243 | } 244 | 245 | // 网卡补丁 246 | unsafe extern "sysv64" fn 247 | IOServiceGetMatchingServices( 248 | _masterPort: c_uint, 249 | _matching: *const patch_data, 250 | existing: *mut usize 251 | ) -> c_int 252 | { 253 | // IOEthernetInterface 254 | let ptr = libc::malloc(8) as usize; 255 | *(ptr as *mut usize) = 1; 256 | *existing = ptr; 257 | 0 258 | } 259 | 260 | static mut GG: u32 = 0; 261 | unsafe extern "sysv64" fn 262 | IOIteratorReset(_ptr: *mut usize) 263 | { 264 | GG = 0; 265 | } 266 | 267 | unsafe extern "sysv64" fn 268 | IOIteratorNext(_ptr: *mut usize) -> usize 269 | { 270 | if GG == 0 { 271 | GG = GG + 1; 272 | 1 273 | } 274 | else { 275 | 0 276 | } 277 | } 278 | 279 | unsafe extern "sysv64" fn skip_0() -> usize { 0 } 280 | unsafe extern "sysv64" fn skip_1() -> usize { 1 } 281 | 282 | unsafe extern "sysv64" fn release(obj: *const c_void) 283 | { 284 | log::warn!("+ TODO: release {:x}", obj as usize); 285 | } 286 | 287 | unsafe extern "sysv64" fn CFStringCreateWithCStringNoCopy( 288 | _alloc: *const c_void, 289 | cStr: *const i8, 290 | _encoding: u32 291 | ) -> *const patch_data 292 | { 293 | patch_data::new_str(cStr) 294 | } 295 | 296 | unsafe extern "sysv64" 297 | fn io_reg(name: *const c_char) -> *const patch_data 298 | { 299 | let name = CStr::from_ptr(name).to_str().unwrap_unchecked(); 300 | log::info!("+ io reg, {}", name); 301 | let ret = match name 302 | { 303 | "board-id" => patch_data::new_data(MacSerial::instance().board_id.as_ptr() as _), 304 | "product-name" => patch_data::new_data(MacSerial::instance().product_name.as_ptr() as _), 305 | "boot-uuid" => patch_data::new_data(MacSerial::instance().boot_uuid.as_ptr() as _), 306 | "IOPlatformSerialNumber" => patch_data::new_str(MacSerial::instance().serial_number.as_ptr() as _), 307 | "IOPlatformUUID" => patch_data::new_str(MacSerial::instance().uuid.as_ptr() as _), 308 | "Gq3489ugfi" => patch_data::new_data(MacSerial::instance().gq_serial.as_ptr() as _), 309 | "Fyp98tpgj" => patch_data::new_data(MacSerial::instance().fy_serial.as_ptr() as _), 310 | "kbjfrfpoJU" => patch_data::new_data(MacSerial::instance().kb_serial.as_ptr() as _), 311 | "IOMACAddress" => patch_data::new_data(MacSerial::instance().mac_address.as_ptr() as _), 312 | "4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:ROM" => patch_data::new_data(MacSerial::instance().rom.as_ptr() as _), 313 | "4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:MLB" => patch_data::new_data(MacSerial::instance().mlb.as_ptr() as _), 314 | "oycqAZloTNDm" => patch_data::new_data(MacSerial::instance().oy_serial.as_ptr() as _), 315 | "abKPld1EcMni" => patch_data::new_data(MacSerial::instance().ab_serial.as_ptr() as _), 316 | _ => 0 as _ 317 | }; 318 | ret 319 | } 320 | 321 | unsafe extern "sysv64" 322 | fn IORegistryEntryCreateCFProperty( 323 | _entry: c_uint, 324 | name: *const patch_data, 325 | _property: *const c_void 326 | ) -> *const patch_data 327 | { 328 | let s = patch_data::get_ptr(name); 329 | io_reg(s) 330 | } 331 | 332 | pub fn register_fn(_dylib: &str, name: &str) -> usize 333 | { 334 | match name 335 | { 336 | "_malloc" => malloc as usize, 337 | "_free" => free as usize, 338 | "____chkstk_darwin" => 0usize, 339 | "___stack_chk_guard" => &STACK_CHK_GUARD as *const u64 as usize, 340 | "_stack_chk_fail" => _stack_chk_fail as usize, 341 | "___memcpy_chk" => memcpy as usize, 342 | "___memset_chk" => memset as usize, 343 | "_time" => time as usize, 344 | // TODO: use other random 345 | // "_arc4random" => libc::rand as usize, 346 | "_pthread_once" => pthread_once as usize, 347 | "_arc4random" => arc4random as usize, 348 | // start to patch 349 | "_sysctlbyname" => sysctlbyname as usize, 350 | "_IOObjectRelease" => release as usize, 351 | "_IORegistryEntryFromPath" => skip_1 as usize, 352 | "_kIOMasterPortDefault" => &KNULL as *const usize as usize, 353 | "_kCFAllocatorDefault" => &KALLOC as *const usize as usize, 354 | "_kCFAllocatorNull" => &KNULL as *const usize as usize, 355 | "_CFStringCreateWithCStringNoCopy" => CFStringCreateWithCStringNoCopy as usize, 356 | "_IORegistryEntryCreateCFProperty" => IORegistryEntryCreateCFProperty as usize, 357 | "_CFGetTypeID" => CFGetTypeID as usize, 358 | "_CFStringGetTypeID" => CFStringGetTypeID as usize, 359 | "_CFStringGetLength" => CFGetLength as usize, 360 | "_CFStringGetMaximumSizeForEncoding" => CFStringGetMaximumSizeForEncoding as usize, 361 | "_CFStringGetCString" => CFStringGetCString as usize, 362 | "_CFDataGetTypeID" => CFDataGetTypeID as usize, 363 | "_CFDataGetLength" => CFGetLength as usize, 364 | "_CFDataGetBytes" => CFDataGetBytes as usize, 365 | "_CFRelease" => release as usize, 366 | "_IOServiceMatching" => IOServiceMatching as usize, 367 | // 网卡 368 | "_CFDictionaryCreateMutable" => skip_1 as usize, 369 | "_CFDictionarySetValue" => skip_0 as usize, 370 | "_IOServiceGetMatchingServices" => IOServiceGetMatchingServices as usize, 371 | "_IOIteratorReset" => IOIteratorReset as usize, 372 | "_IOIteratorNext" => IOIteratorNext as usize, 373 | "_IORegistryEntryGetParentEntry" => skip_0 as usize, 374 | "_CFStringGetSystemEncoding" => skip_1 as usize, 375 | "_kCFTypeDictionaryKeyCallBacks" => &KNULL as *const usize as usize, 376 | "_kCFTypeDictionaryValueCallBacks" => &KNULL as *const usize as usize, 377 | "_kCFBooleanTrue" => &KTRUE as *const usize as usize, 378 | "_kCFBooleanFalse" => &KFALSE as *const usize as usize, 379 | "___kCFBooleanFalse" => &KFALSE as *const usize as usize, 380 | "___kCFBooleanTrue" => &KTRUE as *const usize as usize, 381 | "___CFConstantStringClassReference" => &CFSTR_TAG as *const u64 as usize, 382 | // last 383 | _ => not_implement as usize, 384 | } 385 | } -------------------------------------------------------------------------------- /api/src/service.rs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deadash/apple_cache/93274486161e0fc9e5cecb23ebf4f64bb0404e72/api/src/service.rs -------------------------------------------------------------------------------- /api/src/uniffi-bindgen.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | uniffi::uniffi_bindgen_main() 3 | } -------------------------------------------------------------------------------- /api/uniffi.toml: -------------------------------------------------------------------------------- 1 | [bindings.python] 2 | cdylib_name = "apple_cache" 3 | 4 | [bindings.ruby] 5 | cdylib_name = "apple_cache" 6 | 7 | [bindings.swift] 8 | cdylib_name = "apple_cache" 9 | 10 | [bindings.kotlin] 11 | package_name = "org.apple.cache" 12 | cdylib_name = "apple_cache" -------------------------------------------------------------------------------- /bindings/generate.txt: -------------------------------------------------------------------------------- 1 | cargo run --features=uniffi/cli --package api --bin uniffi-bindgen generate .\api\src\lib.udl --language python -------------------------------------------------------------------------------- /bindings/python/apple_cache.py: -------------------------------------------------------------------------------- 1 | # This file was autogenerated by some hot garbage in the `uniffi` crate. 2 | # Trust me, you don't want to mess with it! 3 | 4 | # Common helper code. 5 | # 6 | # Ideally this would live in a separate .py file where it can be unittested etc 7 | # in isolation, and perhaps even published as a re-useable package. 8 | # 9 | # However, it's important that the details of how this helper code works (e.g. the 10 | # way that different builtin types are passed across the FFI) exactly match what's 11 | # expected by the rust code on the other side of the interface. In practice right 12 | # now that means coming from the exact some version of `uniffi` that was used to 13 | # compile the rust component. The easiest way to ensure this is to bundle the Python 14 | # helpers directly inline like we're doing here. 15 | 16 | import os 17 | import sys 18 | import ctypes 19 | import enum 20 | import struct 21 | import contextlib 22 | import datetime 23 | import typing 24 | import platform 25 | 26 | # Used for default argument values 27 | _DEFAULT = object() 28 | 29 | 30 | class _UniffiRustBuffer(ctypes.Structure): 31 | _fields_ = [ 32 | ("capacity", ctypes.c_int32), 33 | ("len", ctypes.c_int32), 34 | ("data", ctypes.POINTER(ctypes.c_char)), 35 | ] 36 | 37 | @staticmethod 38 | def alloc(size): 39 | return _rust_call(_UniffiLib.ffi_apple_cache_rustbuffer_alloc, size) 40 | 41 | @staticmethod 42 | def reserve(rbuf, additional): 43 | return _rust_call(_UniffiLib.ffi_apple_cache_rustbuffer_reserve, rbuf, additional) 44 | 45 | def free(self): 46 | return _rust_call(_UniffiLib.ffi_apple_cache_rustbuffer_free, self) 47 | 48 | def __str__(self): 49 | return "_UniffiRustBuffer(capacity={}, len={}, data={})".format( 50 | self.capacity, 51 | self.len, 52 | self.data[0:self.len] 53 | ) 54 | 55 | @contextlib.contextmanager 56 | def alloc_with_builder(*args): 57 | """Context-manger to allocate a buffer using a _UniffiRustBufferBuilder. 58 | 59 | The allocated buffer will be automatically freed if an error occurs, ensuring that 60 | we don't accidentally leak it. 61 | """ 62 | builder = _UniffiRustBufferBuilder() 63 | try: 64 | yield builder 65 | except: 66 | builder.discard() 67 | raise 68 | 69 | @contextlib.contextmanager 70 | def consume_with_stream(self): 71 | """Context-manager to consume a buffer using a _UniffiRustBufferStream. 72 | 73 | The _UniffiRustBuffer will be freed once the context-manager exits, ensuring that we don't 74 | leak it even if an error occurs. 75 | """ 76 | try: 77 | s = _UniffiRustBufferStream.from_rust_buffer(self) 78 | yield s 79 | if s.remaining() != 0: 80 | raise RuntimeError("junk data left in buffer at end of consume_with_stream") 81 | finally: 82 | self.free() 83 | 84 | @contextlib.contextmanager 85 | def read_with_stream(self): 86 | """Context-manager to read a buffer using a _UniffiRustBufferStream. 87 | 88 | This is like consume_with_stream, but doesn't free the buffer afterwards. 89 | It should only be used with borrowed `_UniffiRustBuffer` data. 90 | """ 91 | s = _UniffiRustBufferStream.from_rust_buffer(self) 92 | yield s 93 | if s.remaining() != 0: 94 | raise RuntimeError("junk data left in buffer at end of read_with_stream") 95 | 96 | class _UniffiForeignBytes(ctypes.Structure): 97 | _fields_ = [ 98 | ("len", ctypes.c_int32), 99 | ("data", ctypes.POINTER(ctypes.c_char)), 100 | ] 101 | 102 | def __str__(self): 103 | return "_UniffiForeignBytes(len={}, data={})".format(self.len, self.data[0:self.len]) 104 | 105 | 106 | class _UniffiRustBufferStream: 107 | """ 108 | Helper for structured reading of bytes from a _UniffiRustBuffer 109 | """ 110 | 111 | def __init__(self, data, len): 112 | self.data = data 113 | self.len = len 114 | self.offset = 0 115 | 116 | @classmethod 117 | def from_rust_buffer(cls, buf): 118 | return cls(buf.data, buf.len) 119 | 120 | def remaining(self): 121 | return self.len - self.offset 122 | 123 | def _unpack_from(self, size, format): 124 | if self.offset + size > self.len: 125 | raise InternalError("read past end of rust buffer") 126 | value = struct.unpack(format, self.data[self.offset:self.offset+size])[0] 127 | self.offset += size 128 | return value 129 | 130 | def read(self, size): 131 | if self.offset + size > self.len: 132 | raise InternalError("read past end of rust buffer") 133 | data = self.data[self.offset:self.offset+size] 134 | self.offset += size 135 | return data 136 | 137 | def read_i8(self): 138 | return self._unpack_from(1, ">b") 139 | 140 | def read_u8(self): 141 | return self._unpack_from(1, ">B") 142 | 143 | def read_i16(self): 144 | return self._unpack_from(2, ">h") 145 | 146 | def read_u16(self): 147 | return self._unpack_from(2, ">H") 148 | 149 | def read_i32(self): 150 | return self._unpack_from(4, ">i") 151 | 152 | def read_u32(self): 153 | return self._unpack_from(4, ">I") 154 | 155 | def read_i64(self): 156 | return self._unpack_from(8, ">q") 157 | 158 | def read_u64(self): 159 | return self._unpack_from(8, ">Q") 160 | 161 | def read_float(self): 162 | v = self._unpack_from(4, ">f") 163 | return v 164 | 165 | def read_double(self): 166 | return self._unpack_from(8, ">d") 167 | 168 | def read_c_size_t(self): 169 | return self._unpack_from(ctypes.sizeof(ctypes.c_size_t) , "@N") 170 | 171 | class _UniffiRustBufferBuilder: 172 | """ 173 | Helper for structured writing of bytes into a _UniffiRustBuffer. 174 | """ 175 | 176 | def __init__(self): 177 | self.rbuf = _UniffiRustBuffer.alloc(16) 178 | self.rbuf.len = 0 179 | 180 | def finalize(self): 181 | rbuf = self.rbuf 182 | self.rbuf = None 183 | return rbuf 184 | 185 | def discard(self): 186 | if self.rbuf is not None: 187 | rbuf = self.finalize() 188 | rbuf.free() 189 | 190 | @contextlib.contextmanager 191 | def _reserve(self, num_bytes): 192 | if self.rbuf.len + num_bytes > self.rbuf.capacity: 193 | self.rbuf = _UniffiRustBuffer.reserve(self.rbuf, num_bytes) 194 | yield None 195 | self.rbuf.len += num_bytes 196 | 197 | def _pack_into(self, size, format, value): 198 | with self._reserve(size): 199 | # XXX TODO: I feel like I should be able to use `struct.pack_into` here but can't figure it out. 200 | for i, byte in enumerate(struct.pack(format, value)): 201 | self.rbuf.data[self.rbuf.len + i] = byte 202 | 203 | def write(self, value): 204 | with self._reserve(len(value)): 205 | for i, byte in enumerate(value): 206 | self.rbuf.data[self.rbuf.len + i] = byte 207 | 208 | def write_i8(self, v): 209 | self._pack_into(1, ">b", v) 210 | 211 | def write_u8(self, v): 212 | self._pack_into(1, ">B", v) 213 | 214 | def write_i16(self, v): 215 | self._pack_into(2, ">h", v) 216 | 217 | def write_u16(self, v): 218 | self._pack_into(2, ">H", v) 219 | 220 | def write_i32(self, v): 221 | self._pack_into(4, ">i", v) 222 | 223 | def write_u32(self, v): 224 | self._pack_into(4, ">I", v) 225 | 226 | def write_i64(self, v): 227 | self._pack_into(8, ">q", v) 228 | 229 | def write_u64(self, v): 230 | self._pack_into(8, ">Q", v) 231 | 232 | def write_float(self, v): 233 | self._pack_into(4, ">f", v) 234 | 235 | def write_double(self, v): 236 | self._pack_into(8, ">d", v) 237 | 238 | def write_c_size_t(self, v): 239 | self._pack_into(ctypes.sizeof(ctypes.c_size_t) , "@N", v) 240 | # A handful of classes and functions to support the generated data structures. 241 | # This would be a good candidate for isolating in its own ffi-support lib. 242 | 243 | class InternalError(Exception): 244 | pass 245 | 246 | class _UniffiRustCallStatus(ctypes.Structure): 247 | """ 248 | Error runtime. 249 | """ 250 | _fields_ = [ 251 | ("code", ctypes.c_int8), 252 | ("error_buf", _UniffiRustBuffer), 253 | ] 254 | 255 | # These match the values from the uniffi::rustcalls module 256 | CALL_SUCCESS = 0 257 | CALL_ERROR = 1 258 | CALL_PANIC = 2 259 | 260 | def __str__(self): 261 | if self.code == _UniffiRustCallStatus.CALL_SUCCESS: 262 | return "_UniffiRustCallStatus(CALL_SUCCESS)" 263 | elif self.code == _UniffiRustCallStatus.CALL_ERROR: 264 | return "_UniffiRustCallStatus(CALL_ERROR)" 265 | elif self.code == _UniffiRustCallStatus.CALL_PANIC: 266 | return "_UniffiRustCallStatus(CALL_PANIC)" 267 | else: 268 | return "_UniffiRustCallStatus()" 269 | 270 | def _rust_call(fn, *args): 271 | # Call a rust function 272 | return _rust_call_with_error(None, fn, *args) 273 | 274 | def _rust_call_with_error(error_ffi_converter, fn, *args): 275 | # Call a rust function and handle any errors 276 | # 277 | # This function is used for rust calls that return Result<> and therefore can set the CALL_ERROR status code. 278 | # error_ffi_converter must be set to the _UniffiConverter for the error class that corresponds to the result. 279 | call_status = _UniffiRustCallStatus(code=_UniffiRustCallStatus.CALL_SUCCESS, error_buf=_UniffiRustBuffer(0, 0, None)) 280 | 281 | args_with_error = args + (ctypes.byref(call_status),) 282 | result = fn(*args_with_error) 283 | _uniffi_check_call_status(error_ffi_converter, call_status) 284 | return result 285 | 286 | def _uniffi_check_call_status(error_ffi_converter, call_status): 287 | if call_status.code == _UniffiRustCallStatus.CALL_SUCCESS: 288 | pass 289 | elif call_status.code == _UniffiRustCallStatus.CALL_ERROR: 290 | if error_ffi_converter is None: 291 | call_status.error_buf.free() 292 | raise InternalError("_rust_call_with_error: CALL_ERROR, but error_ffi_converter is None") 293 | else: 294 | raise error_ffi_converter.lift(call_status.error_buf) 295 | elif call_status.code == _UniffiRustCallStatus.CALL_PANIC: 296 | # When the rust code sees a panic, it tries to construct a _UniffiRustBuffer 297 | # with the message. But if that code panics, then it just sends back 298 | # an empty buffer. 299 | if call_status.error_buf.len > 0: 300 | msg = _UniffiConverterString.lift(call_status.error_buf) 301 | else: 302 | msg = "Unknown rust panic" 303 | raise InternalError(msg) 304 | else: 305 | raise InternalError("Invalid _UniffiRustCallStatus code: {}".format( 306 | call_status.code)) 307 | 308 | # A function pointer for a callback as defined by UniFFI. 309 | # Rust definition `fn(handle: u64, method: u32, args: _UniffiRustBuffer, buf_ptr: *mut _UniffiRustBuffer) -> int` 310 | _UNIFFI_FOREIGN_CALLBACK_T = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_ulonglong, ctypes.c_ulong, ctypes.POINTER(ctypes.c_char), ctypes.c_int, ctypes.POINTER(_UniffiRustBuffer)) 311 | 312 | # UniFFI future continuation 313 | _UNIFFI_FUTURE_CONTINUATION_T = ctypes.CFUNCTYPE(None, ctypes.c_size_t, ctypes.c_int8) 314 | class _UniffiPointerManagerCPython: 315 | """ 316 | Manage giving out pointers to Python objects on CPython 317 | 318 | This class is used to generate opaque pointers that reference Python objects to pass to Rust. 319 | It assumes a CPython platform. See _UniffiPointerManagerGeneral for the alternative. 320 | """ 321 | 322 | def new_pointer(self, obj): 323 | """ 324 | Get a pointer for an object as a ctypes.c_size_t instance 325 | 326 | Each call to new_pointer() must be balanced with exactly one call to release_pointer() 327 | 328 | This returns a ctypes.c_size_t. This is always the same size as a pointer and can be 329 | interchanged with pointers for FFI function arguments and return values. 330 | """ 331 | # IncRef the object since we're going to pass a pointer to Rust 332 | ctypes.pythonapi.Py_IncRef(ctypes.py_object(obj)) 333 | # id() is the object address on CPython 334 | # (https://docs.python.org/3/library/functions.html#id) 335 | return id(obj) 336 | 337 | def release_pointer(self, address): 338 | py_obj = ctypes.cast(address, ctypes.py_object) 339 | obj = py_obj.value 340 | ctypes.pythonapi.Py_DecRef(py_obj) 341 | return obj 342 | 343 | def lookup(self, address): 344 | return ctypes.cast(address, ctypes.py_object).value 345 | 346 | class _UniffiPointerManagerGeneral: 347 | """ 348 | Manage giving out pointers to Python objects on non-CPython platforms 349 | 350 | This has the same API as _UniffiPointerManagerCPython, but doesn't assume we're running on 351 | CPython and is slightly slower. 352 | 353 | Instead of using real pointers, it maps integer values to objects and returns the keys as 354 | c_size_t values. 355 | """ 356 | 357 | def __init__(self): 358 | self._map = {} 359 | self._lock = threading.Lock() 360 | self._current_handle = 0 361 | 362 | def new_pointer(self, obj): 363 | with self._lock: 364 | handle = self._current_handle 365 | self._current_handle += 1 366 | self._map[handle] = obj 367 | return handle 368 | 369 | def release_pointer(self, handle): 370 | with self._lock: 371 | return self._map.pop(handle) 372 | 373 | def lookup(self, handle): 374 | with self._lock: 375 | return self._map[handle] 376 | 377 | # Pick an pointer manager implementation based on the platform 378 | if platform.python_implementation() == 'CPython': 379 | _UniffiPointerManager = _UniffiPointerManagerCPython # type: ignore 380 | else: 381 | _UniffiPointerManager = _UniffiPointerManagerGeneral # type: ignore 382 | # Types conforming to `_UniffiConverterPrimitive` pass themselves directly over the FFI. 383 | class _UniffiConverterPrimitive: 384 | @classmethod 385 | def check(cls, value): 386 | return value 387 | 388 | @classmethod 389 | def lift(cls, value): 390 | return value 391 | 392 | @classmethod 393 | def lower(cls, value): 394 | return cls.lowerUnchecked(cls.check(value)) 395 | 396 | @classmethod 397 | def lowerUnchecked(cls, value): 398 | return value 399 | 400 | @classmethod 401 | def write(cls, value, buf): 402 | cls.write_unchecked(cls.check(value), buf) 403 | 404 | class _UniffiConverterPrimitiveInt(_UniffiConverterPrimitive): 405 | @classmethod 406 | def check(cls, value): 407 | try: 408 | value = value.__index__() 409 | except Exception: 410 | raise TypeError("'{}' object cannot be interpreted as an integer".format(type(value).__name__)) 411 | if not isinstance(value, int): 412 | raise TypeError("__index__ returned non-int (type {})".format(type(value).__name__)) 413 | if not cls.VALUE_MIN <= value < cls.VALUE_MAX: 414 | raise ValueError("{} requires {} <= value < {}".format(cls.CLASS_NAME, cls.VALUE_MIN, cls.VALUE_MAX)) 415 | return super().check(value) 416 | 417 | class _UniffiConverterPrimitiveFloat(_UniffiConverterPrimitive): 418 | @classmethod 419 | def check(cls, value): 420 | try: 421 | value = value.__float__() 422 | except Exception: 423 | raise TypeError("must be real number, not {}".format(type(value).__name__)) 424 | if not isinstance(value, float): 425 | raise TypeError("__float__ returned non-float (type {})".format(type(value).__name__)) 426 | return super().check(value) 427 | 428 | # Helper class for wrapper types that will always go through a _UniffiRustBuffer. 429 | # Classes should inherit from this and implement the `read` and `write` static methods. 430 | class _UniffiConverterRustBuffer: 431 | @classmethod 432 | def lift(cls, rbuf): 433 | with rbuf.consume_with_stream() as stream: 434 | return cls.read(stream) 435 | 436 | @classmethod 437 | def lower(cls, value): 438 | with _UniffiRustBuffer.alloc_with_builder() as builder: 439 | cls.write(value, builder) 440 | return builder.finalize() 441 | 442 | # Contains loading, initialization code, and the FFI Function declarations. 443 | # Define some ctypes FFI types that we use in the library 444 | 445 | """ 446 | ctypes type for the foreign executor callback. This is a built-in interface for scheduling 447 | tasks 448 | 449 | Args: 450 | executor: opaque c_size_t value representing the eventloop 451 | delay: delay in ms 452 | task: function pointer to the task callback 453 | task_data: void pointer to the task callback data 454 | 455 | Normally we should call task(task_data) after the detail. 456 | However, when task is NULL this indicates that Rust has dropped the ForeignExecutor and we should 457 | decrease the EventLoop refcount. 458 | """ 459 | _UNIFFI_FOREIGN_EXECUTOR_CALLBACK_T = ctypes.CFUNCTYPE(ctypes.c_int8, ctypes.c_size_t, ctypes.c_uint32, ctypes.c_void_p, ctypes.c_void_p) 460 | 461 | """ 462 | Function pointer for a Rust task, which a callback function that takes a opaque pointer 463 | """ 464 | _UNIFFI_RUST_TASK = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_int8) 465 | 466 | def _uniffi_future_callback_t(return_type): 467 | """ 468 | Factory function to create callback function types for async functions 469 | """ 470 | return ctypes.CFUNCTYPE(None, ctypes.c_size_t, return_type, _UniffiRustCallStatus) 471 | 472 | def _uniffi_load_indirect(): 473 | """ 474 | This is how we find and load the dynamic library provided by the component. 475 | For now we just look it up by name. 476 | """ 477 | if sys.platform == "darwin": 478 | libname = "lib{}.dylib" 479 | elif sys.platform.startswith("win"): 480 | # As of python3.8, ctypes does not seem to search $PATH when loading DLLs. 481 | # We could use `os.add_dll_directory` to configure the search path, but 482 | # it doesn't feel right to mess with application-wide settings. Let's 483 | # assume that the `.dll` is next to the `.py` file and load by full path. 484 | libname = os.path.join( 485 | os.path.dirname(__file__), 486 | "{}.dll", 487 | ) 488 | else: 489 | # Anything else must be an ELF platform - Linux, *BSD, Solaris/illumos 490 | libname = "lib{}.so" 491 | 492 | libname = libname.format("apple_cache") 493 | path = os.path.join(os.path.dirname(__file__), libname) 494 | lib = ctypes.cdll.LoadLibrary(path) 495 | return lib 496 | 497 | def _uniffi_check_contract_api_version(lib): 498 | # Get the bindings contract version from our ComponentInterface 499 | bindings_contract_version = 24 500 | # Get the scaffolding contract version by calling the into the dylib 501 | scaffolding_contract_version = lib.ffi_apple_cache_uniffi_contract_version() 502 | if bindings_contract_version != scaffolding_contract_version: 503 | raise InternalError("UniFFI contract version mismatch: try cleaning and rebuilding your project") 504 | 505 | def _uniffi_check_api_checksums(lib): 506 | if lib.uniffi_apple_cache_checksum_func_init_serial() != 12034: 507 | raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 508 | if lib.uniffi_apple_cache_checksum_method_cacheapi_create() != 13109: 509 | raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 510 | if lib.uniffi_apple_cache_checksum_method_cacheapi_obtain() != 36005: 511 | raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 512 | if lib.uniffi_apple_cache_checksum_method_cacheapi_sign() != 51638: 513 | raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 514 | if lib.uniffi_apple_cache_checksum_constructor_cacheapi_new() != 6028: 515 | raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 516 | 517 | # A ctypes library to expose the extern-C FFI definitions. 518 | # This is an implementation detail which will be called internally by the public API. 519 | 520 | _UniffiLib = _uniffi_load_indirect() 521 | _UniffiLib.uniffi_apple_cache_fn_free_cacheapi.argtypes = ( 522 | ctypes.c_void_p, 523 | ctypes.POINTER(_UniffiRustCallStatus), 524 | ) 525 | _UniffiLib.uniffi_apple_cache_fn_free_cacheapi.restype = None 526 | _UniffiLib.uniffi_apple_cache_fn_constructor_cacheapi_new.argtypes = ( 527 | ctypes.POINTER(_UniffiRustCallStatus), 528 | ) 529 | _UniffiLib.uniffi_apple_cache_fn_constructor_cacheapi_new.restype = ctypes.c_void_p 530 | _UniffiLib.uniffi_apple_cache_fn_method_cacheapi_create.argtypes = ( 531 | ctypes.c_void_p, 532 | _UniffiRustBuffer, 533 | ctypes.POINTER(_UniffiRustCallStatus), 534 | ) 535 | _UniffiLib.uniffi_apple_cache_fn_method_cacheapi_create.restype = _UniffiRustBuffer 536 | _UniffiLib.uniffi_apple_cache_fn_method_cacheapi_obtain.argtypes = ( 537 | ctypes.c_void_p, 538 | ctypes.c_uint64, 539 | _UniffiRustBuffer, 540 | ctypes.POINTER(_UniffiRustCallStatus), 541 | ) 542 | _UniffiLib.uniffi_apple_cache_fn_method_cacheapi_obtain.restype = None 543 | _UniffiLib.uniffi_apple_cache_fn_method_cacheapi_sign.argtypes = ( 544 | ctypes.c_void_p, 545 | ctypes.c_uint64, 546 | _UniffiRustBuffer, 547 | ctypes.POINTER(_UniffiRustCallStatus), 548 | ) 549 | _UniffiLib.uniffi_apple_cache_fn_method_cacheapi_sign.restype = _UniffiRustBuffer 550 | _UniffiLib.uniffi_apple_cache_fn_func_init_serial.argtypes = ( 551 | _UniffiRustBuffer, 552 | ctypes.POINTER(_UniffiRustCallStatus), 553 | ) 554 | _UniffiLib.uniffi_apple_cache_fn_func_init_serial.restype = None 555 | _UniffiLib.ffi_apple_cache_rustbuffer_alloc.argtypes = ( 556 | ctypes.c_int32, 557 | ctypes.POINTER(_UniffiRustCallStatus), 558 | ) 559 | _UniffiLib.ffi_apple_cache_rustbuffer_alloc.restype = _UniffiRustBuffer 560 | _UniffiLib.ffi_apple_cache_rustbuffer_from_bytes.argtypes = ( 561 | _UniffiForeignBytes, 562 | ctypes.POINTER(_UniffiRustCallStatus), 563 | ) 564 | _UniffiLib.ffi_apple_cache_rustbuffer_from_bytes.restype = _UniffiRustBuffer 565 | _UniffiLib.ffi_apple_cache_rustbuffer_free.argtypes = ( 566 | _UniffiRustBuffer, 567 | ctypes.POINTER(_UniffiRustCallStatus), 568 | ) 569 | _UniffiLib.ffi_apple_cache_rustbuffer_free.restype = None 570 | _UniffiLib.ffi_apple_cache_rustbuffer_reserve.argtypes = ( 571 | _UniffiRustBuffer, 572 | ctypes.c_int32, 573 | ctypes.POINTER(_UniffiRustCallStatus), 574 | ) 575 | _UniffiLib.ffi_apple_cache_rustbuffer_reserve.restype = _UniffiRustBuffer 576 | _UniffiLib.ffi_apple_cache_rust_future_continuation_callback_set.argtypes = ( 577 | _UNIFFI_FUTURE_CONTINUATION_T, 578 | ) 579 | _UniffiLib.ffi_apple_cache_rust_future_continuation_callback_set.restype = None 580 | _UniffiLib.ffi_apple_cache_rust_future_poll_u8.argtypes = ( 581 | ctypes.c_void_p, 582 | ctypes.c_size_t, 583 | ) 584 | _UniffiLib.ffi_apple_cache_rust_future_poll_u8.restype = None 585 | _UniffiLib.ffi_apple_cache_rust_future_cancel_u8.argtypes = ( 586 | ctypes.c_void_p, 587 | ) 588 | _UniffiLib.ffi_apple_cache_rust_future_cancel_u8.restype = None 589 | _UniffiLib.ffi_apple_cache_rust_future_free_u8.argtypes = ( 590 | ctypes.c_void_p, 591 | ) 592 | _UniffiLib.ffi_apple_cache_rust_future_free_u8.restype = None 593 | _UniffiLib.ffi_apple_cache_rust_future_complete_u8.argtypes = ( 594 | ctypes.c_void_p, 595 | ctypes.POINTER(_UniffiRustCallStatus), 596 | ) 597 | _UniffiLib.ffi_apple_cache_rust_future_complete_u8.restype = ctypes.c_uint8 598 | _UniffiLib.ffi_apple_cache_rust_future_poll_i8.argtypes = ( 599 | ctypes.c_void_p, 600 | ctypes.c_size_t, 601 | ) 602 | _UniffiLib.ffi_apple_cache_rust_future_poll_i8.restype = None 603 | _UniffiLib.ffi_apple_cache_rust_future_cancel_i8.argtypes = ( 604 | ctypes.c_void_p, 605 | ) 606 | _UniffiLib.ffi_apple_cache_rust_future_cancel_i8.restype = None 607 | _UniffiLib.ffi_apple_cache_rust_future_free_i8.argtypes = ( 608 | ctypes.c_void_p, 609 | ) 610 | _UniffiLib.ffi_apple_cache_rust_future_free_i8.restype = None 611 | _UniffiLib.ffi_apple_cache_rust_future_complete_i8.argtypes = ( 612 | ctypes.c_void_p, 613 | ctypes.POINTER(_UniffiRustCallStatus), 614 | ) 615 | _UniffiLib.ffi_apple_cache_rust_future_complete_i8.restype = ctypes.c_int8 616 | _UniffiLib.ffi_apple_cache_rust_future_poll_u16.argtypes = ( 617 | ctypes.c_void_p, 618 | ctypes.c_size_t, 619 | ) 620 | _UniffiLib.ffi_apple_cache_rust_future_poll_u16.restype = None 621 | _UniffiLib.ffi_apple_cache_rust_future_cancel_u16.argtypes = ( 622 | ctypes.c_void_p, 623 | ) 624 | _UniffiLib.ffi_apple_cache_rust_future_cancel_u16.restype = None 625 | _UniffiLib.ffi_apple_cache_rust_future_free_u16.argtypes = ( 626 | ctypes.c_void_p, 627 | ) 628 | _UniffiLib.ffi_apple_cache_rust_future_free_u16.restype = None 629 | _UniffiLib.ffi_apple_cache_rust_future_complete_u16.argtypes = ( 630 | ctypes.c_void_p, 631 | ctypes.POINTER(_UniffiRustCallStatus), 632 | ) 633 | _UniffiLib.ffi_apple_cache_rust_future_complete_u16.restype = ctypes.c_uint16 634 | _UniffiLib.ffi_apple_cache_rust_future_poll_i16.argtypes = ( 635 | ctypes.c_void_p, 636 | ctypes.c_size_t, 637 | ) 638 | _UniffiLib.ffi_apple_cache_rust_future_poll_i16.restype = None 639 | _UniffiLib.ffi_apple_cache_rust_future_cancel_i16.argtypes = ( 640 | ctypes.c_void_p, 641 | ) 642 | _UniffiLib.ffi_apple_cache_rust_future_cancel_i16.restype = None 643 | _UniffiLib.ffi_apple_cache_rust_future_free_i16.argtypes = ( 644 | ctypes.c_void_p, 645 | ) 646 | _UniffiLib.ffi_apple_cache_rust_future_free_i16.restype = None 647 | _UniffiLib.ffi_apple_cache_rust_future_complete_i16.argtypes = ( 648 | ctypes.c_void_p, 649 | ctypes.POINTER(_UniffiRustCallStatus), 650 | ) 651 | _UniffiLib.ffi_apple_cache_rust_future_complete_i16.restype = ctypes.c_int16 652 | _UniffiLib.ffi_apple_cache_rust_future_poll_u32.argtypes = ( 653 | ctypes.c_void_p, 654 | ctypes.c_size_t, 655 | ) 656 | _UniffiLib.ffi_apple_cache_rust_future_poll_u32.restype = None 657 | _UniffiLib.ffi_apple_cache_rust_future_cancel_u32.argtypes = ( 658 | ctypes.c_void_p, 659 | ) 660 | _UniffiLib.ffi_apple_cache_rust_future_cancel_u32.restype = None 661 | _UniffiLib.ffi_apple_cache_rust_future_free_u32.argtypes = ( 662 | ctypes.c_void_p, 663 | ) 664 | _UniffiLib.ffi_apple_cache_rust_future_free_u32.restype = None 665 | _UniffiLib.ffi_apple_cache_rust_future_complete_u32.argtypes = ( 666 | ctypes.c_void_p, 667 | ctypes.POINTER(_UniffiRustCallStatus), 668 | ) 669 | _UniffiLib.ffi_apple_cache_rust_future_complete_u32.restype = ctypes.c_uint32 670 | _UniffiLib.ffi_apple_cache_rust_future_poll_i32.argtypes = ( 671 | ctypes.c_void_p, 672 | ctypes.c_size_t, 673 | ) 674 | _UniffiLib.ffi_apple_cache_rust_future_poll_i32.restype = None 675 | _UniffiLib.ffi_apple_cache_rust_future_cancel_i32.argtypes = ( 676 | ctypes.c_void_p, 677 | ) 678 | _UniffiLib.ffi_apple_cache_rust_future_cancel_i32.restype = None 679 | _UniffiLib.ffi_apple_cache_rust_future_free_i32.argtypes = ( 680 | ctypes.c_void_p, 681 | ) 682 | _UniffiLib.ffi_apple_cache_rust_future_free_i32.restype = None 683 | _UniffiLib.ffi_apple_cache_rust_future_complete_i32.argtypes = ( 684 | ctypes.c_void_p, 685 | ctypes.POINTER(_UniffiRustCallStatus), 686 | ) 687 | _UniffiLib.ffi_apple_cache_rust_future_complete_i32.restype = ctypes.c_int32 688 | _UniffiLib.ffi_apple_cache_rust_future_poll_u64.argtypes = ( 689 | ctypes.c_void_p, 690 | ctypes.c_size_t, 691 | ) 692 | _UniffiLib.ffi_apple_cache_rust_future_poll_u64.restype = None 693 | _UniffiLib.ffi_apple_cache_rust_future_cancel_u64.argtypes = ( 694 | ctypes.c_void_p, 695 | ) 696 | _UniffiLib.ffi_apple_cache_rust_future_cancel_u64.restype = None 697 | _UniffiLib.ffi_apple_cache_rust_future_free_u64.argtypes = ( 698 | ctypes.c_void_p, 699 | ) 700 | _UniffiLib.ffi_apple_cache_rust_future_free_u64.restype = None 701 | _UniffiLib.ffi_apple_cache_rust_future_complete_u64.argtypes = ( 702 | ctypes.c_void_p, 703 | ctypes.POINTER(_UniffiRustCallStatus), 704 | ) 705 | _UniffiLib.ffi_apple_cache_rust_future_complete_u64.restype = ctypes.c_uint64 706 | _UniffiLib.ffi_apple_cache_rust_future_poll_i64.argtypes = ( 707 | ctypes.c_void_p, 708 | ctypes.c_size_t, 709 | ) 710 | _UniffiLib.ffi_apple_cache_rust_future_poll_i64.restype = None 711 | _UniffiLib.ffi_apple_cache_rust_future_cancel_i64.argtypes = ( 712 | ctypes.c_void_p, 713 | ) 714 | _UniffiLib.ffi_apple_cache_rust_future_cancel_i64.restype = None 715 | _UniffiLib.ffi_apple_cache_rust_future_free_i64.argtypes = ( 716 | ctypes.c_void_p, 717 | ) 718 | _UniffiLib.ffi_apple_cache_rust_future_free_i64.restype = None 719 | _UniffiLib.ffi_apple_cache_rust_future_complete_i64.argtypes = ( 720 | ctypes.c_void_p, 721 | ctypes.POINTER(_UniffiRustCallStatus), 722 | ) 723 | _UniffiLib.ffi_apple_cache_rust_future_complete_i64.restype = ctypes.c_int64 724 | _UniffiLib.ffi_apple_cache_rust_future_poll_f32.argtypes = ( 725 | ctypes.c_void_p, 726 | ctypes.c_size_t, 727 | ) 728 | _UniffiLib.ffi_apple_cache_rust_future_poll_f32.restype = None 729 | _UniffiLib.ffi_apple_cache_rust_future_cancel_f32.argtypes = ( 730 | ctypes.c_void_p, 731 | ) 732 | _UniffiLib.ffi_apple_cache_rust_future_cancel_f32.restype = None 733 | _UniffiLib.ffi_apple_cache_rust_future_free_f32.argtypes = ( 734 | ctypes.c_void_p, 735 | ) 736 | _UniffiLib.ffi_apple_cache_rust_future_free_f32.restype = None 737 | _UniffiLib.ffi_apple_cache_rust_future_complete_f32.argtypes = ( 738 | ctypes.c_void_p, 739 | ctypes.POINTER(_UniffiRustCallStatus), 740 | ) 741 | _UniffiLib.ffi_apple_cache_rust_future_complete_f32.restype = ctypes.c_float 742 | _UniffiLib.ffi_apple_cache_rust_future_poll_f64.argtypes = ( 743 | ctypes.c_void_p, 744 | ctypes.c_size_t, 745 | ) 746 | _UniffiLib.ffi_apple_cache_rust_future_poll_f64.restype = None 747 | _UniffiLib.ffi_apple_cache_rust_future_cancel_f64.argtypes = ( 748 | ctypes.c_void_p, 749 | ) 750 | _UniffiLib.ffi_apple_cache_rust_future_cancel_f64.restype = None 751 | _UniffiLib.ffi_apple_cache_rust_future_free_f64.argtypes = ( 752 | ctypes.c_void_p, 753 | ) 754 | _UniffiLib.ffi_apple_cache_rust_future_free_f64.restype = None 755 | _UniffiLib.ffi_apple_cache_rust_future_complete_f64.argtypes = ( 756 | ctypes.c_void_p, 757 | ctypes.POINTER(_UniffiRustCallStatus), 758 | ) 759 | _UniffiLib.ffi_apple_cache_rust_future_complete_f64.restype = ctypes.c_double 760 | _UniffiLib.ffi_apple_cache_rust_future_poll_pointer.argtypes = ( 761 | ctypes.c_void_p, 762 | ctypes.c_size_t, 763 | ) 764 | _UniffiLib.ffi_apple_cache_rust_future_poll_pointer.restype = None 765 | _UniffiLib.ffi_apple_cache_rust_future_cancel_pointer.argtypes = ( 766 | ctypes.c_void_p, 767 | ) 768 | _UniffiLib.ffi_apple_cache_rust_future_cancel_pointer.restype = None 769 | _UniffiLib.ffi_apple_cache_rust_future_free_pointer.argtypes = ( 770 | ctypes.c_void_p, 771 | ) 772 | _UniffiLib.ffi_apple_cache_rust_future_free_pointer.restype = None 773 | _UniffiLib.ffi_apple_cache_rust_future_complete_pointer.argtypes = ( 774 | ctypes.c_void_p, 775 | ctypes.POINTER(_UniffiRustCallStatus), 776 | ) 777 | _UniffiLib.ffi_apple_cache_rust_future_complete_pointer.restype = ctypes.c_void_p 778 | _UniffiLib.ffi_apple_cache_rust_future_poll_rust_buffer.argtypes = ( 779 | ctypes.c_void_p, 780 | ctypes.c_size_t, 781 | ) 782 | _UniffiLib.ffi_apple_cache_rust_future_poll_rust_buffer.restype = None 783 | _UniffiLib.ffi_apple_cache_rust_future_cancel_rust_buffer.argtypes = ( 784 | ctypes.c_void_p, 785 | ) 786 | _UniffiLib.ffi_apple_cache_rust_future_cancel_rust_buffer.restype = None 787 | _UniffiLib.ffi_apple_cache_rust_future_free_rust_buffer.argtypes = ( 788 | ctypes.c_void_p, 789 | ) 790 | _UniffiLib.ffi_apple_cache_rust_future_free_rust_buffer.restype = None 791 | _UniffiLib.ffi_apple_cache_rust_future_complete_rust_buffer.argtypes = ( 792 | ctypes.c_void_p, 793 | ctypes.POINTER(_UniffiRustCallStatus), 794 | ) 795 | _UniffiLib.ffi_apple_cache_rust_future_complete_rust_buffer.restype = _UniffiRustBuffer 796 | _UniffiLib.ffi_apple_cache_rust_future_poll_void.argtypes = ( 797 | ctypes.c_void_p, 798 | ctypes.c_size_t, 799 | ) 800 | _UniffiLib.ffi_apple_cache_rust_future_poll_void.restype = None 801 | _UniffiLib.ffi_apple_cache_rust_future_cancel_void.argtypes = ( 802 | ctypes.c_void_p, 803 | ) 804 | _UniffiLib.ffi_apple_cache_rust_future_cancel_void.restype = None 805 | _UniffiLib.ffi_apple_cache_rust_future_free_void.argtypes = ( 806 | ctypes.c_void_p, 807 | ) 808 | _UniffiLib.ffi_apple_cache_rust_future_free_void.restype = None 809 | _UniffiLib.ffi_apple_cache_rust_future_complete_void.argtypes = ( 810 | ctypes.c_void_p, 811 | ctypes.POINTER(_UniffiRustCallStatus), 812 | ) 813 | _UniffiLib.ffi_apple_cache_rust_future_complete_void.restype = None 814 | _UniffiLib.uniffi_apple_cache_checksum_func_init_serial.argtypes = ( 815 | ) 816 | _UniffiLib.uniffi_apple_cache_checksum_func_init_serial.restype = ctypes.c_uint16 817 | _UniffiLib.uniffi_apple_cache_checksum_method_cacheapi_create.argtypes = ( 818 | ) 819 | _UniffiLib.uniffi_apple_cache_checksum_method_cacheapi_create.restype = ctypes.c_uint16 820 | _UniffiLib.uniffi_apple_cache_checksum_method_cacheapi_obtain.argtypes = ( 821 | ) 822 | _UniffiLib.uniffi_apple_cache_checksum_method_cacheapi_obtain.restype = ctypes.c_uint16 823 | _UniffiLib.uniffi_apple_cache_checksum_method_cacheapi_sign.argtypes = ( 824 | ) 825 | _UniffiLib.uniffi_apple_cache_checksum_method_cacheapi_sign.restype = ctypes.c_uint16 826 | _UniffiLib.uniffi_apple_cache_checksum_constructor_cacheapi_new.argtypes = ( 827 | ) 828 | _UniffiLib.uniffi_apple_cache_checksum_constructor_cacheapi_new.restype = ctypes.c_uint16 829 | _UniffiLib.ffi_apple_cache_uniffi_contract_version.argtypes = ( 830 | ) 831 | _UniffiLib.ffi_apple_cache_uniffi_contract_version.restype = ctypes.c_uint32 832 | _uniffi_check_contract_api_version(_UniffiLib) 833 | _uniffi_check_api_checksums(_UniffiLib) 834 | 835 | # Async support 836 | 837 | # Public interface members begin here. 838 | 839 | 840 | class _UniffiConverterUInt8(_UniffiConverterPrimitiveInt): 841 | CLASS_NAME = "u8" 842 | VALUE_MIN = 0 843 | VALUE_MAX = 2**8 844 | 845 | @staticmethod 846 | def read(buf): 847 | return buf.read_u8() 848 | 849 | @staticmethod 850 | def write_unchecked(value, buf): 851 | buf.write_u8(value) 852 | 853 | class _UniffiConverterUInt64(_UniffiConverterPrimitiveInt): 854 | CLASS_NAME = "u64" 855 | VALUE_MIN = 0 856 | VALUE_MAX = 2**64 857 | 858 | @staticmethod 859 | def read(buf): 860 | return buf.read_u64() 861 | 862 | @staticmethod 863 | def write_unchecked(value, buf): 864 | buf.write_u64(value) 865 | 866 | class _UniffiConverterString: 867 | @staticmethod 868 | def check(value): 869 | if not isinstance(value, str): 870 | raise TypeError("argument must be str, not {}".format(type(value).__name__)) 871 | return value 872 | 873 | @staticmethod 874 | def read(buf): 875 | size = buf.read_i32() 876 | if size < 0: 877 | raise InternalError("Unexpected negative string length") 878 | utf8_bytes = buf.read(size) 879 | return utf8_bytes.decode("utf-8") 880 | 881 | @staticmethod 882 | def write(value, buf): 883 | value = _UniffiConverterString.check(value) 884 | utf8_bytes = value.encode("utf-8") 885 | buf.write_i32(len(utf8_bytes)) 886 | buf.write(utf8_bytes) 887 | 888 | @staticmethod 889 | def lift(buf): 890 | with buf.consume_with_stream() as stream: 891 | return stream.read(stream.remaining()).decode("utf-8") 892 | 893 | @staticmethod 894 | def lower(value): 895 | value = _UniffiConverterString.check(value) 896 | with _UniffiRustBuffer.alloc_with_builder() as builder: 897 | builder.write(value.encode("utf-8")) 898 | return builder.finalize() 899 | 900 | 901 | 902 | class CacheApi: 903 | _pointer: ctypes.c_void_p 904 | def __init__(self, ): 905 | self._pointer = _rust_call_with_error(_UniffiConverterTypeCacheError,_UniffiLib.uniffi_apple_cache_fn_constructor_cacheapi_new,) 906 | 907 | def __del__(self): 908 | # In case of partial initialization of instances. 909 | pointer = getattr(self, "_pointer", None) 910 | if pointer is not None: 911 | _rust_call(_UniffiLib.uniffi_apple_cache_fn_free_cacheapi, pointer) 912 | 913 | # Used by alternative constructors or any methods which return this type. 914 | @classmethod 915 | def _make_instance_(cls, pointer): 916 | # Lightly yucky way to bypass the usual __init__ logic 917 | # and just create a new instance with the required pointer. 918 | inst = cls.__new__(cls) 919 | inst._pointer = pointer 920 | return inst 921 | 922 | 923 | def create(self, cert: "typing.Optional[typing.List[int]]") -> "CacheResult": 924 | 925 | return _UniffiConverterTypeCacheResult.lift( 926 | _rust_call_with_error( 927 | _UniffiConverterTypeCacheError,_UniffiLib.uniffi_apple_cache_fn_method_cacheapi_create,self._pointer, 928 | _UniffiConverterOptionalSequenceUInt8.lower(cert)) 929 | ) 930 | 931 | 932 | 933 | 934 | 935 | 936 | def obtain(self, ctx: "int",session: "typing.List[int]"): 937 | 938 | 939 | _rust_call_with_error( 940 | _UniffiConverterTypeCacheError,_UniffiLib.uniffi_apple_cache_fn_method_cacheapi_obtain,self._pointer, 941 | _UniffiConverterUInt64.lower(ctx), 942 | _UniffiConverterSequenceUInt8.lower(session)) 943 | 944 | 945 | 946 | 947 | 948 | 949 | 950 | def sign(self, ctx: "int",data: "typing.List[int]") -> "typing.List[int]": 951 | 952 | 953 | return _UniffiConverterSequenceUInt8.lift( 954 | _rust_call_with_error( 955 | _UniffiConverterTypeCacheError,_UniffiLib.uniffi_apple_cache_fn_method_cacheapi_sign,self._pointer, 956 | _UniffiConverterUInt64.lower(ctx), 957 | _UniffiConverterSequenceUInt8.lower(data)) 958 | ) 959 | 960 | 961 | 962 | 963 | 964 | 965 | class _UniffiConverterTypeCacheApi: 966 | @classmethod 967 | def read(cls, buf): 968 | ptr = buf.read_u64() 969 | if ptr == 0: 970 | raise InternalError("Raw pointer value was null") 971 | return cls.lift(ptr) 972 | 973 | @classmethod 974 | def write(cls, value, buf): 975 | if not isinstance(value, CacheApi): 976 | raise TypeError("Expected CacheApi instance, {} found".format(type(value).__name__)) 977 | buf.write_u64(cls.lower(value)) 978 | 979 | @staticmethod 980 | def lift(value): 981 | return CacheApi._make_instance_(value) 982 | 983 | @staticmethod 984 | def lower(value): 985 | return value._pointer 986 | 987 | 988 | class CacheResult: 989 | ctx: "int";data: "typing.List[int]"; 990 | 991 | @typing.no_type_check 992 | def __init__(self, ctx: "int", data: "typing.List[int]"): 993 | self.ctx = ctx 994 | self.data = data 995 | 996 | def __str__(self): 997 | return "CacheResult(ctx={}, data={})".format(self.ctx, self.data) 998 | 999 | def __eq__(self, other): 1000 | if self.ctx != other.ctx: 1001 | return False 1002 | if self.data != other.data: 1003 | return False 1004 | return True 1005 | 1006 | class _UniffiConverterTypeCacheResult(_UniffiConverterRustBuffer): 1007 | @staticmethod 1008 | def read(buf): 1009 | return CacheResult( 1010 | ctx=_UniffiConverterUInt64.read(buf), 1011 | data=_UniffiConverterSequenceUInt8.read(buf), 1012 | ) 1013 | 1014 | @staticmethod 1015 | def write(value, buf): 1016 | _UniffiConverterUInt64.write(value.ctx, buf) 1017 | _UniffiConverterSequenceUInt8.write(value.data, buf) 1018 | 1019 | 1020 | # CacheError 1021 | # We want to define each variant as a nested class that's also a subclass, 1022 | # which is tricky in Python. To accomplish this we're going to create each 1023 | # class separately, then manually add the child classes to the base class's 1024 | # __dict__. All of this happens in dummy class to avoid polluting the module 1025 | # namespace. 1026 | class CacheError(Exception): 1027 | pass 1028 | 1029 | _UniffiTempCacheError = CacheError 1030 | 1031 | class CacheError: # type: ignore 1032 | class HandleFailed(_UniffiTempCacheError): 1033 | def __repr__(self): 1034 | return "CacheError.HandleFailed({})".format(repr(str(self))) 1035 | _UniffiTempCacheError.HandleFailed = HandleFailed # type: ignore 1036 | 1037 | CacheError = _UniffiTempCacheError # type: ignore 1038 | del _UniffiTempCacheError 1039 | 1040 | 1041 | class _UniffiConverterTypeCacheError(_UniffiConverterRustBuffer): 1042 | @staticmethod 1043 | def read(buf): 1044 | variant = buf.read_i32() 1045 | if variant == 1: 1046 | return CacheError.HandleFailed( 1047 | _UniffiConverterString.read(buf), 1048 | ) 1049 | raise InternalError("Raw enum value doesn't match any cases") 1050 | 1051 | @staticmethod 1052 | def write(value, buf): 1053 | if isinstance(value, CacheError.HandleFailed): 1054 | buf.write_i32(1) 1055 | 1056 | 1057 | 1058 | class _UniffiConverterOptionalSequenceUInt8(_UniffiConverterRustBuffer): 1059 | @classmethod 1060 | def write(cls, value, buf): 1061 | if value is None: 1062 | buf.write_u8(0) 1063 | return 1064 | 1065 | buf.write_u8(1) 1066 | _UniffiConverterSequenceUInt8.write(value, buf) 1067 | 1068 | @classmethod 1069 | def read(cls, buf): 1070 | flag = buf.read_u8() 1071 | if flag == 0: 1072 | return None 1073 | elif flag == 1: 1074 | return _UniffiConverterSequenceUInt8.read(buf) 1075 | else: 1076 | raise InternalError("Unexpected flag byte for optional type") 1077 | 1078 | 1079 | 1080 | class _UniffiConverterSequenceUInt8(_UniffiConverterRustBuffer): 1081 | @classmethod 1082 | def write(cls, value, buf): 1083 | items = len(value) 1084 | buf.write_i32(items) 1085 | for item in value: 1086 | _UniffiConverterUInt8.write(item, buf) 1087 | 1088 | @classmethod 1089 | def read(cls, buf): 1090 | count = buf.read_i32() 1091 | if count < 0: 1092 | raise InternalError("Unexpected negative sequence length") 1093 | 1094 | return [ 1095 | _UniffiConverterUInt8.read(buf) for i in range(count) 1096 | ] 1097 | 1098 | def init_serial(serial: "str"): 1099 | 1100 | _rust_call_with_error(_UniffiConverterTypeCacheError,_UniffiLib.uniffi_apple_cache_fn_func_init_serial, 1101 | _UniffiConverterString.lower(serial)) 1102 | 1103 | 1104 | __all__ = [ 1105 | "InternalError", 1106 | "CacheError", 1107 | "CacheResult", 1108 | "init_serial", 1109 | "CacheApi", 1110 | ] 1111 | 1112 | -------------------------------------------------------------------------------- /bindings/python/register.py: -------------------------------------------------------------------------------- 1 | import toml 2 | import json 3 | import base64 4 | import requests 5 | import apple_cache 6 | 7 | # Load and parse the TOML file 8 | with open('mac.toml', 'r') as toml_file: 9 | mac_data = toml.load(toml_file) 10 | 11 | # Convert to a JSON string 12 | json_data = json.dumps(mac_data) 13 | 14 | # Initialize the serial with the JSON data 15 | apple_cache.init_serial(json_data) 16 | 17 | # Load the JSON template from 'cache.json' file 18 | with open('cache.json', 'r') as json_file: 19 | template = json.load(json_file) # This now represents the JSON template 20 | 21 | # Create a new CacheApi instance 22 | cache = apple_cache.CacheApi() 23 | 24 | # Call the create method and encode the response 25 | res = cache.create(None) 26 | encoded_res = base64.b64encode(bytes(res.data)).decode('utf-8') 27 | print(f"+ res: {res.ctx}, {encoded_res}") 28 | 29 | # Setup headers for the HTTP request 30 | headers = { 31 | 'User-Agent': 'AssetCache/243 CFNetwork/1111 Darwin/19.0.0 (x86_64)', 32 | 'X-Protocol-Version': '3' 33 | } 34 | 35 | # Create a session to manage cookies and requests 36 | session = requests.Session() 37 | session.headers.update(headers) 38 | 39 | # Disable SSL certificate verification (not recommended for production) 40 | session.verify = False 41 | 42 | # Send request to create a new session 43 | resp = session.post("https://lcdn-registration.apple.com/lcdn/session", data=encoded_res) 44 | 45 | # Check if the LCDN-Session cookie was successfully retrieved 46 | lcdnsession_cookie = resp.cookies.get('LCDN-Session') 47 | if not lcdnsession_cookie: 48 | raise Exception("LCDN-Session cookie not found.") 49 | 50 | print(f"+ LCDN: {lcdnsession_cookie}") 51 | 52 | # Obtain the response text, removing quotes and replacing escaped equals 53 | data = resp.text.strip('"').replace("\\u003d", "=") 54 | 55 | print(f"Got {data}") 56 | 57 | # Decode the data from base64 58 | decoded_data = base64.b64decode(data) 59 | 60 | # Use the obtained data 61 | cache.obtain(res.ctx, list(decoded_data)) 62 | 63 | # Use the LCDN-Session cookie to update the template 64 | template['session-token'] = lcdnsession_cookie 65 | data_to_register = json.dumps(template) 66 | 67 | print(f"+ Send {data_to_register}") 68 | 69 | # Sign the updated data 70 | signed_data = cache.sign(res.ctx, list(data_to_register.encode('utf-8'))) 71 | 72 | # Encode the signed data 73 | signed_data_encoded = base64.b64encode(bytes(signed_data)).decode('utf-8') 74 | print(f"+ Sign: {signed_data_encoded}") 75 | 76 | # Send the registration request 77 | register_resp = session.post("https://lcdn-registration.apple.com/lcdn/register", data=signed_data_encoded) 78 | 79 | # Check the registration response for errors 80 | if register_resp.status_code != 200: 81 | raise Exception(f"Registration failed with status code {register_resp.status_code}: {register_resp.text}") 82 | 83 | # Print the registration response 84 | print(f"+ Register: {register_resp.text}") 85 | -------------------------------------------------------------------------------- /blob/AssetCache: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:7848dd203cf27997bbe8bf442f17a8a1ca09d4a5de1c6f8c5a9f9186268aedaa 3 | size 3999248 4 | -------------------------------------------------------------------------------- /blob/AssetCache~.x64: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:5e5e2c1112a3f5479e572206c8bb0a65b317665ce7c91ef6865333fd2ffdcf07 3 | size 2056384 4 | -------------------------------------------------------------------------------- /blob/cert.cer: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:1b172b7411b63a03c6e220c11a5b7c6d08da91a418b59e5b2794aac0ec6ee4da 3 | size 2385 4 | -------------------------------------------------------------------------------- /blob/reloc.bin: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:9e0e7258a75a705decb2683636f09270f02cc8e3046acd8dbb5bb70990153f18 3 | size 79848 4 | -------------------------------------------------------------------------------- /blob/reloc.txt: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:217df9f166e42dd93bea902adef7b0c2121190e1d5f62f7c148fedaa6832f3da 3 | size 159688 4 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | cargo build --release --features=rel -------------------------------------------------------------------------------- /cache.json: -------------------------------------------------------------------------------- 1 | { 2 | "push-token": "45Zh0sGUcZnNiNbhc2bX0F4AS1lMLSbLygyRh2XMmYU=", 3 | "ranked-peers": true, 4 | "details": { 5 | "capabilities": { 6 | "ur": true, 7 | "sc": true, 8 | "pc": true, 9 | "im": true, 10 | "ns": true, 11 | "query-parameters": true 12 | }, 13 | "cache-size": 199000000000, 14 | "ac-power": false, 15 | "is-portable": true, 16 | "local-network": [ 17 | { 18 | "speed": 195, 19 | "wired": false 20 | } 21 | ] 22 | }, 23 | "local-ranges-only": true, 24 | "local-ranges":[ 25 | { 26 | "first": "192.168.0.0", 27 | "last": "192.168.255.255" 28 | } 29 | ], 30 | "cache-software": [ 31 | { 32 | "type": "cache", 33 | "name": "Caching Server", 34 | "version": "244" 35 | }, 36 | { 37 | "build": "21E258", 38 | "type": "system", 39 | "name": "macOS", 40 | "version": "12.3.1" 41 | } 42 | ], 43 | "guid": "B8361E6D-4D72-40F2-9402-2716ED1C9481", 44 | "local-addresses": [ 45 | { 46 | "address": "192.168.8.7", 47 | "netmask": "255.255.255.0", 48 | "port": "52098" 49 | } 50 | ] 51 | } -------------------------------------------------------------------------------- /cast_tool/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /cast_tool/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cast_tool" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | anyhow = "1.0" 10 | serde = { version = "1.0", features = ["derive"] } 11 | bincode = { git = "https://github.com/bincode-org/bincode.git" } -------------------------------------------------------------------------------- /cast_tool/src/main.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use bincode::config; 3 | use std::fs::File; 4 | use std::io::BufRead; 5 | use std::{fs, io}; 6 | use std::path::Path; 7 | 8 | fn read_lines

(filename: P) -> io::Result>> 9 | where P: AsRef, { 10 | let file = File::open(filename)?; 11 | Ok(io::BufReader::new(file).lines()) 12 | } 13 | 14 | fn main() -> Result<()>{ 15 | let mut values: Vec = Vec::new(); 16 | if let Ok(lines) = read_lines("../blob/reloc.txt") { 17 | // Consumes the iterator, returns an (Optional) String 18 | for line in lines { 19 | if let Ok(value) = line { 20 | let value = value.trim(); 21 | let value = value.trim_start_matches("0x"); 22 | let a: u64 = u64::from_str_radix(value, 16)?; 23 | values.push(a as usize); 24 | } 25 | } 26 | } 27 | let config = config::standard(); 28 | let encoded: Vec = bincode::encode_to_vec(&values, config)?; 29 | 30 | fs::write("../blob/reloc.bin", encoded)?; 31 | Ok(()) 32 | } -------------------------------------------------------------------------------- /mac.toml: -------------------------------------------------------------------------------- 1 | # sysctl -n kern.osversion 2 | osversion = "22A400" 3 | # sysctl -n kern.osrevision 4 | osrevision = 199506 5 | # From Board ID or ioreg -d2 -c IOPlatformExpertDevice | awk -F\" '/board-id/{ print $(NF-1) }' 6 | board_id = "VMware7,1" 7 | # From Model 8 | product_name = "C246-WU4-CF" 9 | 10 | # ioreg -l -p IODeviceTree | grep [system or boot]-uuid 11 | boot_uuid = "309F9AA3-582D-404C-9D5D-98D1872753F4" 12 | # From Serial Number 13 | serial_number = "VMWPArEagx4F" 14 | # From Hardware UUID 15 | uuid = "564DDF61-046F-3563-337D-A8DD7EC93B39" 16 | 17 | # serial 18 | Gq3489ugfi = "20E7842CF797F2CEF7D6FBC3A3BD9555F0" 19 | Fyp98tpgj = "14431143163D8EE5144E952AE793416FA7" 20 | kbjfrfpoJU = "A028951F5F266FCADD4C5161C11E3F907B" 21 | oycqAZloTNDm = "89202B04C7EC3E704E490803E8D652412D" 22 | abKPld1EcMni = "2BDC80C930ECAF71A29612DF217C332385" 23 | 24 | # ifconfig en0 | awk '/ether/{ gsub(":",""); print $2 }' 25 | mac_address = "bcd07437730f" 26 | 27 | # From ROM & MLB 28 | # nvram 4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:ROM | awk '{ print $NF }' 29 | rom = "564DDF61046F" 30 | # nvram 4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:MLB | awk '{ print $NF }' 31 | mlb = "NWMzfajdfsk7OQ..." -------------------------------------------------------------------------------- /serial: -------------------------------------------------------------------------------- 1 | Xserialnumber -------------------------------------------------------------------------------- /vmp/VMProtectLicense.ini: -------------------------------------------------------------------------------- 1 | [TestLicense] 2 | AcceptedSerialNumber=Xserialnumber -------------------------------------------------------------------------------- /vmp/libVMProtectSDK64.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deadash/apple_cache/93274486161e0fc9e5cecb23ebf4f64bb0404e72/vmp/libVMProtectSDK64.so -------------------------------------------------------------------------------- /vmp_cmd: -------------------------------------------------------------------------------- 1 | RUST_LOG=trace LD_LIBRARY_PATH=vmp target/release/api --------------------------------------------------------------------------------