1
1
mirror of https://github.com/wader/fq.git synced 2024-12-03 21:52:59 +03:00
fq/format/apple/macho/macho_fat.go
2023-05-01 13:19:04 +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(
format.MachO_Fat,
&decode.Format{
Description: "Fat Mach-O macOS executable (multi-architecture)",
Groups: []*decode.Group{format.Probe},
DecodeFn: machoFatDecode,
Dependencies: []decode.Dependency{
{Groups: []*decode.Group{format.MachO}, Out: &machoFormat},
},
})
}
const FAT_MAGIC = 0xcafe_babe
func machoFatDecode(d *decode.D) any {
type ofile struct {
offset int64
size int64
}
var ofiles []ofile
d.FieldStruct("fat_header", func(d *decode.D) {
d.FieldU32("magic", magicSymMapper, scalar.UintHex, d.UintAssert(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.UintHex)
d.FieldU32("cpusubtype", cpuSubTypes[cpuType], scalar.UintHex)
offset := d.FieldU32("offset", scalar.UintHex)
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
}