1
1
mirror of https://github.com/wader/fq.git synced 2024-12-25 22:34:14 +03:00
fq/format/macho/macho_fat.go
Mattias Wadman 725c8e83ab macho: Split into macho/macho_fat, fix offset issue and add string decoding
Split fat macho into own decoder macho_fat. This also fixes issue with section
offset etc not being correct as they are from the start of each embedded file.

Make all address and offset field be in hex.

Decode __cstring, __ustring and __cfstring sections.

Fix LC_ENCRYPTION_INFO_64 missing pading issue.

Skip ranging for __bss and __common as they dont have any data in the file.

Simplifed magic handling a bit and add symbols.

Simplified state struct field, had redudant struct.
2022-08-02 14:36:53 +02:00

66 lines
1.6 KiB
Go

package macho
// https://github.com/aidansteele/osx-abi-macho-file-format-reference
import (
"github.com/wader/fq/format"
"github.com/wader/fq/pkg/decode"
"github.com/wader/fq/pkg/interp"
"github.com/wader/fq/pkg/scalar"
)
var machoFormat decode.Group
func init() {
interp.RegisterFormat(decode.Format{
Name: format.MACHO_FAT,
Description: "Fat Mach-O macOS executable (multi-architecture)",
Groups: []string{format.PROBE},
DecodeFn: machoFatDecode,
Dependencies: []decode.Dependency{
{Names: []string{format.MACHO}, Group: &machoFormat},
},
})
}
//nolint:revive
const FAT_MAGIC = 0xcafe_babe
func machoFatDecode(d *decode.D, _ any) any {
type ofile struct {
offset int64
size int64
}
var ofiles []ofile
d.FieldStruct("fat_header", func(d *decode.D) {
d.FieldU32("magic", magicSymMapper, scalar.ActualHex, d.AssertU(FAT_MAGIC))
narchs := d.FieldU32("narchs")
d.FieldArray("archs", func(d *decode.D) {
for i := 0; i < int(narchs); i++ {
d.FieldStruct("arch", func(d *decode.D) {
// beware cputype and cpusubtype changes from ofile header to fat header
cpuType := d.FieldU32("cputype", cpuTypes, scalar.ActualHex)
d.FieldU32("cpusubtype", cpuSubTypes[cpuType], scalar.ActualHex)
offset := d.FieldU32("offset", scalar.ActualHex)
size := d.FieldU32("size")
d.FieldU32("align")
ofiles = append(ofiles, ofile{offset: int64(offset), size: int64(size)})
})
}
})
})
d.FieldArray("files", func(d *decode.D) {
for _, o := range ofiles {
d.RangeFn(o.offset*8, o.size*8, func(d *decode.D) {
d.FieldFormat("file", machoFormat, nil)
})
}
})
return nil
}