Closed plk closed 2 years ago
Just wanted to confirm that this won't work due to the assumptions pp'ed binaries make about headers etc. I assume that there is no way to create universal binaries with pp?
Sorry, there's no way to create "universal" binaries. See the section "Anatomy of a Self-Contained PAR executable" in
PAR::Tutorial: you would somehow have to combine the corresponding parts of two native packed executables separately
(e.g. use lipo
for the first (execuatble) parts, create a "union" zip from the third (zip) parts), then make sure that when run
on architecture A, only the stuff for this architecture from the "union" zip is used etc.
I'm curious why our naive attempt works at all for at least one architecture. My guess is that lipo
works by concatenating the
two executables and then prepends a new MachO header that references sections in both executables (tagged with
architecture) and the MacOS loader picks the correct sections. In this scenario the pp binary the was placed last in the
resulting universal binary might actually work (since the "embedded" files are correctly found by offset from the end of the file,
same goes for the zip).
I think this is correct as in testing using lipo
, it's the last one in the universal list that seems to work. It's not that it works on ARM vs x86_64, it's just that the ARM binary was after the x86_64. I wonder if there is a way then to detect universal binaries and adjust the unpacking offsets at runtime.
I wonder if there is a way then to detect universal binaries and adjust the unpacking offsets at runtime.
There are two problems here:
Archive::Zip
: it always searches backwards from the end of the file until it finds a certain signature, then locates the zip "directory" from there. AFAIK there's no way to direct Archive::Zip
to extract a zip not in the tail position.AFAIK there's no way to direct Archive::Zip to extract a zip not in the tail position.
Correction: there might be a away, see https://metacpan.org/release/PHRED/Archive-Zip-1.68/source/examples/readScalar.pl
But then we're facing the same problem as for the "embedded" files.
I wonder if we can then detect a fat binary, if it's a fat binary, use lipo
(which should be on any MacOS I think?) to extract that arch and then run as normal? lipo
can do this by extracting the arch (given by the arch
command) to a new file - I did a quick test and this works - the pp
binary runs as normal after such an extract.
There is information in the FAT header about the offsets for the different archictectures:
You could patch something like the following into myldr/boot.c, directly before the call of extract_embedded_file
:
lipo
to extract a "lean" binary from my_prog, preferably into some file in stmpdirOpened a PR doing what was suggested - works on my previously failing tests.
Closed via #58
I created two pp binaries, one for x86_64 and one for ARM, signed them both, both work. Then combined them into a universal binary with
lipo
, resulting in new binary. This only works on ARM and the x86_64 fails with errors like this:Just wanted to confirm that this won't work due to the assumptions
pp
'ed binaries make about headers etc. I assume that there is no way to create universal binaries withpp
?