summaryrefslogtreecommitdiff
path: root/view/macho
diff options
context:
space:
mode:
authorAlexander Taylor <alex@vector35.com>2025-04-10 13:27:34 -0400
committerAlexander Taylor <alex@vector35.com>2025-04-14 18:35:29 -0400
commit941b8b63c02184b4708d85391c5348b8d8913628 (patch)
treef2b2dca7fda020595f6b314bbcd516d7247b977c /view/macho
parentc3f286e6ab09fb7945d84fa7d213905d328bb4e5 (diff)
Avoid MH_FILESET in Mach-O view during magic check.
Diffstat (limited to 'view/macho')
-rw-r--r--view/macho/fatmachoview.cpp4
-rw-r--r--view/macho/machoview.cpp45
2 files changed, 31 insertions, 18 deletions
diff --git a/view/macho/fatmachoview.cpp b/view/macho/fatmachoview.cpp
index de9b755b..83499fb6 100644
--- a/view/macho/fatmachoview.cpp
+++ b/view/macho/fatmachoview.cpp
@@ -210,8 +210,8 @@ bool FatMachoViewType::IsTypeValidForData(BinaryView* data)
if (!ExtractFatArchForCPU(data, arch, m_cputype, m_cpusubtype))
return false;
- // MachoView::IsMacho only considers the magic header, so we can load only that
- DataBuffer buffer = data->ReadBuffer(arch.offset, 4);
+ // MachoView::IsMacho needs to inspect the full header
+ DataBuffer buffer = data->ReadBuffer(arch.offset, sizeof(mach_header));
Ref<BinaryData> newData = new BinaryData(data->GetFile(), std::move(buffer));
Ref<BinaryViewType> attemptedViewType = FatViewTypeForData(newData);
diff --git a/view/macho/machoview.cpp b/view/macho/machoview.cpp
index df742c25..440d2797 100644
--- a/view/macho/machoview.cpp
+++ b/view/macho/machoview.cpp
@@ -3730,27 +3730,40 @@ Ref<BinaryView> MachoViewType::Parse(BinaryView* data)
bool MachoViewType::IsTypeValidForData(BinaryView* data)
{
if (!data)
+ {
+ // Can't be valid if we don't have any data
return false;
+ }
- DataBuffer sig = data->ReadBuffer(data->GetStart(), 4);
- if (sig.GetLength() != 4)
+ DataBuffer header = data->ReadBuffer(data->GetStart(), sizeof(mach_header));
+ if (header.GetLength() < sizeof(mach_header))
+ {
+ // Can't be valid if we don't have enough data for a header
return false;
+ }
- uint32_t magic = *(uint32_t*)sig.GetData();
- if (magic == MH_CIGAM || magic == MH_CIGAM_64 || magic == MH_MAGIC || magic == MH_MAGIC_64)
- return true;
- magic = ToBE32(magic);
- if ((magic == FAT_MAGIC) || (magic == FAT_MAGIC_64))
+ auto mh = (const mach_header*)header.GetData();
+ if (mh->magic == MH_MAGIC || mh->magic == MH_MAGIC_64)
+ {
+ // MH_FILESET is now handled by the KernelCache view instead
+ if (mh->filetype != MH_FILESET)
+ return true;
+ else
+ return false;
+ }
+ else if (mh->magic == MH_CIGAM || mh->magic == MH_CIGAM_64)
+ {
+ // MH_FILESET is now handled by the KernelCache view instead
+ if (ToBE32(mh->filetype) != MH_FILESET)
+ return true;
+ else
+ return false;
+ }
+ else if (ToBE32(mh->magic) == FAT_MAGIC || ToBE32(mh->magic) == FAT_MAGIC_64)
+ {
+ // Fat Mach-O files are valid, but have different parsing logic
return true;
-
- // If it's an MH_FILESET, return false, these are now handled by the KernelCache plugin by default
- DataBuffer header = data->ReadBuffer(data->GetStart(), sizeof(mach_header_64));
- if (header.GetLength() < sizeof(mach_header_64))
- return false;
- const mach_header_64* mh = (const mach_header_64*)header.GetData();
- uint32_t filetype = mh->magic == MH_MAGIC_64 || mh->magic == MH_MAGIC ? mh->filetype : ToBE32(mh->filetype);
- if (filetype == MH_FILESET)
- return false;
+ }
return data->GetLoadSettings(GetName()) ? true : false;
}