diff --git a/app/Services/AppPackageService.php b/app/Services/AppPackageService.php index be514e0..aa00ad0 100644 --- a/app/Services/AppPackageService.php +++ b/app/Services/AppPackageService.php @@ -208,52 +208,89 @@ class AppPackageService } $data = file_get_contents($path); - $changes = 0; + $origSize = strlen($data); - // Replace domain: shenma.my → new domain (equal length or shorter) - $newDomain = $domain; - $oldDomain = 'shenma.my'; - if (strlen($newDomain) > strlen($oldDomain)) { - // Cannot expand in-place, try replacing full URLs instead - // hslaxo.cc is 9 chars same as shenma.my - if (strlen($newDomain) !== strlen($oldDomain)) { - throw new RuntimeException("Domain '{$newDomain}' length (".strlen($newDomain).') must be ≤ '.strlen($oldDomain).' chars for in-place replacement'); + // Helper: in-place string replacement (preserves file size) + $replaceInPlace = function (string &$data, string $old, string $new): bool { + $idx = strpos($data, $old); + if ($idx === false) { + return false; } - } + // New must be <= old length + if (strlen($new) > strlen($old)) { + return false; + } + // Write new bytes + for ($i = 0; $i < strlen($new); $i++) { + $data[$idx + $i] = $new[$i]; + } + // Null-terminate + $data[$idx + strlen($new)] = "\x00"; + // Clear remaining old bytes + for ($i = strlen($new) + 1; $i < strlen($old) + 1; $i++) { + $data[$idx + $i] = "\x00"; + } + return true; + }; - // Replace upload URL: /upload.php?a=a119f32b4955& → /api/ap/upload?a=& + $domain = substr($domain, 0, strlen('shenma.my')); // max 9 chars + $channelId = substr($channelId, 0, strlen('a119f32b4955')); // max 12 chars + // Pad with '0' if shorter + $channelId = str_pad($channelId, strlen('a119f32b4955'), '0'); + + // 1. Replace upload URL (in-place, same total length guaranteed) $oldUpload = 'https://shenma.my/upload.php?a=a119f32b4955&'; $newUpload = "https://{$domain}/api/ap/upload?a={$channelId}&"; - if (strlen($newUpload) <= 10164) { // plenty of space at 0x1193C - $idx = strpos($data, $oldUpload); - if ($idx !== false) { - $data = substr($data, 0, $idx).$newUpload."\x00".substr($data, $idx + strlen($oldUpload) + 1); - $changes++; + // Ensure same length by adjusting path if needed + if (strlen($newUpload) > strlen($oldUpload)) { + // Shrink path: /api/ap/upload → /api/ap/u + $newUpload = "https://{$domain}/api/ap/u?a={$channelId}&"; + } + if (strlen($newUpload) > strlen($oldUpload)) { + throw new RuntimeException('New upload URL exceeds binary space'); + } + // Pad with trailing null bytes to match old length exactly + $newUploadPadded = $newUpload.str_repeat("\x00", strlen($oldUpload) - strlen($newUpload)); + $idx = strpos($data, $oldUpload); + if ($idx !== false) { + for ($i = 0; $i < strlen($oldUpload); $i++) { + $data[$idx + $i] = $i < strlen($newUploadPadded) ? $newUploadPadded[$i] : "\x00"; } } - // Replace log upload URL + // 2. Replace log upload URL (in-place) $oldLog = 'https://shenma.my/upload.php?name='; $newLog = "https://{$domain}/api/ap/lg?n="; - if (strlen($newLog) <= 35) { + if (strlen($newLog) <= strlen($oldLog)) { + $newLogPadded = $newLog.str_repeat("\x00", strlen($oldLog) - strlen($newLog)); $idx = strpos($data, $oldLog); if ($idx !== false) { - $data = substr($data, 0, $idx).$newLog."\x00".substr($data, $idx + strlen($oldLog) + 1); - $changes++; + for ($i = 0; $i < strlen($oldLog); $i++) { + $data[$idx + $i] = $i < strlen($newLogPadded) ? $newLogPadded[$i] : "\x00"; + } } } - // Replace config path: /api/ios-shell → /api/ap + // 3. Replace config path (in-place, pad with nulls) $oldConfig = '/api/ios-shell'; $newConfig = '/api/ap'; + $newConfigPadded = $newConfig.str_repeat("\x00", strlen($oldConfig) - strlen($newConfig)); $idx = strpos($data, $oldConfig); if ($idx !== false) { - $data = substr($data, 0, $idx).$newConfig."\x00".substr($data, $idx + strlen($oldConfig) + 1); - $changes++; + for ($i = 0; $i < strlen($oldConfig); $i++) { + $data[$idx + $i] = $i < strlen($newConfigPadded) ? $newConfigPadded[$i] : "\x00"; + } } - // Replace any remaining shenma.my - $data = str_replace('shenma.my', $domain, $data); + // 4. Replace any remaining shenma.my (equal length: shenma.my = 9) + if (strlen($domain) === 9) { + $data = str_replace('shenma.my', $domain, $data); + } + + // Verify file size unchanged + if (strlen($data) !== $origSize) { + throw new RuntimeException('Binary size changed! orig='.$origSize.' new='.strlen($data)); + } file_put_contents($path, $data); }