package fat import ( "bufio" "bytes" "encoding/binary" "errors" "os" . "ios-wrapper/pkg/ios" "ios-wrapper/pkg/ios/macho" ) type FatHeader struct { Magic uint32 Nfat_arch uint32 } func (h *FatHeader) Serialize() []byte { buf := new(bytes.Buffer) binary.Write(buf, binary.BigEndian, h.Magic) binary.Write(buf, binary.BigEndian, h.Nfat_arch) return buf.Bytes() } type FatArch struct { Cputype uint32 Cpusubtype uint32 Offset uint32 Size uint32 Align uint32 } func (arch *FatArch) Serialize() []byte { buf := new(bytes.Buffer) binary.Write(buf, binary.BigEndian, arch.Cputype) binary.Write(buf, binary.BigEndian, arch.Cpusubtype) binary.Write(buf, binary.BigEndian, arch.Offset) binary.Write(buf, binary.BigEndian, arch.Size) binary.Write(buf, binary.BigEndian, arch.Align) return buf.Bytes() } // don't know when to use // it seems that only use if the size of any file is > 4GB // else just use FatArch type FatArch64 struct { Cputype uint32 Cpusubtype uint32 Offset uint64 Size uint64 Align uint32 } type FatContext struct { fatArch []*FatArch } func (fc *FatContext) ParseFile(file *os.File) { r := bufio.NewReader(file) { // read magic to define byteorder and pointersize var magic uint32 magic_buf := make([]byte, 4) r.Read(magic_buf) magic_r := bytes.NewReader(magic_buf) binary.Read(magic_r, binary.BigEndian, &magic) if magic != MagicFat { return } } var nfat_arch uint32 binary.Read(r, binary.BigEndian, &nfat_arch) for i := uint32(0); i < nfat_arch; i++ { var fat_arch FatArch binary.Read(r, binary.BigEndian, &fat_arch.Cputype) binary.Read(r, binary.BigEndian, &fat_arch.Cpusubtype) binary.Read(r, binary.BigEndian, &fat_arch.Offset) binary.Read(r, binary.BigEndian, &fat_arch.Size) binary.Read(r, binary.BigEndian, &fat_arch.Align) fc.fatArch = append(fc.fatArch, &fat_arch) } } func (fc *FatContext) Machos() []*FatArch { return fc.fatArch } func FatSplit(path string) ([]string, error) { return CreateMachosFromFat(path) } // Parse files into Mach-O, calculate fat_arch and join // into a Fat binary // @paths: paths to Mach-O binaries // @out: output Fat file path // returns success? func FatJoin(paths []string, out string) error { machos, err := macho.MachosFromFiles(paths) if err != nil { return err } if macho.CheckDuplicateArch(machos) { return errors.New("Duplicate Arch") } return CreateFat(machos, out) }