diff --git a/macho-go/pkg/ios/macho/dyld_info.go b/macho-go/pkg/ios/macho/dyld_info.go index 6365912..147bf6f 100644 --- a/macho-go/pkg/ios/macho/dyld_info.go +++ b/macho-go/pkg/ios/macho/dyld_info.go @@ -74,15 +74,9 @@ func (mc *MachoContext) findSegmentIndexAt(address uint64) int { // New convention using LC_DYLD_CHAINED_FIXUPS func (mc *MachoContext) CollectBindSymbolsModern() []*ImportSymbol { - var buf []byte - for _, cmd := range mc.Linkedits() { - if cmd.Cmd() != LC_DYLD_CHAINED_FIXUPS { - continue - } - - buf = mc.buf[cmd.Dataoff() : cmd.Dataoff()+cmd.Datasize()] - break - } + start := mc.fixups.dataoff + size := mc.fixups.datasize + buf := mc.buf[start:start+size] // all pointers used are based from this **buf** // until buf is freed, all pointers are valid diff --git a/macho-go/pkg/ios/macho/load_commands.go b/macho-go/pkg/ios/macho/load_commands.go index 0105802..da3fb5f 100644 --- a/macho-go/pkg/ios/macho/load_commands.go +++ b/macho-go/pkg/ios/macho/load_commands.go @@ -396,6 +396,39 @@ func (lcmd *DyldInfo) Deserialize(mc *MachoContext, buf []byte) { binary.Read(r, mc.byteorder, &lcmd.export_size) } +type Fixups struct { + fixups_version uint32 + starts_offset uint32 + imports_offset uint32 + symbols_offset uint32 + imports_count uint32 + imports_format uint32 + symbols_format uint32 +} + +func (lcmd *Fixups) Serialize(mc *MachoContext) []byte { + buf := new(bytes.Buffer) + binary.Write(buf, mc.byteorder, lcmd.fixups_version) + binary.Write(buf, mc.byteorder, lcmd.starts_offset) + binary.Write(buf, mc.byteorder, lcmd.imports_offset) + binary.Write(buf, mc.byteorder, lcmd.symbols_offset) + binary.Write(buf, mc.byteorder, lcmd.imports_count) + binary.Write(buf, mc.byteorder, lcmd.imports_format) + binary.Write(buf, mc.byteorder, lcmd.symbols_format) + return buf.Bytes() +} + +func (lcmd *Fixups) Deserialize(mc *MachoContext, buf []byte) { + r := bytes.NewBuffer(buf) + binary.Read(r, mc.byteorder, &lcmd.fixups_version) + binary.Read(r, mc.byteorder, &lcmd.starts_offset) + binary.Read(r, mc.byteorder, &lcmd.imports_offset) + binary.Read(r, mc.byteorder, &lcmd.symbols_offset) + binary.Read(r, mc.byteorder, &lcmd.imports_count) + binary.Read(r, mc.byteorder, &lcmd.imports_format) + binary.Read(r, mc.byteorder, &lcmd.symbols_format) +} + type LinkEdit struct { c LoadCmd dataoff uint32 @@ -481,3 +514,87 @@ func (lcmd *Symtab) Deserialize(mc *MachoContext, buf []byte) { binary.Read(r, mc.byteorder, &lcmd.stroff) binary.Read(r, mc.byteorder, &lcmd.strsize) } + +type DySymtab struct { + c LoadCmd + ilocalsym uint32 + nlocalsym uint32 + iextdefsym uint32 + nextdefsym uint32 + iundefsym uint32 + nundefsym uint32 + tocoff uint32 + ntoc uint32 + modtaboff uint32 + nmodtab uint32 + extrefsymoff uint32 + nextrefsyms uint32 + indirectsymoff uint32 + nindirectsyms uint32 + extreloff uint32 + nextrel uint32 + localrefoff uint32 + nlocref uint32 +} + +func (lcmd *DySymtab) Cmd() uint32 { + return lcmd.c.Cmd() +} + +func (lcmd *DySymtab) Cmdsize() uint32 { + return uint32(8 + 4*18) +} + +func (lcmd *DySymtab) Cmdname() string { + return fmt.Sprintf("%s indirectsymoff:0x%x nindirectsyms:%d", + lcmd.c.Cmdname(), lcmd.indirectsymoff, lcmd.nindirectsyms) +} + +func (lcmd *DySymtab) Serialize(mc *MachoContext) []byte { + buf := new(bytes.Buffer) + binary.Write(buf, mc.byteorder, lcmd.Cmd()) + binary.Write(buf, mc.byteorder, lcmd.Cmdsize()) + binary.Write(buf, mc.byteorder, lcmd.ilocalsym) + binary.Write(buf, mc.byteorder, lcmd.nlocalsym) + binary.Write(buf, mc.byteorder, lcmd.iextdefsym) + binary.Write(buf, mc.byteorder, lcmd.nextdefsym) + binary.Write(buf, mc.byteorder, lcmd.iundefsym) + binary.Write(buf, mc.byteorder, lcmd.nundefsym) + binary.Write(buf, mc.byteorder, lcmd.tocoff) + binary.Write(buf, mc.byteorder, lcmd.ntoc) + binary.Write(buf, mc.byteorder, lcmd.modtaboff) + binary.Write(buf, mc.byteorder, lcmd.nmodtab) + binary.Write(buf, mc.byteorder, lcmd.extrefsymoff) + binary.Write(buf, mc.byteorder, lcmd.nextrefsyms) + binary.Write(buf, mc.byteorder, lcmd.indirectsymoff) + binary.Write(buf, mc.byteorder, lcmd.nindirectsyms) + binary.Write(buf, mc.byteorder, lcmd.extreloff) + binary.Write(buf, mc.byteorder, lcmd.nextrel) + binary.Write(buf, mc.byteorder, lcmd.localrefoff) + binary.Write(buf, mc.byteorder, lcmd.nlocref) + return buf.Bytes() +} + +func (lcmd *DySymtab) Deserialize(mc *MachoContext, buf []byte) { + r := bytes.NewBuffer(buf) + binary.Read(r, mc.byteorder, &lcmd.c.cmd) + binary.Read(r, mc.byteorder, &lcmd.c.cmdsize) + binary.Read(r, mc.byteorder, &lcmd.ilocalsym) + binary.Read(r, mc.byteorder, &lcmd.nlocalsym) + binary.Read(r, mc.byteorder, &lcmd.iextdefsym) + binary.Read(r, mc.byteorder, &lcmd.nextdefsym) + binary.Read(r, mc.byteorder, &lcmd.iundefsym) + binary.Read(r, mc.byteorder, &lcmd.nundefsym) + binary.Read(r, mc.byteorder, &lcmd.tocoff) + binary.Read(r, mc.byteorder, &lcmd.ntoc) + binary.Read(r, mc.byteorder, &lcmd.modtaboff) + binary.Read(r, mc.byteorder, &lcmd.nmodtab) + binary.Read(r, mc.byteorder, &lcmd.extrefsymoff) + binary.Read(r, mc.byteorder, &lcmd.nextrefsyms) + binary.Read(r, mc.byteorder, &lcmd.indirectsymoff) + binary.Read(r, mc.byteorder, &lcmd.nindirectsyms) + binary.Read(r, mc.byteorder, &lcmd.extreloff) + binary.Read(r, mc.byteorder, &lcmd.nextrel) + binary.Read(r, mc.byteorder, &lcmd.localrefoff) + binary.Read(r, mc.byteorder, &lcmd.nlocref) +} diff --git a/macho-go/pkg/ios/macho/macho.go b/macho-go/pkg/ios/macho/macho.go index 3d33fed..c8fc09b 100644 --- a/macho-go/pkg/ios/macho/macho.go +++ b/macho-go/pkg/ios/macho/macho.go @@ -29,7 +29,11 @@ type MachoContext struct { linkedits []*LinkEdit segments []Segment symtab *Symtab + dysymtab *DySymtab + dyldinfo *DyldInfo + fixups *LinkEdit + exports *LinkEdit } func (mc *MachoContext) FileSize() uint32 { @@ -231,6 +235,12 @@ func (mc *MachoContext) Parse(r *bufio.Reader) error { lcmd.Deserialize(mc, command_buf) mc.commands = append(mc.commands, lcmd) mc.linkedits = append(mc.linkedits, lcmd) + if lcmd.Cmd() == LC_DYLD_CHAINED_FIXUPS { + mc.fixups = lcmd + } + if lcmd.Cmd() == LC_DYLD_EXPORTS_TRIE { + mc.exports = lcmd + } break case LC_SYMTAB: @@ -239,6 +249,12 @@ func (mc *MachoContext) Parse(r *bufio.Reader) error { mc.commands = append(mc.commands, lcmd) mc.symtab = lcmd + case LC_DYSYMTAB: + lcmd := new(DySymtab) + lcmd.Deserialize(mc, command_buf) + mc.commands = append(mc.commands, lcmd) + mc.dysymtab = lcmd + default: lcmd := new(LoadCmd) lcmd.Deserialize(mc, command_buf)