From 0b0eff0cb63e36413af7e82c8983fa2fa392381b Mon Sep 17 00:00:00 2001 From: Dhash Shrivathsa Date: Sat, 10 May 2025 07:34:01 -0400 Subject: [PATCH] pattern/macho: Load Commands should include additional specializations (LoadDyLib) (#386) * add additional command specialization * address PR feedback --- patterns/macho.hexpat | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/patterns/macho.hexpat b/patterns/macho.hexpat index f6a5f96..dce0182 100644 --- a/patterns/macho.hexpat +++ b/patterns/macho.hexpat @@ -4,6 +4,7 @@ #pragma MIME application/x-mach-binary import type.size; +import std.string; enum Magic : u32 { _32BitMagic = 0xFEEDFACE, @@ -367,18 +368,44 @@ struct CommandSegment64 { u8 data[fileSize] @ fileOffset [[sealed]]; }; +struct lc_str { // NB: struct as opposed to it's union def in loader.h + u32 offset; + // It's important to note that the `ptr` field is not used in the Mach-O file itself. + // It is only relevant at runtime when the Mach-O file is loaded into memory. + // The Mach-O file uses the `offset` field to locate the string data within the file. +}; + +struct Dylib { + lc_str name; // always 24 + u32 timestamp; + u32 current_version; + u32 compatibility_version; +}; + +struct LoadDyLib { + Dylib dylib [[inline]]; +}; + struct LoadCommand { Command command; type::Size commandSize; - if (command == Command::UUID) - CommandUUID data; - else if (command == Command::Segment) - CommandSegment data; - else if (command == Command::Segment64) - CommandSegment64 data; - else - u8 data[commandSize - 8] [[sealed]]; + match (command) { + (Command::UUID): CommandUUID data; + (Command::Segment): CommandSegment data; + (Command::Segment64): CommandSegment64 data; + (Command::LoadDyLib | Command::IdDyLib | Command::LoadWeakDyLib): { + LoadDyLib dylib; + + // always 24 bytes in the struct + std::string::NullString dylib_name; + + // the 1 is the size of the string terminator + // not using align here since according to the spec this is computed + padding[commandSize - dylib.dylib.name.offset - 1 - std::string::length(dylib_name)]; + } + (_): u8 data[commandSize - 8] [[sealed]]; + } }; struct MachO {