111 lines
2.4 KiB
Go
111 lines
2.4 KiB
Go
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)
|
|
}
|