Apple's announcement of macOS Big Sur had meant the release of the developer beta. In an attempt to create the appbundle from Apple's softwarecatalog
, I attempted to study the contents of InstallAssistant.pkg
. In the process, I found pbzx
files in the payloadv2
directory that mimic Format 3.0 used by iOS for its' OTA updates and the study of that format by Johnathan Levin and attempted to use his ota
tool to extract it (which uses the following struct)
#pragma pack(1)
struct entry
{
unsigned int usually_0x210_or_0x110;
unsigned short usually_0x00_00; //_00_00;
unsigned int fileSize;
unsigned short whatever;
unsigned long long timestamp_likely;
unsigned short _usually_0x20;
unsigned short nameLen;
unsigned short uid;
unsigned short gid;
unsigned short perms;
char name[0];
// Followed by file contents
};
#pragma pack()
There was no avail with ota
so I resorted to use a slightly modified (in terms of memory improvements) version of his pbzx
tool to extract the stream, to success using the bash command given below in the payloadv2
directory
rm *.ecc && find *.??? -exec bash -c "./pbzx {} >> {}.unpbzx" \; && mkdir unpbzx && mv *.unpbzx unpbzx/
As a result I now have a directory full of .unpbzx
files. Attempting to run ota
(with pbzx
support removed to eliminate the possibility of potential bugs there) on payload.000.unpbzx
results in a Segmentation Fault, gdb
returns
Corrupt entry (0x31414159 at pos 30@0x10100001e).. skipping
Thread 2 received signal SIGSEGV, Segmentation fault.
0x00000001000031b4 in processFile (FileName=0x7ffeefbff74e "/Volumes/[redacted]/pbzx/payload.000.unpbzx") at ota.c:423
423 while (ent->usually_0x210_or_0x110 != 0x210 && ent->usually_0x210_or_0x110 != 0x110)
Running it with alternative tools like ota2tar
(with pbzx
extraction code removed) and forks of ota
like iOS-Utilities
gave similar errors (out-of-bounds memory errors, etc.)
It appears that somehow this unpbzx
file has a different header structure to the description of Format 3.0 on the iPhone Wiki
Opening payload.000.unpbzx
with Hex Fiend shows that the file format appears to be differing from the struct given above (singular entry highlighted)
Files seem to be listed with some form of delimiter YAA1
in the beginning. Isolating individual entries gives results similar to the image given below (file name highlighted)
My knowledge of reverse engineering is admittedly limited so the best I could do is some psudocode about what the struct may look like
struct entry
{
uint8_t header; // 59414131 (0xYAA1)
uint32_t description; // 69005459 50314450 41545030 (iTYP1DPATP)
uint8_t padding; // 00
// fileNameLen undefined
char[fileNameLen] filename; // System/Library/Perl/Extras/5.28/Net/LDAP/Control
uint8_t uid; // 55494431 (or 0xUID1)
uint8_t padding2; // 00
uint8_t descr_end; // 474944 31004D4F 4432ED01 464C4734 00000800 4D544D54
// (descr_end includes GID, MOD and FLG values)
// file_contents
}
As a last ditch attempt, I ran payload.000.unpbzx
through 7zip and it identifies the file as a gzip
stream
Path = /Volumes/[redacted]/pbzx/payload.000.unpbzx
Type = gzip
ERRORS:
There are data after the end of archive
Offset = 5636247
Physical Size = 98
Tail Size = 12327687
Headers Size = 10
Streams = 1
ERROR: There is some data after the end of the payload data : payload.000
Sub items Errors: 1
Archives with Errors: 1
Open Errors: 1
But gunzip
does not recognize the format.
At this point, what would be the best way of interpreting this new archival structure and how do I proceed forward?
(Note: Hex Fiend displays 000.pbzx
because I did actually name the files with the .pbzx
extension even though that naming was incorrect and had modified it to .unpbzx
for clarity in this question)