Skip to content

Commit 66f8244

Browse files
committed
[MachO] Add support for dylib_use_command
dylib_use_command is an extended version of dylib_command that is support from iOS 18 / macOS 15. It is indicated by the presence of a special marker value in the timestamp field of the dylib_command.
1 parent bfe165e commit 66f8244

File tree

2 files changed

+59
-5
lines changed

2 files changed

+59
-5
lines changed

macho/types.cpp

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -444,10 +444,18 @@ void CreateHeaderTypes(Ref<BinaryView> view)
444444
// clang-format on
445445
});
446446

447+
QualifiedName lcStringName("lc_str");
448+
std::string lcStringTypeId = Type::GenerateAutoTypeId("macho", lcStringName);
449+
auto lcStringType = Type::NamedType(view,
450+
view->DefineType(lcStringTypeId, lcStringName,
451+
TypeBuilder::PointerType(4, Type::IntegerType(1, true))
452+
.SetPointerBase(RelativeToVariableAddressPointerBaseType, -8)
453+
.Finalize()));
454+
447455
auto dylibType = BuildStruct(view, "dylib", false,
448456
{
449457
// clang-format off
450-
{"name", Type::IntegerType(4, false)},
458+
{"name", lcStringType},
451459
{"timestamp", Type::IntegerType(4, false)},
452460
{"current_version", Type::IntegerType(4, false)},
453461
{"compatibility_version", Type::IntegerType(4, false)}
@@ -463,6 +471,34 @@ void CreateHeaderTypes(Ref<BinaryView> view)
463471
// clang-format on
464472
});
465473

474+
auto dylibUseMarkerEnum = BuildEnum(view, "dylib_use_marker_t", 4,
475+
{
476+
{"DYLIB_USE_MARKER", DYLIB_USE_MARKER},
477+
});
478+
479+
auto dylibUseFlagsEnum = BuildEnum(view, "dylib_use_flags_t", 4,
480+
{
481+
// clang-format off
482+
{"DYLIB_USE_WEAK_LINK", DYLIB_USE_WEAK_LINK},
483+
{"DYLIB_USE_REEXPORT", DYLIB_USE_REEXPORT},
484+
{"DYLIB_USE_UPWARD", DYLIB_USE_UPWARD},
485+
{"DYLIB_USE_DELAYED_INIT", DYLIB_USE_DELAYED_INIT}
486+
// clang-format on
487+
});
488+
489+
auto dylibUseCommandType = BuildStruct(view, "dylib_use_command", false,
490+
{
491+
// clang-format off
492+
{"cmd", cmdTypeEnum},
493+
{"cmdsize", Type::IntegerType(4, false)},
494+
{"nameoff", lcStringType},
495+
{"marker", dylibUseMarkerEnum},
496+
{"current_version", Type::IntegerType(4, false)},
497+
{"compat_version", Type::IntegerType(4, false)},
498+
{"flags", dylibUseFlagsEnum}
499+
// clang-format on
500+
});
501+
466502
auto filesetEntryCommandType = BuildStruct(view, "fileset_entry_command", false,
467503
{
468504
// clang-format off
@@ -550,11 +586,22 @@ void ApplyHeaderTypes(Ref<BinaryView> view, Ref<Logger> logger, const BinaryRead
550586
case LC_REEXPORT_DYLIB:
551587
case LC_LOAD_WEAK_DYLIB:
552588
case LC_LOAD_UPWARD_DYLIB:
553-
view->DefineDataVariable(cmdAddr, Type::NamedType(view, QualifiedName("dylib_command")));
554-
if (load.cmdsize - 24 <= 150)
555-
view->DefineDataVariable(
556-
cmdAddr + 24, Type::ArrayType(Type::IntegerType(1, true), load.cmdsize - 24));
589+
{
590+
reader.SeekRelative(4);
591+
uint32_t timestamp = reader.Read32();
592+
Ref<Type> type = Type::NamedType(view, QualifiedName("dylib_command"));
593+
// A timestamp of `DYLIB_USE_MARKER` indicates this is a `dylib_use_command`.
594+
if (timestamp == DYLIB_USE_MARKER)
595+
{
596+
type = Type::NamedType(view, QualifiedName("dylib_use_command"));
597+
}
598+
view->DefineDataVariable(cmdAddr, type);
599+
600+
if (load.cmdsize - type->GetWidth() <= 150)
601+
view->DefineDataVariable(cmdAddr + type->GetWidth(),
602+
Type::ArrayType(Type::IntegerType(1, true), load.cmdsize - type->GetWidth()));
557603
break;
604+
}
558605
case LC_CODE_SIGNATURE:
559606
case LC_SEGMENT_SPLIT_INFO:
560607
case LC_FUNCTION_STARTS:

macho/types.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,13 @@ typedef int vm_prot_t;
246246
#define _MH_SIM_SUPPORT 0x08000000u
247247
#define _MH_DYLIB_IN_CACHE 0x80000000u
248248

249+
#define DYLIB_USE_WEAK_LINK 0x01
250+
#define DYLIB_USE_REEXPORT 0x02
251+
#define DYLIB_USE_UPWARD 0x04
252+
#define DYLIB_USE_DELAYED_INIT 0x08
253+
254+
#define DYLIB_USE_MARKER 0x1a741800
255+
249256
// Segment Names
250257
#define SEG_PAGEZERO "__PAGEZERO"
251258
#define SEG_TEXT "__TEXT"

0 commit comments

Comments
 (0)