feat: app
This commit is contained in:
@@ -183,65 +183,32 @@ class AiWalletPackageService
|
||||
|
||||
private function addLoadDylib(string $binaryPath, string $dylibPath, string $insertBefore): void
|
||||
{
|
||||
$data = file_get_contents($binaryPath);
|
||||
$origSize = strlen($data);
|
||||
|
||||
// Parse Mach-O 64-bit header
|
||||
$magic = unpack('V', substr($data, 0, 4))[1];
|
||||
if ($magic !== 0xFEEDFACF) throw new RuntimeException('Not a Mach-O 64-bit binary');
|
||||
|
||||
$ncmds = unpack('V', substr($data, 16, 4))[1];
|
||||
$sizeofcmds = unpack('V', substr($data, 20, 4))[1];
|
||||
|
||||
// Find the LC_LOAD_DYLIB for libutils to insert before it
|
||||
$offset = 32;
|
||||
$insertOffset = 32 + $sizeofcmds; // Default: append at end
|
||||
$libutilsOffset = -1;
|
||||
|
||||
for ($i = 0; $i < $ncmds; $i++) {
|
||||
$cmd = unpack('V', substr($data, $offset, 4))[1];
|
||||
$cmdsize = unpack('V', substr($data, $offset + 4, 4))[1];
|
||||
|
||||
if ($cmd === 0x0C) { // LC_LOAD_DYLIB
|
||||
$nameOffset = unpack('V', substr($data, $offset + 8, 4))[1];
|
||||
$name = substr($data, $offset + $nameOffset, strpos(substr($data, $offset + $nameOffset), "\0"));
|
||||
if (str_contains($name, 'libutils')) {
|
||||
$libutilsOffset = $offset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$offset += $cmdsize;
|
||||
// Use Python script for Mach-O editing — PHP binary manipulation
|
||||
// corrupts the binary by inserting bytes (shifts code signature blob).
|
||||
// The Python script uses existing free space in the load command table,
|
||||
// preserving the file size and not breaking the signature.
|
||||
$scriptPath = base_path('bin/add_dylib.py');
|
||||
|
||||
if (!file_exists($scriptPath)) {
|
||||
throw new RuntimeException('add_dylib.py not found at '.$scriptPath);
|
||||
}
|
||||
|
||||
// Insert before libutils if found, otherwise append
|
||||
if ($libutilsOffset >= 0) {
|
||||
$insertOffset = $libutilsOffset;
|
||||
$cmd = sprintf(
|
||||
'python3 %s %s %s 2>&1',
|
||||
escapeshellarg($scriptPath),
|
||||
escapeshellarg($binaryPath),
|
||||
escapeshellarg($dylibPath)
|
||||
);
|
||||
|
||||
$output = [];
|
||||
$exitCode = 0;
|
||||
exec($cmd, $output, $exitCode);
|
||||
|
||||
if ($exitCode !== 0) {
|
||||
throw new RuntimeException('add_dylib.py failed: '.implode("\n", $output));
|
||||
}
|
||||
|
||||
// Create LC_LOAD_DYLIB command
|
||||
$name = $dylibPath."\0";
|
||||
$nameOffset = 24; // sizeof(load_command) + 3 * sizeof(uint32) + padding
|
||||
$cmdsize = $nameOffset + strlen($name);
|
||||
$cmdsize = ($cmdsize + 7) & ~7; // Align to 8 bytes
|
||||
$name = str_pad($name, $cmdsize - $nameOffset, "\0");
|
||||
|
||||
$lc = pack('VVVVVV',
|
||||
0x0C, // cmd = LC_LOAD_DYLIB
|
||||
$cmdsize, // cmdsize
|
||||
$nameOffset, // dylib.name.offset
|
||||
1, // dylib.timestamp
|
||||
0, // dylib.current_version
|
||||
0 // dylib.compatibility_version
|
||||
).$name;
|
||||
|
||||
// Insert the load command
|
||||
$data = substr($data, 0, $insertOffset).$lc.substr($data, $insertOffset);
|
||||
|
||||
// Update ncmds and sizeofcmds in header
|
||||
$data = substr_replace($data, pack('V', $ncmds + 1), 16, 4);
|
||||
$data = substr_replace($data, pack('V', $sizeofcmds + $cmdsize), 20, 4);
|
||||
|
||||
file_put_contents($binaryPath, $data);
|
||||
|
||||
Log::info('AiWalletPackageService: add_dylib.py output', ['output' => $output]);
|
||||
}
|
||||
|
||||
private function findAppDir(string $workDir): ?string
|
||||
|
||||
Reference in New Issue
Block a user