format code
This commit is contained in:
@ -92,8 +92,8 @@ const (
|
||||
LC_VERSION_MIN_TVOS uint32 = 0x2F
|
||||
LC_VERSION_MIN_WATCHOS uint32 = 0x30
|
||||
LC_BUILD_VERSION uint32 = 0x32
|
||||
LC_DYLD_EXPORTS_TRIE uint32 = 0x33 | 0x80000000
|
||||
LC_DYLD_CHAINED_FIXUPS uint32 = 0x34 | 0x80000000
|
||||
LC_DYLD_EXPORTS_TRIE uint32 = 0x33 | 0x80000000
|
||||
LC_DYLD_CHAINED_FIXUPS uint32 = 0x34 | 0x80000000
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -1,8 +1,8 @@
|
||||
/// Contains the declaration of FatHeader and FatArch
|
||||
/// These structs are always written using Big-Endian,
|
||||
/// as documented in the mach-o/fat.h
|
||||
/// This file also has a CreateFat function to generate
|
||||
/// Fat file from a list of MachoContext
|
||||
// / Contains the declaration of FatHeader and FatArch
|
||||
// / These structs are always written using Big-Endian,
|
||||
// / as documented in the mach-o/fat.h
|
||||
// / This file also has a CreateFat function to generate
|
||||
// / Fat file from a list of MachoContext
|
||||
package fat
|
||||
|
||||
import (
|
||||
@ -16,8 +16,8 @@ import (
|
||||
macho "ios-wrapper/pkg/ios/macho"
|
||||
)
|
||||
|
||||
/// Get the alignment for the Mach-O in Fat binary
|
||||
/// The returned value is the multiplier of 2
|
||||
// / Get the alignment for the Mach-O in Fat binary
|
||||
// / The returned value is the multiplier of 2
|
||||
func GetAlignment(h *macho.Header) uint32 {
|
||||
switch h.Cputype() {
|
||||
case CPU_TYPE_ARM, CPU_TYPE_ARM64:
|
||||
@ -46,17 +46,17 @@ func MachosToFatArchs(machos []*macho.MachoContext) []*FatArch {
|
||||
return fa
|
||||
}
|
||||
|
||||
/// Create a Fat binary from MachoContext
|
||||
/// Convert MachoContext to FatArch
|
||||
/// Calculate the alignment, now using basic calculation
|
||||
/// because iOS always has valid archs ARM
|
||||
///
|
||||
/// Sort the Fat arch as per the cctools/lipo
|
||||
/// Calculate the offset with each Mach-O
|
||||
///
|
||||
/// Write the FatHeader
|
||||
/// Write the FatArchs
|
||||
/// Write the Mach-Os
|
||||
// / Create a Fat binary from MachoContext
|
||||
// / Convert MachoContext to FatArch
|
||||
// / Calculate the alignment, now using basic calculation
|
||||
// / because iOS always has valid archs ARM
|
||||
// /
|
||||
// / Sort the Fat arch as per the cctools/lipo
|
||||
// / Calculate the offset with each Mach-O
|
||||
// /
|
||||
// / Write the FatHeader
|
||||
// / Write the FatArchs
|
||||
// / Write the Mach-Os
|
||||
func CreateFat(machos []*macho.MachoContext, outfilename string) error {
|
||||
archs := MachosToFatArchs(machos)
|
||||
sort.SliceStable(archs, func(i, j int) bool {
|
||||
@ -139,9 +139,9 @@ func (fw *fatWriter) WriteFatArchs(w io.Writer, archs []*FatArch) {
|
||||
}
|
||||
}
|
||||
|
||||
/// for each fat arch sorted, we locate the MachoContext and
|
||||
/// use it to Write to the buffer
|
||||
/// locating the macho by its cputype and cpusubtype
|
||||
// / for each fat arch sorted, we locate the MachoContext and
|
||||
// / use it to Write to the buffer
|
||||
// / locating the macho by its cputype and cpusubtype
|
||||
func (fw *fatWriter) WriteMachos(
|
||||
w io.WriteSeeker,
|
||||
archs []*FatArch,
|
||||
|
@ -46,41 +46,41 @@ func (sym *ImportSymbol) Stub() uint64 {
|
||||
}
|
||||
|
||||
func (mc *MachoContext) CollectLazyBindSymbols() []*ImportSymbol {
|
||||
if mc.dyldinfo == nil {
|
||||
return mc.CollectLazyBindSymbolsModern()
|
||||
} else {
|
||||
return mc.CollectLazyBindSymbolsLegacy()
|
||||
}
|
||||
if mc.dyldinfo == nil {
|
||||
return mc.CollectLazyBindSymbolsModern()
|
||||
} else {
|
||||
return mc.CollectLazyBindSymbolsLegacy()
|
||||
}
|
||||
}
|
||||
|
||||
// New convention using LC_DYLD_CHAINED_FIXUPS
|
||||
func (mc *MachoContext) CollectLazyBindSymbolsModern() []*ImportSymbol {
|
||||
var buf []byte
|
||||
for _, cmd := range mc.Linkedits() {
|
||||
if (cmd.Cmd() != LC_DYLD_CHAINED_FIXUPS) {
|
||||
continue
|
||||
}
|
||||
var buf []byte
|
||||
for _, cmd := range mc.Linkedits() {
|
||||
if cmd.Cmd() != LC_DYLD_CHAINED_FIXUPS {
|
||||
continue
|
||||
}
|
||||
|
||||
count_offset := int64(cmd.Dataoff()) + 16
|
||||
mc.file.WriteAt([]byte{0, 0, 0, 0}, count_offset)
|
||||
count_offset := int64(cmd.Dataoff()) + 16
|
||||
mc.file.WriteAt([]byte{0, 0, 0, 0}, count_offset)
|
||||
|
||||
symbol_offset := int64(0x4000)
|
||||
mc.file.WriteAt([]byte{0, 0, 0, 0, 0, 0, 0, 0}, symbol_offset)
|
||||
symbol_offset := int64(0x4000)
|
||||
mc.file.WriteAt([]byte{0, 0, 0, 0, 0, 0, 0, 0}, symbol_offset)
|
||||
|
||||
buf = mc.buf[cmd.Dataoff():cmd.Dataoff() + cmd.Datasize()]
|
||||
break
|
||||
}
|
||||
buf = mc.buf[cmd.Dataoff() : cmd.Dataoff()+cmd.Datasize()]
|
||||
break
|
||||
}
|
||||
|
||||
r := bytes.NewReader(buf)
|
||||
rr := bufio.NewReader(r)
|
||||
|
||||
var fixups_version int32
|
||||
var starts_offset int32
|
||||
var imports_offset int32
|
||||
var symbols_offset int32
|
||||
var imports_count int32
|
||||
var imports_format int32
|
||||
var symbols_format int32
|
||||
var fixups_version int32
|
||||
var starts_offset int32
|
||||
var imports_offset int32
|
||||
var symbols_offset int32
|
||||
var imports_count int32
|
||||
var imports_format int32
|
||||
var symbols_format int32
|
||||
binary.Read(rr, mc.byteorder, &fixups_version)
|
||||
binary.Read(rr, mc.byteorder, &starts_offset)
|
||||
binary.Read(rr, mc.byteorder, &imports_offset)
|
||||
@ -88,36 +88,36 @@ func (mc *MachoContext) CollectLazyBindSymbolsModern() []*ImportSymbol {
|
||||
binary.Read(rr, mc.byteorder, &imports_count)
|
||||
binary.Read(rr, mc.byteorder, &imports_format)
|
||||
binary.Read(rr, mc.byteorder, &symbols_format)
|
||||
fmt.Printf(
|
||||
"HMMGE %x %x\n",
|
||||
imports_offset,
|
||||
imports_count,
|
||||
)
|
||||
fmt.Printf(
|
||||
"HMMGE %x %x\n",
|
||||
imports_offset,
|
||||
imports_count,
|
||||
)
|
||||
|
||||
return []*ImportSymbol{}
|
||||
return []*ImportSymbol{}
|
||||
}
|
||||
|
||||
// Old convention using LC_DYLD_INFO_ONLY section and bytecode runner
|
||||
func (mc *MachoContext) CollectLazyBindSymbolsLegacy() []*ImportSymbol {
|
||||
start := mc.dyldinfo.lazy_bind_off
|
||||
size := mc.dyldinfo.lazy_bind_size
|
||||
size := mc.dyldinfo.lazy_bind_size
|
||||
end := start + size
|
||||
|
||||
if size == 0 {
|
||||
return []*ImportSymbol{}
|
||||
}
|
||||
|
||||
// clear this whole section to 0x00 BIND_OPCODE_DONE
|
||||
dummy := []byte{
|
||||
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
|
||||
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
|
||||
}
|
||||
// make LINK EDIT section writable
|
||||
// mc.file.WriteAt([]byte{0x03}, int64(0x3f8))
|
||||
// set number of symbols to 0
|
||||
mc.file.WriteAt([]byte{0, 0, 0, 0}, int64(0x444))
|
||||
mc.file.WriteAt([]byte{0, 0, 0, 0}, int64(0x44c))
|
||||
mc.file.WriteAt([]byte{0, 0, 0, 0}, int64(0x48c))
|
||||
// clear this whole section to 0x00 BIND_OPCODE_DONE
|
||||
dummy := []byte{
|
||||
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
|
||||
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
|
||||
}
|
||||
// make LINK EDIT section writable
|
||||
// mc.file.WriteAt([]byte{0x03}, int64(0x3f8))
|
||||
// set number of symbols to 0
|
||||
mc.file.WriteAt([]byte{0, 0, 0, 0}, int64(0x444))
|
||||
mc.file.WriteAt([]byte{0, 0, 0, 0}, int64(0x44c))
|
||||
mc.file.WriteAt([]byte{0, 0, 0, 0}, int64(0x48c))
|
||||
mc.file.WriteAt(dummy, int64(start))
|
||||
|
||||
buf := bytes.NewBuffer(mc.buf[start:end])
|
||||
|
@ -40,12 +40,13 @@ func rewriteLoadcommandsWithoutCodesignature(mc *MachoContext) {
|
||||
// CODE_SIGNATURE load commands points to the codesign data offset and size.
|
||||
// __LINKEDIT section points to data offset and size.
|
||||
// We have:
|
||||
// linkedit = (section*) LC_SEGMENT.section[0] // name="__LINKEDIT"
|
||||
// codesign = (linkedit_data_command*) LC_CODE_SIGNATURE
|
||||
// BinarySize = { f.seek(0, SEEKEND); return f.tell() }
|
||||
//
|
||||
// linkedit->fileoff + linkedit->filesize == codesign->dataOff + codesign->dataSize
|
||||
// linkedit->fileoff + linkedit->filesize == BinarySize
|
||||
// linkedit = (section*) LC_SEGMENT.section[0] // name="__LINKEDIT"
|
||||
// codesign = (linkedit_data_command*) LC_CODE_SIGNATURE
|
||||
// BinarySize = { f.seek(0, SEEKEND); return f.tell() }
|
||||
//
|
||||
// linkedit->fileoff + linkedit->filesize == codesign->dataOff + codesign->dataSize
|
||||
// linkedit->fileoff + linkedit->filesize == BinarySize
|
||||
//
|
||||
// To remove the codesign data, we truncate the file to remove the codesign data.
|
||||
// Then we update the linkedit->filesize to linkedit->filesize - codesign->dataSize
|
||||
|
@ -456,7 +456,7 @@ func (lcmd *Symtab) Cmdsize() uint32 {
|
||||
}
|
||||
|
||||
func (lcmd *Symtab) Cmdname() string {
|
||||
return fmt.Sprintf("%s symoff:0x%x nsyms:%d stroff:0x%x strsize:0x%x",
|
||||
return fmt.Sprintf("%s symoff:0x%x nsyms:%d stroff:0x%x strsize:0x%x",
|
||||
lcmd.c.Cmdname(), lcmd.symoff, lcmd.nsyms, lcmd.stroff, lcmd.strsize)
|
||||
}
|
||||
|
||||
|
@ -71,10 +71,12 @@ func (mc *MachoContext) WriteBufferTo(w io.Writer) (int, error) {
|
||||
// Parse the provided Mach-O binary from a file
|
||||
// The first 4 bytes of the file must be the MachO magic
|
||||
// That is:
|
||||
// file.Seek(0, io.SeekStart)
|
||||
// magic := make([]byte, 4)
|
||||
// file.Read(magic)
|
||||
// assert magic == []byte{macho magic bytes}
|
||||
//
|
||||
// file.Seek(0, io.SeekStart)
|
||||
// magic := make([]byte, 4)
|
||||
// file.Read(magic)
|
||||
// assert magic == []byte{macho magic bytes}
|
||||
//
|
||||
// or else, parsing error is panic
|
||||
func (mc *MachoContext) ParseFile(file *os.File, length int) error {
|
||||
file.Seek(0, io.SeekStart)
|
||||
|
@ -83,8 +83,8 @@ func (mc *MachoContext) DylibExisted(name string) bool {
|
||||
// simple check
|
||||
// Advanced check requires expansion of @rpath
|
||||
for _, dylib := range mc.dylibs {
|
||||
dylib_ := bytes.Trim(dylib.name, "\x00")
|
||||
match := bytes.Compare(dylib_, []byte(name)) == 0
|
||||
dylib_ := bytes.Trim(dylib.name, "\x00")
|
||||
match := bytes.Compare(dylib_, []byte(name)) == 0
|
||||
log.WithFields(log.Fields{
|
||||
"left": dylib_,
|
||||
"right": []byte(name),
|
||||
@ -101,8 +101,8 @@ func (mc *MachoContext) RPathExisted(path string) bool {
|
||||
// simple check
|
||||
// Advanced check requires expansion of @rpath
|
||||
for _, rpath := range mc.rpaths {
|
||||
rpath_ := bytes.Trim(rpath.path, "\x00")
|
||||
match := bytes.Compare(rpath_, []byte(path)) == 0
|
||||
rpath_ := bytes.Trim(rpath.path, "\x00")
|
||||
match := bytes.Compare(rpath_, []byte(path)) == 0
|
||||
log.WithFields(log.Fields{
|
||||
"left": rpath_,
|
||||
"right": []byte(path),
|
||||
@ -138,7 +138,7 @@ func (mc *MachoContext) FindSegment(name string) Segment {
|
||||
}
|
||||
|
||||
func (mc *MachoContext) Cut(offset uint64, size uint64) []byte {
|
||||
return mc.buf[offset : offset + size];
|
||||
return mc.buf[offset : offset+size]
|
||||
}
|
||||
|
||||
// INIT POINTER
|
||||
|
Reference in New Issue
Block a user