From 58d77dd03153c5635230d44dd7f6c9de352f689d Mon Sep 17 00:00:00 2001 From: blacktop Date: Sun, 1 Sep 2024 14:54:11 -0600 Subject: [PATCH] fix: prebuilt loader set fallback in iOS18 (#543) --- cmd/ipsw/cmd/dyld/dyld_image.go | 14 ++- internal/commands/dsc/dsc.go | 2 +- pkg/dyld/closure.go | 7 -- pkg/dyld/prebuilt.go | 162 +++++++++++++++++--------------- pkg/dyld/prebuilt_types.go | 41 +++++--- pkg/dyld/symbols.go | 4 +- 6 files changed, 131 insertions(+), 99 deletions(-) diff --git a/cmd/ipsw/cmd/dyld/dyld_image.go b/cmd/ipsw/cmd/dyld/dyld_image.go index a3f4500385..4e5d0b2c8c 100644 --- a/cmd/ipsw/cmd/dyld/dyld_image.go +++ b/cmd/ipsw/cmd/dyld/dyld_image.go @@ -51,6 +51,7 @@ var ImageCmd = &cobra.Command{ return getDSCs(toComplete), cobra.ShellCompDirectiveDefault }, SilenceErrors: true, + SilenceUsage: true, Example: ` # List all the apps ❯ ipsw dyld image DSC # Dump the closure info for a in-cache dylib @@ -103,7 +104,9 @@ var ImageCmd = &cobra.Command{ if pbl, err := f.GetDylibPrebuiltLoader(image.Name); err == nil { fmt.Println(pbl.String(f)) } else { - if !errors.Is(err, dyld.ErrPrebuiltLoaderSetNotSupported) { + if errors.Is(err, dyld.ErrPrebuiltLoaderSetNotSupported) { + log.Warn("prebuilt loader sets not supported for this version of dyld_shared_cache") + } else { return fmt.Errorf("failed parsing launch loader sets: %v", err) } // try to parse the dylib closures using the old iOS14.x method @@ -122,7 +125,9 @@ var ImageCmd = &cobra.Command{ if pset, err := f.GetLaunchLoaderSet(args[1]); err == nil { fmt.Println(pset.String(f)) } else { - if !errors.Is(err, dyld.ErrPrebuiltLoaderSetNotSupported) { + if errors.Is(err, dyld.ErrPrebuiltLoaderSetNotSupported) { + log.Warn("prebuilt loader sets not supported for this version of dyld_shared_cache") + } else { return fmt.Errorf("failed parsing launch loader sets: %v", err) } // try to parse the app closures using the old iOS14.x method @@ -134,6 +139,7 @@ var ImageCmd = &cobra.Command{ fmt.Println(ci.String(f, viper.GetBool("verbose"))) return nil } else { + log.Warn("failed to find app in 'other' image arrays: attempting to find in program launch closures") for _, clos := range f.Closures { for _, img := range clos.Images { if img.Name == args[1] { @@ -150,7 +156,9 @@ var ImageCmd = &cobra.Command{ if err := f.ForEachLaunchLoaderSetPath(func(execPath string) { fmt.Println(execPath) }); err != nil { - if !errors.Is(err, dyld.ErrPrebuiltLoaderSetNotSupported) { + if errors.Is(err, dyld.ErrPrebuiltLoaderSetNotSupported) { + log.Warn("prebuilt loader sets not supported for this version of dyld_shared_cache") + } else { return fmt.Errorf("failed parsing launch loader sets: %v", err) } // try to parse the image array using the old iOS14.x method diff --git a/internal/commands/dsc/dsc.go b/internal/commands/dsc/dsc.go index fcef5baa3c..dce5344651 100644 --- a/internal/commands/dsc/dsc.go +++ b/internal/commands/dsc/dsc.go @@ -412,7 +412,7 @@ func GetDylibsThatImport(f *dyld.File, name string) (*ImportedBy, error) { } } - if f.SupportsPrebuiltLoaderSet() { + if f.SupportsProgramTrie() { if err := f.ForEachLaunchLoaderSet(func(execPath string, pset *dyld.PrebuiltLoaderSet) { for _, loader := range pset.Loaders { for _, dep := range loader.Dependents { diff --git a/pkg/dyld/closure.go b/pkg/dyld/closure.go index f4bb185428..d9b7f95525 100644 --- a/pkg/dyld/closure.go +++ b/pkg/dyld/closure.go @@ -961,14 +961,7 @@ func (f *File) GetDylibsImageArray() error { var size uint64 if f.Headers[f.UUID].DylibsImageArrayAddr == 0 { - if f.Headers[f.UUID].DylibsPblSetAddr > 0 { - return fmt.Errorf("ipsw cannot parse dylibs image array info for macOS12+/iOS15+ yet 😔") - } return fmt.Errorf("cache does not contain dylibs image array info") - // } else { - // addr = f.Headers[f.UUID].DylibsPblSetAddr - // size = f.Headers[f.UUID].ProgramsPblSetPoolAddr - f.Headers[f.UUID].DylibsPblSetAddr - // } } else { addr = f.Headers[f.UUID].DylibsImageArrayAddr size = f.Headers[f.UUID].DylibsImageArraySize diff --git a/pkg/dyld/prebuilt.go b/pkg/dyld/prebuilt.go index f9db9cc811..af4fbe46a9 100644 --- a/pkg/dyld/prebuilt.go +++ b/pkg/dyld/prebuilt.go @@ -13,7 +13,7 @@ import ( "github.com/blacktop/go-macho/types" ) -func (f *File) SupportsPrebuiltLoaderSet() bool { +func (f *File) SupportsProgramTrie() bool { if f.Headers[f.UUID].MappingOffset < uint32(unsafe.Offsetof(f.Headers[f.UUID].ProgramTrieSize)) { return false } @@ -24,11 +24,8 @@ func (f *File) SupportsPrebuiltLoaderSet() bool { } func (f *File) ForEachLaunchLoaderSet(handler func(execPath string, pset *PrebuiltLoaderSet)) error { - if f.Headers[f.UUID].MappingOffset < uint32(unsafe.Offsetof(f.Headers[f.UUID].ProgramTrieSize)) { - return ErrPrebuiltLoaderSetNotSupported - } - if f.Headers[f.UUID].ProgramTrieAddr == 0 { - return ErrPrebuiltLoaderSetNotSupported + if !f.SupportsProgramTrie() { + return ErrProgramTrieNotSupported } uuid, off, err := f.GetOffset(f.Headers[f.UUID].ProgramTrieAddr) @@ -73,11 +70,8 @@ func (f *File) ForEachLaunchLoaderSet(handler func(execPath string, pset *Prebui } func (f *File) ForEachLaunchLoaderSetPath(handler func(execPath string)) error { - if f.Headers[f.UUID].MappingOffset < uint32(unsafe.Offsetof(f.Headers[f.UUID].ProgramTrieSize)) { - return ErrPrebuiltLoaderSetNotSupported - } - if f.Headers[f.UUID].ProgramTrieAddr == 0 { - return ErrPrebuiltLoaderSetNotSupported + if !f.SupportsProgramTrie() { + return ErrProgramTrieNotSupported } uuid, off, err := f.GetOffset(f.Headers[f.UUID].ProgramTrieAddr) @@ -106,10 +100,10 @@ func (f *File) ForEachLaunchLoaderSetPath(handler func(execPath string)) error { // GetLaunchLoaderSet returns the PrebuiltLoaderSet for the given executable app path. func (f *File) GetLaunchLoaderSet(executablePath string) (*PrebuiltLoaderSet, error) { - if f.Headers[f.UUID].MappingOffset < uint32(unsafe.Offsetof(f.Headers[f.UUID].ProgramTrieSize)) { - return nil, ErrPrebuiltLoaderSetNotSupported + if !f.SupportsProgramTrie() { + return nil, ErrProgramTrieNotSupported } - if f.Headers[f.UUID].ProgramTrieAddr == 0 { + if !f.SupportsDylibPrebuiltLoader() { return nil, ErrPrebuiltLoaderSetNotSupported } @@ -164,17 +158,7 @@ func (f *File) SupportsDylibPrebuiltLoader() bool { // GetLaunchLoader returns the PrebuiltLoader for the given executable in-cache dylib path. func (f *File) GetDylibPrebuiltLoader(executablePath string) (*PrebuiltLoader, error) { - if f.Headers[f.UUID].MappingOffset < uint32(unsafe.Offsetof(f.Headers[f.UUID].ProgramTrieSize)) { - return nil, ErrPrebuiltLoaderSetNotSupported - } - if f.Headers[f.UUID].MappingOffset < uint32(unsafe.Offsetof(f.Headers[f.UUID].DylibsPblSetAddr)) { - return nil, ErrPrebuiltLoaderSetNotSupported - } - // FIXME: REMOVE once I have added iOS 18.x support - if f.Headers[f.UUID].MappingOffset > uint32(unsafe.Offsetof(f.Headers[f.UUID].TPROMappingOffset)) { - return nil, ErrPrebuiltLoaderSetNotSupported - } - if f.Headers[f.UUID].DylibsPblSetAddr == 0 { + if !f.SupportsDylibPrebuiltLoader() { return nil, ErrPrebuiltLoaderSetNotSupported } @@ -182,6 +166,9 @@ func (f *File) GetDylibPrebuiltLoader(executablePath string) (*PrebuiltLoader, e if err != nil { return nil, err } + // if sc := f.GetSubCacheInfo(uuid); sc != nil { + // log.Debug(sc.Extention) + // } sr := io.NewSectionReader(f.r[uuid], int64(off), 1<<63-1) @@ -190,6 +177,10 @@ func (f *File) GetDylibPrebuiltLoader(executablePath string) (*PrebuiltLoader, e return nil, err } + if pset.Magic != PrebuiltLoaderSetMagic { + return nil, fmt.Errorf("invalid magic for PrebuiltLoaderSet: expected %x got %x", PrebuiltLoaderSetMagic, pset.Magic) + } + sr.Seek(int64(pset.LoadersArrayOffset), io.SeekStart) loaderOffsets := make([]uint32, pset.LoadersArrayCount) @@ -206,6 +197,8 @@ func (f *File) GetDylibPrebuiltLoader(executablePath string) (*PrebuiltLoader, e sr.Seek(int64(loaderOffsets[imgIdx]), io.SeekStart) + // fmt.Println(executablePath) + return f.parsePrebuiltLoader(io.NewSectionReader(f.r[uuid], int64(off)+int64(loaderOffsets[imgIdx]), 1<<63-1)) } @@ -281,7 +274,7 @@ func (f *File) parsePrebuiltLoaderSet(sr *io.SectionReader) (*PrebuiltLoaderSet, } pset.SelectorTable = &o } - if pset.ObjcClassHashTableOffset > 0 { + if pset.ObjcClassHashTableOffset > 0 && !pset.Loaders[0].Loader.IsVersion2() { sr.Seek(int64(pset.ObjcClassHashTableOffset), io.SeekStart) var o ObjCClassOpt if err := binary.Read(sr, f.ByteOrder, &o.objCStringTable); err != nil { @@ -315,7 +308,7 @@ func (f *File) parsePrebuiltLoaderSet(sr *io.SectionReader) (*PrebuiltLoaderSet, } pset.ClassTable = &o } - if pset.ObjcProtocolHashTableOffset > 0 { + if pset.ObjcProtocolHashTableOffset > 0 && !pset.Loaders[0].Loader.IsVersion2() { sr.Seek(int64(pset.ObjcProtocolHashTableOffset), io.SeekStart) var o ObjCClassOpt if err := binary.Read(sr, f.ByteOrder, &o.objCStringTable); err != nil { @@ -430,58 +423,77 @@ func (f *File) parsePrebuiltLoaderSet(sr *io.SectionReader) (*PrebuiltLoaderSet, // parsePrebuiltLoader parses a prebuilt loader from a section reader. func (f *File) parsePrebuiltLoader(sr *io.SectionReader) (*PrebuiltLoader, error) { var pbl PrebuiltLoader - if err := binary.Read(sr, binary.LittleEndian, &pbl.prebuiltLoaderHeader); err != nil { - return nil, err + + if err := binary.Read(sr, binary.LittleEndian, &pbl.Loader); err != nil { + return nil, fmt.Errorf("failed to read prebuilt loader: %v", err) } - if pbl.Magic != LoaderMagic { - return nil, fmt.Errorf("invalid magic for prebuilt loader: expected %x got %x", LoaderMagic, pbl.Magic) + if pbl.Loader.IsVersion2() { + // skip unknown data => [12]uint16 + sr.Seek(24, io.SeekCurrent) } - if pbl.PathOffset > 0 { - sr.Seek(int64(pbl.PathOffset), io.SeekStart) - br := bufio.NewReader(sr) - path, err := br.ReadString('\x00') + if err := binary.Read(sr, binary.LittleEndian, &pbl.Header); err != nil { + return nil, fmt.Errorf("failed to read prebuilt loader header: %v", err) + } + + if pbl.Loader.Magic != LoaderMagic { + return nil, fmt.Errorf("invalid magic for prebuilt loader: expected %x got %x", LoaderMagic, pbl.Loader.Magic) + } + + // log.Debug(pbl.Loader.String()) + // log.Debug(pbl.GetInfo()) + + // fmt.Println("Loader Info:") + // fmt.Println(utils.Bits(uint64(pbl.Loader.Info))) + // fmt.Println("Info:") + // fmt.Println(pbl.GetInfo()) + + if pbl.Header.PathOffset > 0 { + sr.Seek(int64(pbl.Header.PathOffset), io.SeekStart) + path, err := bufio.NewReader(sr).ReadString('\x00') if err != nil { - return nil, err + return nil, fmt.Errorf("failed to read prebuilt loader path: %v", err) } pbl.Path = strings.TrimSuffix(path, "\x00") } - if pbl.AltPathOffset > 0 { - sr.Seek(int64(pbl.AltPathOffset), io.SeekStart) - br := bufio.NewReader(sr) - path, err := br.ReadString('\x00') + if pbl.Header.AltPathOffset > 0 { + sr.Seek(int64(pbl.Header.AltPathOffset), io.SeekStart) + path, err := bufio.NewReader(sr).ReadString('\x00') if err != nil { - return nil, err + return nil, fmt.Errorf("failed to read prebuilt loader alt path: %v", err) } pbl.AltPath = strings.TrimSuffix(path, "\x00") } - if pbl.FileValidationOffset > 0 { - sr.Seek(int64(pbl.FileValidationOffset), io.SeekStart) + if pbl.Header.FileValidationOffset > 0 { + sr.Seek(int64(pbl.Header.FileValidationOffset), io.SeekStart) var fv fileValidation if err := binary.Read(sr, binary.LittleEndian, &fv); err != nil { - return nil, err + return nil, fmt.Errorf("failed to read prebuilt loader file validation: %v", err) } pbl.FileValidation = &fv } if pbl.RegionsCount() > 0 { - sr.Seek(int64(pbl.RegionsOffset), io.SeekStart) + sr.Seek(int64(pbl.Header.RegionsOffset), io.SeekStart) pbl.Regions = make([]Region, pbl.RegionsCount()) if err := binary.Read(sr, binary.LittleEndian, &pbl.Regions); err != nil { - return nil, err + return nil, fmt.Errorf("failed to read prebuilt loader regions: %v", err) } + // for i, r := range pbl.Regions { + // fmt.Printf("Region %d) %s\n", i, r) + // } } - if pbl.DependentLoaderRefsArrayOffset > 0 { - sr.Seek(int64(pbl.DependentLoaderRefsArrayOffset), io.SeekStart) - depsArray := make([]LoaderRef, pbl.DepCount) + if pbl.Header.DependentLoaderRefsArrayOffset > 0 { + sr.Seek(int64(pbl.Header.DependentLoaderRefsArrayOffset), io.SeekStart) + depsArray := make([]LoaderRef, pbl.Header.DepCount) if err := binary.Read(sr, binary.LittleEndian, &depsArray); err != nil { - return nil, err + return nil, fmt.Errorf("failed to read prebuilt loader dependent loader refs: %v", err) } - kindsArray := make([]DependentKind, pbl.DepCount) - if pbl.DependentKindArrayOffset > 0 { - sr.Seek(int64(pbl.DependentKindArrayOffset), io.SeekStart) + kindsArray := make([]DependentKind, pbl.Header.DepCount) + if pbl.Header.DependentKindArrayOffset > 0 { + sr.Seek(int64(pbl.Header.DependentKindArrayOffset), io.SeekStart) if err := binary.Read(sr, binary.LittleEndian, &kindsArray); err != nil { - return nil, err + return nil, fmt.Errorf("failed to read prebuilt loader dependent kinds: %v", err) } } for idx, dep := range depsArray { @@ -495,47 +507,47 @@ func (f *File) parsePrebuiltLoader(sr *io.SectionReader) (*PrebuiltLoader, error }) } } - if pbl.BindTargetRefsCount > 0 { - sr.Seek(int64(pbl.BindTargetRefsOffset), io.SeekStart) - pbl.BindTargets = make([]BindTargetRef, pbl.BindTargetRefsCount) + if pbl.Header.BindTargetRefsCount > 0 { + sr.Seek(int64(pbl.Header.BindTargetRefsOffset), io.SeekStart) + pbl.BindTargets = make([]BindTargetRef, pbl.Header.BindTargetRefsCount) if err := binary.Read(sr, binary.LittleEndian, &pbl.BindTargets); err != nil { - return nil, err + return nil, fmt.Errorf("failed to read prebuilt loader bind target refs: %v", err) } } - if pbl.OverrideBindTargetRefsCount > 0 { - sr.Seek(int64(pbl.OverrideBindTargetRefsOffset), io.SeekStart) - pbl.OverrideBindTargets = make([]BindTargetRef, pbl.OverrideBindTargetRefsCount) + if pbl.Header.OverrideBindTargetRefsCount > 0 { + sr.Seek(int64(pbl.Header.OverrideBindTargetRefsOffset), io.SeekStart) + pbl.OverrideBindTargets = make([]BindTargetRef, pbl.Header.OverrideBindTargetRefsCount) if err := binary.Read(sr, binary.LittleEndian, &pbl.OverrideBindTargets); err != nil { - return nil, err + return nil, fmt.Errorf("failed to read prebuilt loader override bind target refs: %v", err) } } - if pbl.ObjcBinaryInfoOffset > 0 { - sr.Seek(int64(pbl.ObjcBinaryInfoOffset), io.SeekStart) + if pbl.Header.ObjcBinaryInfoOffset > 0 { + sr.Seek(int64(pbl.Header.ObjcBinaryInfoOffset), io.SeekStart) var ofi ObjCBinaryInfo if err := binary.Read(sr, binary.LittleEndian, &ofi); err != nil { - return nil, err + return nil, fmt.Errorf("failed to read prebuilt loader objc binary info: %v", err) } pbl.ObjcFixupInfo = &ofi - sr.Seek(int64(pbl.ObjcBinaryInfoOffset)+int64(pbl.ObjcFixupInfo.ProtocolFixupsOffset), io.SeekStart) + sr.Seek(int64(pbl.Header.ObjcBinaryInfoOffset)+int64(pbl.ObjcFixupInfo.ProtocolFixupsOffset), io.SeekStart) pbl.ObjcCanonicalProtocolFixups = make([]bool, pbl.ObjcFixupInfo.ProtocolListCount) if err := binary.Read(sr, binary.LittleEndian, &pbl.ObjcCanonicalProtocolFixups); err != nil { - return nil, err + return nil, fmt.Errorf("failed to read prebuilt loader objc canonical protocol fixups: %v", err) } - sr.Seek(int64(pbl.ObjcBinaryInfoOffset)+int64(pbl.ObjcFixupInfo.SelectorReferencesFixupsOffset), io.SeekStart) + sr.Seek(int64(pbl.Header.ObjcBinaryInfoOffset)+int64(pbl.ObjcFixupInfo.SelectorReferencesFixupsOffset), io.SeekStart) pbl.ObjcSelectorFixups = make([]BindTargetRef, pbl.ObjcFixupInfo.SelectorReferencesFixupsCount) if err := binary.Read(sr, binary.LittleEndian, &pbl.ObjcSelectorFixups); err != nil { - return nil, err + return nil, fmt.Errorf("failed to read prebuilt loader objc selector fixups: %v", err) } } - if pbl.IndexOfTwin != NoUnzipperedTwin { - pbl.Twin = f.Images[pbl.IndexOfTwin].Name + if pbl.Header.IndexOfTwin != NoUnzipperedTwin { + pbl.Twin = f.Images[pbl.Header.IndexOfTwin].Name } - if pbl.PatchTableOffset > 0 { - sr.Seek(int64(pbl.PatchTableOffset), io.SeekStart) + if pbl.Header.PatchTableOffset > 0 { + sr.Seek(int64(pbl.Header.PatchTableOffset), io.SeekStart) for { var patch DylibPatch if err := binary.Read(sr, binary.LittleEndian, &patch); err != nil { - return nil, err + return nil, fmt.Errorf("failed to read prebuilt loader dylib patch: %v", err) } pbl.DylibPatches = append(pbl.DylibPatches, patch) if patch.Kind == endOfPatchTable { @@ -546,3 +558,5 @@ func (f *File) parsePrebuiltLoader(sr *io.SectionReader) (*PrebuiltLoader, error return &pbl, nil } + +// 110594112 [6978840h] SIZE = 0x222CA0; PADDING = 0x6B310; diff --git a/pkg/dyld/prebuilt_types.go b/pkg/dyld/prebuilt_types.go index 00e6d4f50e..492d7baa62 100644 --- a/pkg/dyld/prebuilt_types.go +++ b/pkg/dyld/prebuilt_types.go @@ -16,6 +16,7 @@ const ( ) var ErrPrebuiltLoaderSetNotSupported = fmt.Errorf("dyld_shared_cache has no launch prebuilt loader set info") +var ErrProgramTrieNotSupported = fmt.Errorf("dyld_shared_cache has no program trie info") type LoaderRef uint16 @@ -59,8 +60,10 @@ type Loader struct { // hasReadOnlyObjC : 1, // Has __DATA_CONST,__objc_selrefs section // pre2022Binary : 1, // isPremapped : 1, // mapped by exclave core + // isVersion2 : 1, // FIXME: when dyld src is out for iOS 18.0/macOS 15.0 // padding : 6; Ref LoaderRef + // Unk [12]uint16 } func (l Loader) IsPrebuilt() bool { @@ -93,6 +96,9 @@ func (l Loader) Pre2022Binary() bool { func (l Loader) IsPremapped() bool { return types.ExtractBits(uint64(l.Info), 9, 1) != 0 } +func (l Loader) IsVersion2() bool { + return types.ExtractBits(uint64(l.Info), 10, 1) != 0 +} func (l Loader) String() string { var out []string @@ -128,6 +134,9 @@ func (l Loader) String() string { if l.IsPremapped() { out = append(out, "premapped") } + if l.IsVersion2() { + out = append(out, "v2") + } return fmt.Sprintf("%s, ref: %s", strings.Join(out, "|"), l.Ref) } @@ -303,6 +312,11 @@ type CodeSignatureInFile struct { Size uint32 } +type ExportsTrieLoaderInFile struct { + Offset uint64 + Size uint32 +} + func deserializeAbsoluteValue(value uint64) uint64 { // sign extend if (value & 0x4000000000000000) != 0 { @@ -317,7 +331,6 @@ type dependent struct { } type prebuiltLoaderHeader struct { - Loader PathOffset uint16 DependentLoaderRefsArrayOffset uint16 // offset to array of LoaderRef DependentKindArrayOffset uint16 // zero if all deps normal @@ -343,9 +356,9 @@ type prebuiltLoaderHeader struct { IndexOfTwin uint16 // if in dyld cache and part of unzippered twin, then index of the other twin _ uint16 - ExportsTrieLoaderOffset uint64 - ExportsTrieLoaderSize uint32 - VmSize uint32 + ExportsTrieLoader ExportsTrieLoaderInFile + + VmSize uint32 CodeSignature CodeSignatureInFile @@ -449,7 +462,8 @@ func (o ObjCBinaryInfo) String() string { } type PrebuiltLoader struct { - prebuiltLoaderHeader + Loader + Header prebuiltLoaderHeader Path string AltPath string Twin string @@ -493,6 +507,9 @@ func (pl PrebuiltLoader) GetInfo() string { if pl.IsCatalystOverride() { out = append(out, "catalyst_override") } + if pl.RegionsCount() > 0 { + out = append(out, fmt.Sprintf("regions=%d", pl.RegionsCount())) + } return strings.Join(out, "|") } func (pl PrebuiltLoader) GetFileOffset(vmoffset uint64) uint64 { @@ -514,9 +531,9 @@ func (pl PrebuiltLoader) String(f *File) string { if pl.Twin != "" { out += fmt.Sprintf("Twin: %s\n", pl.Twin) } - out += fmt.Sprintf("VM Size: %#x\n", pl.VmSize) - if pl.CodeSignature.Size > 0 { - out += fmt.Sprintf("CodeSignature: off=%#08x, sz=%#x\n", pl.CodeSignature.FileOffset, pl.CodeSignature.Size) + out += fmt.Sprintf("VM Size: %#x\n", pl.Header.VmSize) + if pl.Header.CodeSignature.Size > 0 { + out += fmt.Sprintf("CodeSignature: off=%#08x, sz=%#x\n", pl.Header.CodeSignature.FileOffset, pl.Header.CodeSignature.Size) } if pl.FileValidation != nil { if pl.FileValidation.CheckCDHash { @@ -538,11 +555,11 @@ func (pl PrebuiltLoader) String(f *File) string { if len(pl.GetInfo()) > 0 { out += fmt.Sprintf("Info: %s\n", pl.GetInfo()) } - if pl.ExportsTrieLoaderSize > 0 { - out += fmt.Sprintf("ExportsTrie: off=%#08x, sz=%#x\n", pl.GetFileOffset(pl.ExportsTrieLoaderOffset), pl.ExportsTrieLoaderSize) + if pl.Header.ExportsTrieLoader.Size > 0 { + out += fmt.Sprintf("ExportsTrie: off=%#08x, sz=%#x\n", pl.GetFileOffset(pl.Header.ExportsTrieLoader.Offset), pl.Header.ExportsTrieLoader.Size) } - if pl.FixupsLoadCommandOffset > 0 { - out += fmt.Sprintf("FixupsLoadCmd: off=%#08x\n", pl.FixupsLoadCommandOffset) + if pl.Header.FixupsLoadCommandOffset > 0 { + out += fmt.Sprintf("FixupsLoadCmd: off=%#08x\n", pl.Header.FixupsLoadCommandOffset) } if len(pl.Regions) > 0 { out += "\nRegions:\n" diff --git a/pkg/dyld/symbols.go b/pkg/dyld/symbols.go index 1225e5cf73..8e566eaade 100644 --- a/pkg/dyld/symbols.go +++ b/pkg/dyld/symbols.go @@ -291,11 +291,11 @@ func (f *File) GetExportedSymbols(ctx context.Context, symbolName string) (<-cha if err != nil { return fmt.Errorf("failed to get prebuilt loader for %s: %s", image.Name, err) } - uuid, off, err := f.GetOffset(image.LoadAddress + pbl.ExportsTrieLoaderOffset) + uuid, off, err := f.GetOffset(image.LoadAddress + pbl.Header.ExportsTrieLoader.Offset) if err != nil { return fmt.Errorf("failed to get ExportsTrie offset for %s: %s", image.Name, err) } - data, err := f.ReadBytesForUUID(uuid, int64(off), uint64(pbl.ExportsTrieLoaderSize)) + data, err := f.ReadBytesForUUID(uuid, int64(off), uint64(pbl.Header.ExportsTrieLoader.Size)) if err != nil { return fmt.Errorf("failed to read ExportsTrie data for %s: %s", image.Name, err) }