add parsing for more commands

This commit is contained in:
nganhkhoa 2023-06-06 13:15:17 +07:00
parent 6d757108a7
commit 6089c18d30
3 changed files with 136 additions and 9 deletions

View File

@ -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

View File

@ -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)
}

View File

@ -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)