summaryrefslogtreecommitdiff
path: root/view/sharedcache/core/DSCView.cpp
diff options
context:
space:
mode:
authorMason Reed <mason@vector35.com>2025-03-10 11:05:40 -0400
committerMason Reed <mason@vector35.com>2025-04-02 05:36:54 -0400
commit25cc02431b61097b2adfc2fbc493b648b0300c3b (patch)
treea79d9c4f4f67234d3bf9bda413e8608f479a4cc8 /view/sharedcache/core/DSCView.cpp
parentfa85bf28502286c4821427c5d0ed91a7ed46f8f6 (diff)
[SharedCache] Refactor Shared Cache
In absence of a better name, this commit refactors the shared cache code.
Diffstat (limited to 'view/sharedcache/core/DSCView.cpp')
-rw-r--r--view/sharedcache/core/DSCView.cpp771
1 files changed, 0 insertions, 771 deletions
diff --git a/view/sharedcache/core/DSCView.cpp b/view/sharedcache/core/DSCView.cpp
deleted file mode 100644
index add2faff..00000000
--- a/view/sharedcache/core/DSCView.cpp
+++ /dev/null
@@ -1,771 +0,0 @@
-//
-// Created by kat on 5/23/23.
-//
-
-/*
- * If you're here looking for the code to load caches, out of luck.
- *
- * The VIEW_NAME is essentially a blank slate that only knows how to deserialize and reserialize itself
- * based on some metadata encoded in it.
- *
- * The actual controller logic that does _all_ of the image loading is invoked via API -> SharedCache.cpp
- *
- * */
-
-#include "DSCView.h"
-#include "view/macho/machoview.h"
-#include "SharedCache.h"
-
-using namespace BinaryNinja;
-
-
-DSCView::DSCView(const std::string& typeName, BinaryView* data, bool parseOnly) :
- BinaryView(typeName, data->GetFile(), data), m_parseOnly(parseOnly)
-{
- CreateLogger("SharedCache");
- CreateLogger("SharedCache.ObjC");
-}
-
-DSCView::~DSCView()
-{
-}
-
-enum DSCPlatform {
- DSCPlatformMacOS = 1,
- DSCPlatformiOS = 2,
- DSCPlatformTVOS = 3,
- DSCPlatformWatchOS = 4,
- DSCPlatformBridgeOS = 5, // T1/T2 APL1023/T8012, this is your touchbar/touchid in intel macs. Similar to watchOS.
- // DSCPlatformMacCatalyst = 6,
- DSCPlatformiOSSimulator = 7,
- DSCPlatformTVOSSimulator = 8,
- DSCPlatformWatchOSSimulator = 9,
- DSCPlatformVisionOS = 11, // Apple Vision Pro
- DSCPlatformVisionOSSimulator = 12 // Apple Vision Pro Simulator
-};
-
-bool DSCView::Init()
-{
- std::string os;
- std::string arch;
-
- uint32_t platform;
- GetParentView()->Read(&platform, 0xd8, 4);
- char magic[17];
- GetParentView()->Read(&magic, 0, 16);
- magic[16] = 0;
- switch (platform)
- {
- case DSCPlatformMacOS:
- case DSCPlatformTVOS:
- case DSCPlatformTVOSSimulator:
- os = "mac";
- break;
- case DSCPlatformiOS:
- case DSCPlatformiOSSimulator:
- case DSCPlatformVisionOS:
- case DSCPlatformVisionOSSimulator:
- os = "ios";
- break;
- // armv7 or slide info v1 (unsupported)
- case DSCPlatformWatchOS:
- case DSCPlatformWatchOSSimulator:
- case DSCPlatformBridgeOS:
- default:
- LogError("Unknown platform: %d", platform);
- return false;
- }
-
- if (std::string(magic) == "dyld_v1 arm64" || std::string(magic) == "dyld_v1 arm64e" || std::string(magic) == "dyld_v1arm64_32")
- {
- arch = "aarch64";
- }
- else if (std::string(magic) == "dyld_v1 x86_64" || std::string(magic) == "dyld_v1 x86_64h")
- {
- arch = "x86_64";
- }
- else
- {
- LogError("Unknown magic: %s", magic);
- return false;
- }
-
- SetDefaultPlatform(Platform::GetByName(os + "-" + arch));
- SetDefaultArchitecture(Architecture::GetByName(arch));
-
- QualifiedNameAndType headerType;
- std::string err;
-
- ParseTypeString("\n"
- "\tstruct dyld_cache_header\n"
- "\t{\n"
- "\t\tchar magic[16];\t\t\t\t\t // e.g. \"dyld_v0 i386\"\n"
- "\t\tuint32_t mappingOffset;\t\t\t // file offset to first dyld_cache_mapping_info\n"
- "\t\tuint32_t mappingCount;\t\t\t // number of dyld_cache_mapping_info entries\n"
- "\t\tuint32_t imagesOffsetOld;\t\t // UNUSED: moved to imagesOffset to prevent older dsc_extarctors from crashing\n"
- "\t\tuint32_t imagesCountOld;\t\t // UNUSED: moved to imagesCount to prevent older dsc_extarctors from crashing\n"
- "\t\tuint64_t dyldBaseAddress;\t\t // base address of dyld when cache was built\n"
- "\t\tuint64_t codeSignatureOffset;\t // file offset of code signature blob\n"
- "\t\tuint64_t codeSignatureSize;\t\t // size of code signature blob (zero means to end of file)\n"
- "\t\tuint64_t slideInfoOffsetUnused;\t // unused. Used to be file offset of kernel slid info\n"
- "\t\tuint64_t slideInfoSizeUnused;\t // unused. Used to be size of kernel slid info\n"
- "\t\tuint64_t localSymbolsOffset;\t // file offset of where local symbols are stored\n"
- "\t\tuint64_t localSymbolsSize;\t\t // size of local symbols information\n"
- "\t\tuint8_t uuid[16];\t\t\t\t // unique value for each shared cache file\n"
- "\t\tuint64_t cacheType;\t\t\t\t // 0 for development, 1 for production // Kat: , 2 for iOS 16?\n"
- "\t\tuint32_t branchPoolsOffset;\t\t // file offset to table of uint64_t pool addresses\n"
- "\t\tuint32_t branchPoolsCount;\t\t // number of uint64_t entries\n"
- "\t\tuint64_t accelerateInfoAddr;\t // (unslid) address of optimization info\n"
- "\t\tuint64_t accelerateInfoSize;\t // size of optimization info\n"
- "\t\tuint64_t imagesTextOffset;\t\t // file offset to first dyld_cache_image_text_info\n"
- "\t\tuint64_t imagesTextCount;\t\t // number of dyld_cache_image_text_info entries\n"
- "\t\tuint64_t patchInfoAddr;\t\t\t // (unslid) address of dyld_cache_patch_info\n"
- "\t\tuint64_t patchInfoSize;\t // Size of all of the patch information pointed to via the dyld_cache_patch_info\n"
- "\t\tuint64_t otherImageGroupAddrUnused;\t // unused\n"
- "\t\tuint64_t otherImageGroupSizeUnused;\t // unused\n"
- "\t\tuint64_t progClosuresAddr;\t\t\t // (unslid) address of list of program launch closures\n"
- "\t\tuint64_t progClosuresSize;\t\t\t // size of list of program launch closures\n"
- "\t\tuint64_t progClosuresTrieAddr;\t\t // (unslid) address of trie of indexes into program launch closures\n"
- "\t\tuint64_t progClosuresTrieSize;\t\t // size of trie of indexes into program launch closures\n"
- "\t\tuint32_t platform;\t\t\t\t\t // platform number (macOS=1, etc)\n"
- "\t\tuint32_t formatVersion : 8,\t\t\t // dyld3::closure::kFormatVersion\n"
- "\t\t\tdylibsExpectedOnDisk : 1, // dyld should expect the dylib exists on disk and to compare inode/mtime to see if cache is valid\n"
- "\t\t\tsimulator : 1,\t\t\t // for simulator of specified platform\n"
- "\t\t\tlocallyBuiltCache : 1,\t // 0 for B&I built cache, 1 for locally built cache\n"
- "\t\t\tbuiltFromChainedFixups : 1,\t // some dylib in cache was built using chained fixups, so patch tables must be used for overrides\n"
- "\t\t\tpadding : 20;\t\t\t\t // TBD\n"
- "\t\tuint64_t sharedRegionStart;\t\t // base load address of cache if not slid\n"
- "\t\tuint64_t sharedRegionSize;\t\t // overall size required to map the cache and all subCaches, if any\n"
- "\t\tuint64_t maxSlide;\t\t\t\t // runtime slide of cache can be between zero and this value\n"
- "\t\tuint64_t dylibsImageArrayAddr;\t // (unslid) address of ImageArray for dylibs in this cache\n"
- "\t\tuint64_t dylibsImageArraySize;\t // size of ImageArray for dylibs in this cache\n"
- "\t\tuint64_t dylibsTrieAddr;\t\t // (unslid) address of trie of indexes of all cached dylibs\n"
- "\t\tuint64_t dylibsTrieSize;\t\t // size of trie of cached dylib paths\n"
- "\t\tuint64_t otherImageArrayAddr;\t // (unslid) address of ImageArray for dylibs and bundles with dlopen closures\n"
- "\t\tuint64_t otherImageArraySize;\t // size of ImageArray for dylibs and bundles with dlopen closures\n"
- "\t\tuint64_t otherTrieAddr;\t // (unslid) address of trie of indexes of all dylibs and bundles with dlopen closures\n"
- "\t\tuint64_t otherTrieSize;\t // size of trie of dylibs and bundles with dlopen closures\n"
- "\t\tuint32_t mappingWithSlideOffset;\t\t // file offset to first dyld_cache_mapping_and_slide_info\n"
- "\t\tuint32_t mappingWithSlideCount;\t\t\t // number of dyld_cache_mapping_and_slide_info entries\n"
- "\t\tuint64_t dylibsPBLStateArrayAddrUnused;\t // unused\n"
- "\t\tuint64_t dylibsPBLSetAddr;\t\t\t\t // (unslid) address of PrebuiltLoaderSet of all cached dylibs\n"
- "\t\tuint64_t programsPBLSetPoolAddr;\t\t // (unslid) address of pool of PrebuiltLoaderSet for each program\n"
- "\t\tuint64_t programsPBLSetPoolSize;\t\t // size of pool of PrebuiltLoaderSet for each program\n"
- "\t\tuint64_t programTrieAddr;\t\t\t\t // (unslid) address of trie mapping program path to PrebuiltLoaderSet\n"
- "\t\tuint32_t programTrieSize;\n"
- "\t\tuint32_t osVersion;\t\t\t\t// OS Version of dylibs in this cache for the main platform\n"
- "\t\tuint32_t altPlatform;\t\t\t// e.g. iOSMac on macOS\n"
- "\t\tuint32_t altOsVersion;\t\t\t// e.g. 14.0 for iOSMac\n"
- "\t\tuint64_t swiftOptsOffset;\t\t// file offset to Swift optimizations header\n"
- "\t\tuint64_t swiftOptsSize;\t\t\t// size of Swift optimizations header\n"
- "\t\tuint32_t subCacheArrayOffset;\t// file offset to first dyld_subcache_entry\n"
- "\t\tuint32_t subCacheArrayCount;\t// number of subCache entries\n"
- "\t\tuint8_t symbolFileUUID[16];\t\t// unique value for the shared cache file containing unmapped local symbols\n"
- "\t\tuint64_t rosettaReadOnlyAddr;\t// (unslid) address of the start of where Rosetta can add read-only/executable data\n"
- "\t\tuint64_t rosettaReadOnlySize;\t// maximum size of the Rosetta read-only/executable region\n"
- "\t\tuint64_t rosettaReadWriteAddr;\t// (unslid) address of the start of where Rosetta can add read-write data\n"
- "\t\tuint64_t rosettaReadWriteSize;\t// maximum size of the Rosetta read-write region\n"
- "\t\tuint32_t imagesOffset;\t\t\t// file offset to first dyld_cache_image_info\n"
- "\t\tuint32_t imagesCount;\t\t\t// number of dyld_cache_image_info entries\n"
- "\t\tuint32_t cacheSubType; // 0 for development, 1 for production, when cacheType is multi-cache(2)\n"
- "\t\tuint64_t objcOptsOffset; // VM offset from cache_header* to ObjC optimizations header\n"
- "\t\tuint64_t objcOptsSize; // size of ObjC optimizations header\n"
- "\t\tuint64_t cacheAtlasOffset; // VM offset from cache_header* to embedded cache atlas for process introspection\n"
- "\t\tuint64_t cacheAtlasSize; // size of embedded cache atlas\n"
- "\t\tuint64_t dynamicDataOffset; // VM offset from cache_header* to the location of dyld_cache_dynamic_data_header\n"
- "\t\tuint64_t dynamicDataMaxSize; // maximum size of space reserved from dynamic data\n"
- "\t\tuint32_t tproMappingsOffset; // file offset to first dyld_cache_tpro_mapping_info\n"
- "\t\tuint32_t tproMappingsCount; // number of dyld_cache_tpro_mapping_info entries\n"
- "\t};", headerType, err);
-
- if (!err.empty() || !headerType.type)
- {
- LogError("Failed to parse header type: %s", err.c_str());
- return false;
- }
-
- Ref<Settings> settings = GetLoadSettings(GetTypeName());
-
- if (!settings)
- {
- Ref<Settings> programSettings = Settings::Instance();
- programSettings->Set("analysis.workflows.functionWorkflow", "core.function.dsc", this);
- }
-
- if (m_parseOnly)
- return true;
-
- // Check the metadata version if there is one, so we can alert the user to why they have no loaded images.
- // TODO: Once the view is able to be exited early we should offer to close the view if the user does not want to upgrade.
- auto metadataVersion = SharedCacheCore::SharedCacheMetadata::ViewMetadataVersion(GetParentView());
- if (metadataVersion.has_value() && metadataVersion.value() != METADATA_VERSION)
- {
- ShowMessageBox("Invalid Shared Cache Metadata!", "The BNDB shared cache metadata was created with a different version of the Shared Cache view, to continue the metadata has to be recreated. You will need to add your images back again.");
- }
-
- // Add Mach-O file header type info
- EnumerationBuilder cpuTypeBuilder;
- cpuTypeBuilder.AddMemberWithValue("CPU_TYPE_ANY", MACHO_CPU_TYPE_ANY);
- cpuTypeBuilder.AddMemberWithValue("CPU_TYPE_VAX", MACHO_CPU_TYPE_VAX);
- cpuTypeBuilder.AddMemberWithValue("CPU_TYPE_MC680x0", MACHO_CPU_TYPE_MC680x0);
- cpuTypeBuilder.AddMemberWithValue("CPU_TYPE_X86", MACHO_CPU_TYPE_X86);
- cpuTypeBuilder.AddMemberWithValue("CPU_TYPE_X86_64", MACHO_CPU_TYPE_X86_64);
- cpuTypeBuilder.AddMemberWithValue("CPU_TYPE_MIPS", MACHO_CPU_TYPE_MIPS);
- cpuTypeBuilder.AddMemberWithValue("CPU_TYPE_MC98000", MACHO_CPU_TYPE_MC98000);
- cpuTypeBuilder.AddMemberWithValue("CPU_TYPE_HPPA", MACHO_CPU_TYPE_HPPA);
- cpuTypeBuilder.AddMemberWithValue("CPU_TYPE_ARM", MACHO_CPU_TYPE_ARM);
- cpuTypeBuilder.AddMemberWithValue("CPU_TYPE_ARM64", MACHO_CPU_TYPE_ARM64);
- cpuTypeBuilder.AddMemberWithValue("CPU_TYPE_ARM64_32", MACHO_CPU_TYPE_ARM64_32);
- cpuTypeBuilder.AddMemberWithValue("CPU_TYPE_MC88000", MACHO_CPU_TYPE_MC88000);
- cpuTypeBuilder.AddMemberWithValue("CPU_TYPE_SPARC", MACHO_CPU_TYPE_SPARC);
- cpuTypeBuilder.AddMemberWithValue("CPU_TYPE_I860", MACHO_CPU_TYPE_I860);
- cpuTypeBuilder.AddMemberWithValue("CPU_TYPE_ALPHA", MACHO_CPU_TYPE_ALPHA);
- cpuTypeBuilder.AddMemberWithValue("CPU_TYPE_POWERPC", MACHO_CPU_TYPE_POWERPC);
- cpuTypeBuilder.AddMemberWithValue("CPU_TYPE_POWERPC64", MACHO_CPU_TYPE_POWERPC64);
- Ref<Enumeration> cpuTypeEnum = cpuTypeBuilder.Finalize();
-
- Ref<Type> cpuTypeEnumType = Type::EnumerationType(nullptr, cpuTypeEnum, 4, false);
- std::string cpuTypeEnumName = "cpu_type_t";
- std::string cpuTypeEnumId = Type::GenerateAutoTypeId("macho", cpuTypeEnumName);
- DefineType(cpuTypeEnumId, cpuTypeEnumName, cpuTypeEnumType);
-
- EnumerationBuilder fileTypeBuilder;
- fileTypeBuilder.AddMemberWithValue("MH_OBJECT", MH_OBJECT);
- fileTypeBuilder.AddMemberWithValue("MH_EXECUTE", MH_EXECUTE);
- fileTypeBuilder.AddMemberWithValue("MH_FVMLIB", MH_FVMLIB);
- fileTypeBuilder.AddMemberWithValue("MH_CORE", MH_CORE);
- fileTypeBuilder.AddMemberWithValue("MH_PRELOAD", MH_PRELOAD);
- fileTypeBuilder.AddMemberWithValue("MH_DYLIB", MH_DYLIB);
- fileTypeBuilder.AddMemberWithValue("MH_DYLINKER", MH_DYLINKER);
- fileTypeBuilder.AddMemberWithValue("MH_BUNDLE", MH_BUNDLE);
- fileTypeBuilder.AddMemberWithValue("MH_DYLIB_STUB", MH_DYLIB_STUB);
- fileTypeBuilder.AddMemberWithValue("MH_DSYM", MH_DSYM);
- fileTypeBuilder.AddMemberWithValue("MH_KEXT_BUNDLE", MH_KEXT_BUNDLE);
- fileTypeBuilder.AddMemberWithValue("MH_FILESET", MH_FILESET);
- Ref<Enumeration> fileTypeEnum = fileTypeBuilder.Finalize();
-
- Ref<Type> fileTypeEnumType = Type::EnumerationType(nullptr, fileTypeEnum, 4, false);
- std::string fileTypeEnumName = "file_type_t";
- std::string fileTypeEnumId = Type::GenerateAutoTypeId("macho", fileTypeEnumName);
- DefineType(fileTypeEnumId, fileTypeEnumName, fileTypeEnumType);
-
- EnumerationBuilder flagsTypeBuilder;
- flagsTypeBuilder.AddMemberWithValue("MH_NOUNDEFS", MH_NOUNDEFS);
- flagsTypeBuilder.AddMemberWithValue("MH_INCRLINK", MH_INCRLINK);
- flagsTypeBuilder.AddMemberWithValue("MH_DYLDLINK", MH_DYLDLINK);
- flagsTypeBuilder.AddMemberWithValue("MH_BINDATLOAD", MH_BINDATLOAD);
- flagsTypeBuilder.AddMemberWithValue("MH_PREBOUND", MH_PREBOUND);
- flagsTypeBuilder.AddMemberWithValue("MH_SPLIT_SEGS", MH_SPLIT_SEGS);
- flagsTypeBuilder.AddMemberWithValue("MH_LAZY_INIT", MH_LAZY_INIT);
- flagsTypeBuilder.AddMemberWithValue("MH_TWOLEVEL", MH_TWOLEVEL);
- flagsTypeBuilder.AddMemberWithValue("MH_FORCE_FLAT", MH_FORCE_FLAT);
- flagsTypeBuilder.AddMemberWithValue("MH_NOMULTIDEFS", MH_NOMULTIDEFS);
- flagsTypeBuilder.AddMemberWithValue("MH_NOFIXPREBINDING", MH_NOFIXPREBINDING);
- flagsTypeBuilder.AddMemberWithValue("MH_PREBINDABLE", MH_PREBINDABLE);
- flagsTypeBuilder.AddMemberWithValue("MH_ALLMODSBOUND", MH_ALLMODSBOUND);
- flagsTypeBuilder.AddMemberWithValue("MH_SUBSECTIONS_VIA_SYMBOLS", MH_SUBSECTIONS_VIA_SYMBOLS);
- flagsTypeBuilder.AddMemberWithValue("MH_CANONICAL", MH_CANONICAL);
- flagsTypeBuilder.AddMemberWithValue("MH_WEAK_DEFINES", MH_WEAK_DEFINES);
- flagsTypeBuilder.AddMemberWithValue("MH_BINDS_TO_WEAK", MH_BINDS_TO_WEAK);
- flagsTypeBuilder.AddMemberWithValue("MH_ALLOW_STACK_EXECUTION", MH_ALLOW_STACK_EXECUTION);
- flagsTypeBuilder.AddMemberWithValue("MH_ROOT_SAFE", MH_ROOT_SAFE);
- flagsTypeBuilder.AddMemberWithValue("MH_SETUID_SAFE", MH_SETUID_SAFE);
- flagsTypeBuilder.AddMemberWithValue("MH_NO_REEXPORTED_DYLIBS", MH_NO_REEXPORTED_DYLIBS);
- flagsTypeBuilder.AddMemberWithValue("MH_PIE", MH_PIE);
- flagsTypeBuilder.AddMemberWithValue("MH_DEAD_STRIPPABLE_DYLIB", MH_DEAD_STRIPPABLE_DYLIB);
- flagsTypeBuilder.AddMemberWithValue("MH_HAS_TLV_DESCRIPTORS", MH_HAS_TLV_DESCRIPTORS);
- flagsTypeBuilder.AddMemberWithValue("MH_NO_HEAP_EXECUTION", MH_NO_HEAP_EXECUTION);
- flagsTypeBuilder.AddMemberWithValue("MH_APP_EXTENSION_SAFE", _MH_APP_EXTENSION_SAFE);
- flagsTypeBuilder.AddMemberWithValue("MH_NLIST_OUTOFSYNC_WITH_DYLDINFO", _MH_NLIST_OUTOFSYNC_WITH_DYLDINFO);
- flagsTypeBuilder.AddMemberWithValue("MH_SIM_SUPPORT", _MH_SIM_SUPPORT);
- flagsTypeBuilder.AddMemberWithValue("MH_DYLIB_IN_CACHE", _MH_DYLIB_IN_CACHE);
- Ref<Enumeration> flagsTypeEnum = flagsTypeBuilder.Finalize();
-
- Ref<Type> flagsTypeEnumType = Type::EnumerationType(nullptr, flagsTypeEnum, 4, false);
- std::string flagsTypeEnumName = "flags_type_t";
- std::string flagsTypeEnumId = Type::GenerateAutoTypeId("macho", flagsTypeEnumName);
- DefineType(flagsTypeEnumId, flagsTypeEnumName, flagsTypeEnumType);
-
- StructureBuilder machoHeaderBuilder;
- machoHeaderBuilder.AddMember(Type::IntegerType(4, false), "magic");
- machoHeaderBuilder.AddMember(Type::NamedType(this, QualifiedName("cpu_type_t")), "cputype");
- machoHeaderBuilder.AddMember(Type::IntegerType(4, false), "cpusubtype");
- machoHeaderBuilder.AddMember(Type::NamedType(this, QualifiedName("file_type_t")), "filetype");
- machoHeaderBuilder.AddMember(Type::IntegerType(4, false), "ncmds");
- machoHeaderBuilder.AddMember(Type::IntegerType(4, false), "sizeofcmds");
- machoHeaderBuilder.AddMember(Type::NamedType(this, QualifiedName("flags_type_t")), "flags");
- if (GetAddressSize() == 8)
- machoHeaderBuilder.AddMember(Type::IntegerType(4, false), "reserved");
- Ref<Structure> machoHeaderStruct = machoHeaderBuilder.Finalize();
- QualifiedName headerName = (GetAddressSize() == 8) ? std::string("mach_header_64") : std::string("mach_header");
-
- std::string headerTypeId = Type::GenerateAutoTypeId("macho", headerName);
- Ref<Type> machoHeaderType = Type::StructureType(machoHeaderStruct);
- DefineType(headerTypeId, headerName, machoHeaderType);
-
- EnumerationBuilder cmdTypeBuilder;
- cmdTypeBuilder.AddMemberWithValue("LC_REQ_DYLD", LC_REQ_DYLD);
- cmdTypeBuilder.AddMemberWithValue("LC_SEGMENT", LC_SEGMENT);
- cmdTypeBuilder.AddMemberWithValue("LC_SYMTAB", LC_SYMTAB);
- cmdTypeBuilder.AddMemberWithValue("LC_SYMSEG", LC_SYMSEG);
- cmdTypeBuilder.AddMemberWithValue("LC_THREAD", LC_THREAD);
- cmdTypeBuilder.AddMemberWithValue("LC_UNIXTHREAD", LC_UNIXTHREAD);
- cmdTypeBuilder.AddMemberWithValue("LC_LOADFVMLIB", LC_LOADFVMLIB);
- cmdTypeBuilder.AddMemberWithValue("LC_IDFVMLIB", LC_IDFVMLIB);
- cmdTypeBuilder.AddMemberWithValue("LC_IDENT", LC_IDENT);
- cmdTypeBuilder.AddMemberWithValue("LC_FVMFILE", LC_FVMFILE);
- cmdTypeBuilder.AddMemberWithValue("LC_PREPAGE", LC_PREPAGE);
- cmdTypeBuilder.AddMemberWithValue("LC_DYSYMTAB", LC_DYSYMTAB);
- cmdTypeBuilder.AddMemberWithValue("LC_LOAD_DYLIB", LC_LOAD_DYLIB);
- cmdTypeBuilder.AddMemberWithValue("LC_ID_DYLIB", LC_ID_DYLIB);
- cmdTypeBuilder.AddMemberWithValue("LC_LOAD_DYLINKER", LC_LOAD_DYLINKER);
- cmdTypeBuilder.AddMemberWithValue("LC_ID_DYLINKER", LC_ID_DYLINKER);
- cmdTypeBuilder.AddMemberWithValue("LC_PREBOUND_DYLIB", LC_PREBOUND_DYLIB);
- cmdTypeBuilder.AddMemberWithValue("LC_ROUTINES", LC_ROUTINES);
- cmdTypeBuilder.AddMemberWithValue("LC_SUB_FRAMEWORK", LC_SUB_FRAMEWORK);
- cmdTypeBuilder.AddMemberWithValue("LC_SUB_UMBRELLA", LC_SUB_UMBRELLA);
- cmdTypeBuilder.AddMemberWithValue("LC_SUB_CLIENT", LC_SUB_CLIENT);
- cmdTypeBuilder.AddMemberWithValue("LC_SUB_LIBRARY", LC_SUB_LIBRARY);
- cmdTypeBuilder.AddMemberWithValue("LC_TWOLEVEL_HINTS", LC_TWOLEVEL_HINTS);
- cmdTypeBuilder.AddMemberWithValue("LC_PREBIND_CKSUM", LC_PREBIND_CKSUM);
- cmdTypeBuilder.AddMemberWithValue("LC_LOAD_WEAK_DYLIB", LC_LOAD_WEAK_DYLIB); // (0x18 | LC_REQ_DYLD)
- cmdTypeBuilder.AddMemberWithValue("LC_SEGMENT_64", LC_SEGMENT_64);
- cmdTypeBuilder.AddMemberWithValue("LC_ROUTINES_64", LC_ROUTINES_64);
- cmdTypeBuilder.AddMemberWithValue("LC_UUID", LC_UUID);
- cmdTypeBuilder.AddMemberWithValue("LC_RPATH", LC_RPATH); // (0x1c | LC_REQ_DYLD)
- cmdTypeBuilder.AddMemberWithValue("LC_CODE_SIGNATURE", LC_CODE_SIGNATURE);
- cmdTypeBuilder.AddMemberWithValue("LC_SEGMENT_SPLIT_INFO", LC_SEGMENT_SPLIT_INFO);
- cmdTypeBuilder.AddMemberWithValue("LC_REEXPORT_DYLIB", LC_REEXPORT_DYLIB); // (0x1f | LC_REQ_DYLD)
- cmdTypeBuilder.AddMemberWithValue("LC_LAZY_LOAD_DYLIB", LC_LAZY_LOAD_DYLIB);
- cmdTypeBuilder.AddMemberWithValue("LC_ENCRYPTION_INFO", LC_ENCRYPTION_INFO);
- cmdTypeBuilder.AddMemberWithValue("LC_DYLD_INFO", LC_DYLD_INFO);
- cmdTypeBuilder.AddMemberWithValue("LC_DYLD_INFO_ONLY", LC_DYLD_INFO_ONLY); // (0x22 | LC_REQ_DYLD)
- cmdTypeBuilder.AddMemberWithValue("LC_LOAD_UPWARD_DYLIB", LC_LOAD_UPWARD_DYLIB); // (0x23 | LC_REQ_DYLD)
- cmdTypeBuilder.AddMemberWithValue("LC_VERSION_MIN_MACOSX", LC_VERSION_MIN_MACOSX);
- cmdTypeBuilder.AddMemberWithValue("LC_VERSION_MIN_IPHONEOS", LC_VERSION_MIN_IPHONEOS);
- cmdTypeBuilder.AddMemberWithValue("LC_FUNCTION_STARTS", LC_FUNCTION_STARTS);
- cmdTypeBuilder.AddMemberWithValue("LC_DYLD_ENVIRONMENT", LC_DYLD_ENVIRONMENT);
- cmdTypeBuilder.AddMemberWithValue("LC_MAIN", LC_MAIN); // (0x28 | LC_REQ_DYLD)
- cmdTypeBuilder.AddMemberWithValue("LC_DATA_IN_CODE", LC_DATA_IN_CODE);
- cmdTypeBuilder.AddMemberWithValue("LC_SOURCE_VERSION", LC_SOURCE_VERSION);
- cmdTypeBuilder.AddMemberWithValue("LC_DYLIB_CODE_SIGN_DRS", LC_DYLIB_CODE_SIGN_DRS);
- cmdTypeBuilder.AddMemberWithValue("LC_ENCRYPTION_INFO_64", _LC_ENCRYPTION_INFO_64);
- cmdTypeBuilder.AddMemberWithValue("LC_LINKER_OPTION", _LC_LINKER_OPTION);
- cmdTypeBuilder.AddMemberWithValue("LC_LINKER_OPTIMIZATION_HINT", _LC_LINKER_OPTIMIZATION_HINT);
- cmdTypeBuilder.AddMemberWithValue("LC_VERSION_MIN_TVOS", _LC_VERSION_MIN_TVOS);
- cmdTypeBuilder.AddMemberWithValue("LC_VERSION_MIN_WATCHOS", LC_VERSION_MIN_WATCHOS);
- cmdTypeBuilder.AddMemberWithValue("LC_NOTE", LC_NOTE);
- cmdTypeBuilder.AddMemberWithValue("LC_BUILD_VERSION", LC_BUILD_VERSION);
- cmdTypeBuilder.AddMemberWithValue("LC_DYLD_EXPORTS_TRIE", LC_DYLD_EXPORTS_TRIE);
- cmdTypeBuilder.AddMemberWithValue("LC_DYLD_CHAINED_FIXUPS", LC_DYLD_CHAINED_FIXUPS);
- cmdTypeBuilder.AddMemberWithValue("LC_FILESET_ENTRY", LC_FILESET_ENTRY);
- Ref<Enumeration> cmdTypeEnum = cmdTypeBuilder.Finalize();
-
- Ref<Type> cmdTypeEnumType = Type::EnumerationType(nullptr, cmdTypeEnum, 4, false);
- std::string cmdTypeEnumName = "load_command_type_t";
- std::string cmdTypeEnumId = Type::GenerateAutoTypeId("macho", cmdTypeEnumName);
- DefineType(cmdTypeEnumId, cmdTypeEnumName, cmdTypeEnumType);
-
- StructureBuilder loadCommandBuilder;
- loadCommandBuilder.AddMember(Type::NamedType(this, QualifiedName("load_command_type_t")), "cmd");
- loadCommandBuilder.AddMember(Type::IntegerType(4, false), "cmdsize");
- Ref<Structure> loadCommandStruct = loadCommandBuilder.Finalize();
- QualifiedName loadCommandName = std::string("load_command");
- std::string loadCommandTypeId = Type::GenerateAutoTypeId("macho", loadCommandName);
- Ref<Type> loadCommandType = Type::StructureType(loadCommandStruct);
- DefineType(loadCommandTypeId, loadCommandName, loadCommandType);
-
- EnumerationBuilder protTypeBuilder;
- protTypeBuilder.AddMemberWithValue("VM_PROT_NONE", MACHO_VM_PROT_NONE);
- protTypeBuilder.AddMemberWithValue("VM_PROT_READ", MACHO_VM_PROT_READ);
- protTypeBuilder.AddMemberWithValue("VM_PROT_WRITE", MACHO_VM_PROT_WRITE);
- protTypeBuilder.AddMemberWithValue("VM_PROT_EXECUTE", MACHO_VM_PROT_EXECUTE);
- // protTypeBuilder.AddMemberWithValue("VM_PROT_DEFAULT", MACHO_VM_PROT_DEFAULT);
- // protTypeBuilder.AddMemberWithValue("VM_PROT_ALL", MACHO_VM_PROT_ALL);
- protTypeBuilder.AddMemberWithValue("VM_PROT_NO_CHANGE", MACHO_VM_PROT_NO_CHANGE);
- protTypeBuilder.AddMemberWithValue("VM_PROT_COPY_OR_WANTS_COPY", MACHO_VM_PROT_COPY);
- // protTypeBuilder.AddMemberWithValue("VM_PROT_WANTS_COPY", MACHO_VM_PROT_WANTS_COPY);
- Ref<Enumeration> protTypeEnum = protTypeBuilder.Finalize();
-
- Ref<Type> protTypeEnumType = Type::EnumerationType(nullptr, protTypeEnum, 4, false);
- std::string protTypeEnumName = "vm_prot_t";
- std::string protTypeEnumId = Type::GenerateAutoTypeId("macho", protTypeEnumName);
- DefineType(protTypeEnumId, protTypeEnumName, protTypeEnumType);
-
- EnumerationBuilder segFlagsTypeBuilder;
- segFlagsTypeBuilder.AddMemberWithValue("SG_HIGHVM", SG_HIGHVM);
- segFlagsTypeBuilder.AddMemberWithValue("SG_FVMLIB", SG_FVMLIB);
- segFlagsTypeBuilder.AddMemberWithValue("SG_NORELOC", SG_NORELOC);
- segFlagsTypeBuilder.AddMemberWithValue("SG_PROTECTED_VERSION_1", SG_PROTECTED_VERSION_1);
- Ref<Enumeration> segFlagsTypeEnum = segFlagsTypeBuilder.Finalize();
-
- Ref<Type> segFlagsTypeEnumType = Type::EnumerationType(nullptr, segFlagsTypeEnum, 4, false);
- std::string segFlagsTypeEnumName = "sg_flags_t";
- std::string segFlagsTypeEnumId = Type::GenerateAutoTypeId("macho", segFlagsTypeEnumName);
- DefineType(segFlagsTypeEnumId, segFlagsTypeEnumName, segFlagsTypeEnumType);
-
- StructureBuilder loadSegmentCommandBuilder;
- loadSegmentCommandBuilder.AddMember(Type::NamedType(this, QualifiedName("load_command_type_t")), "cmd");
- loadSegmentCommandBuilder.AddMember(Type::IntegerType(4, false), "cmdsize");
- loadSegmentCommandBuilder.AddMember(Type::ArrayType(Type::IntegerType(1, true), 16), "segname");
- loadSegmentCommandBuilder.AddMember(Type::IntegerType(4, false), "vmaddr");
- loadSegmentCommandBuilder.AddMember(Type::IntegerType(4, false), "vmsize");
- loadSegmentCommandBuilder.AddMember(Type::IntegerType(4, false), "fileoff");
- loadSegmentCommandBuilder.AddMember(Type::IntegerType(4, false), "filesize");
- loadSegmentCommandBuilder.AddMember(Type::NamedType(this, QualifiedName("vm_prot_t")), "maxprot");
- loadSegmentCommandBuilder.AddMember(Type::NamedType(this, QualifiedName("vm_prot_t")), "initprot");
- loadSegmentCommandBuilder.AddMember(Type::IntegerType(4, false), "nsects");
- loadSegmentCommandBuilder.AddMember(Type::NamedType(this, QualifiedName("sg_flags_t")), "flags");
- Ref<Structure> loadSegmentCommandStruct = loadSegmentCommandBuilder.Finalize();
- QualifiedName loadSegmentCommandName = std::string("segment_command");
- std::string loadSegmentCommandTypeId = Type::GenerateAutoTypeId("macho", loadSegmentCommandName);
- Ref<Type> loadSegmentCommandType = Type::StructureType(loadSegmentCommandStruct);
- DefineType(loadSegmentCommandTypeId, loadSegmentCommandName, loadSegmentCommandType);
-
- StructureBuilder loadSegmentCommand64Builder;
- loadSegmentCommand64Builder.AddMember(Type::NamedType(this, QualifiedName("load_command_type_t")), "cmd");
- loadSegmentCommand64Builder.AddMember(Type::IntegerType(4, false), "cmdsize");
- loadSegmentCommand64Builder.AddMember(Type::ArrayType(Type::IntegerType(1, true), 16), "segname");
- loadSegmentCommand64Builder.AddMember(Type::IntegerType(8, false), "vmaddr");
- loadSegmentCommand64Builder.AddMember(Type::IntegerType(8, false), "vmsize");
- loadSegmentCommand64Builder.AddMember(Type::IntegerType(8, false), "fileoff");
- loadSegmentCommand64Builder.AddMember(Type::IntegerType(8, false), "filesize");
- loadSegmentCommand64Builder.AddMember(Type::NamedType(this, QualifiedName("vm_prot_t")), "maxprot");
- loadSegmentCommand64Builder.AddMember(Type::NamedType(this, QualifiedName("vm_prot_t")), "initprot");
- loadSegmentCommand64Builder.AddMember(Type::IntegerType(4, false), "nsects");
- loadSegmentCommand64Builder.AddMember(Type::NamedType(this, QualifiedName("sg_flags_t")), "flags");
- Ref<Structure> loadSegmentCommand64Struct = loadSegmentCommand64Builder.Finalize();
- QualifiedName loadSegment64CommandName = std::string("segment_command_64");
- std::string loadSegment64CommandTypeId = Type::GenerateAutoTypeId("macho", loadSegment64CommandName);
- Ref<Type> loadSegment64CommandType = Type::StructureType(loadSegmentCommand64Struct);
- DefineType(loadSegment64CommandTypeId, loadSegment64CommandName, loadSegment64CommandType);
-
- StructureBuilder sectionBuilder;
- sectionBuilder.AddMember(Type::ArrayType(Type::IntegerType(1, true), 16), "sectname");
- sectionBuilder.AddMember(Type::ArrayType(Type::IntegerType(1, true), 16), "segname");
- sectionBuilder.AddMember(Type::IntegerType(4, false), "addr");
- sectionBuilder.AddMember(Type::IntegerType(4, false), "size");
- sectionBuilder.AddMember(Type::IntegerType(4, false), "offset");
- sectionBuilder.AddMember(Type::IntegerType(4, false), "align");
- sectionBuilder.AddMember(Type::IntegerType(4, false), "reloff");
- sectionBuilder.AddMember(Type::IntegerType(4, false), "nreloc");
- sectionBuilder.AddMember(Type::IntegerType(4, false), "flags");
- sectionBuilder.AddMember(Type::IntegerType(4, false), "reserved1");
- sectionBuilder.AddMember(Type::IntegerType(4, false), "reserved2");
- Ref<Structure> sectionStruct = sectionBuilder.Finalize();
- QualifiedName sectionName = std::string("section");
- std::string sectionTypeId = Type::GenerateAutoTypeId("macho", sectionName);
- Ref<Type> sectionType = Type::StructureType(sectionStruct);
- DefineType(sectionTypeId, sectionName, sectionType);
-
- StructureBuilder section64Builder;
- section64Builder.AddMember(Type::ArrayType(Type::IntegerType(1, true), 16), "sectname");
- section64Builder.AddMember(Type::ArrayType(Type::IntegerType(1, true), 16), "segname");
- section64Builder.AddMember(Type::IntegerType(8, false), "addr");
- section64Builder.AddMember(Type::IntegerType(8, false), "size");
- section64Builder.AddMember(Type::IntegerType(4, false), "offset");
- section64Builder.AddMember(Type::IntegerType(4, false), "align");
- section64Builder.AddMember(Type::IntegerType(4, false), "reloff");
- section64Builder.AddMember(Type::IntegerType(4, false), "nreloc");
- section64Builder.AddMember(Type::IntegerType(4, false), "flags");
- section64Builder.AddMember(Type::IntegerType(4, false), "reserved1");
- section64Builder.AddMember(Type::IntegerType(4, false), "reserved2");
- section64Builder.AddMember(Type::IntegerType(4, false), "reserved3");
- Ref<Structure> section64Struct = section64Builder.Finalize();
- QualifiedName section64Name = std::string("section_64");
- std::string section64TypeId = Type::GenerateAutoTypeId("macho", section64Name);
- Ref<Type> section64Type = Type::StructureType(section64Struct);
- DefineType(section64TypeId, section64Name, section64Type);
-
- StructureBuilder symtabBuilder;
- symtabBuilder.AddMember(Type::NamedType(this, QualifiedName("load_command_type_t")), "cmd");
- symtabBuilder.AddMember(Type::IntegerType(4, false), "cmdsize");
- symtabBuilder.AddMember(Type::IntegerType(4, false), "symoff");
- symtabBuilder.AddMember(Type::IntegerType(4, false), "nsyms");
- symtabBuilder.AddMember(Type::IntegerType(4, false), "stroff");
- symtabBuilder.AddMember(Type::IntegerType(4, false), "strsize");
- Ref<Structure> symtabStruct = symtabBuilder.Finalize();
- QualifiedName symtabName = std::string("symtab");
- std::string symtabTypeId = Type::GenerateAutoTypeId("macho", symtabName);
- Ref<Type> symtabType = Type::StructureType(symtabStruct);
- DefineType(symtabTypeId, symtabName, symtabType);
-
- StructureBuilder dynsymtabBuilder;
- dynsymtabBuilder.AddMember(Type::NamedType(this, QualifiedName("load_command_type_t")), "cmd");
- dynsymtabBuilder.AddMember(Type::IntegerType(4, false), "cmdsize");
- dynsymtabBuilder.AddMember(Type::IntegerType(4, false), "ilocalsym");
- dynsymtabBuilder.AddMember(Type::IntegerType(4, false), "nlocalsym");
- dynsymtabBuilder.AddMember(Type::IntegerType(4, false), "iextdefsym");
- dynsymtabBuilder.AddMember(Type::IntegerType(4, false), "nextdefsym");
- dynsymtabBuilder.AddMember(Type::IntegerType(4, false), "iundefsym");
- dynsymtabBuilder.AddMember(Type::IntegerType(4, false), "nundefsym");
- dynsymtabBuilder.AddMember(Type::IntegerType(4, false), "tocoff");
- dynsymtabBuilder.AddMember(Type::IntegerType(4, false), "ntoc");
- dynsymtabBuilder.AddMember(Type::IntegerType(4, false), "modtaboff");
- dynsymtabBuilder.AddMember(Type::IntegerType(4, false), "nmodtab");
- dynsymtabBuilder.AddMember(Type::IntegerType(4, false), "extrefsymoff");
- dynsymtabBuilder.AddMember(Type::IntegerType(4, false), "nextrefsyms");
- dynsymtabBuilder.AddMember(Type::IntegerType(4, false), "indirectsymoff");
- dynsymtabBuilder.AddMember(Type::IntegerType(4, false), "nindirectsyms");
- dynsymtabBuilder.AddMember(Type::IntegerType(4, false), "extreloff");
- dynsymtabBuilder.AddMember(Type::IntegerType(4, false), "nextrel");
- dynsymtabBuilder.AddMember(Type::IntegerType(4, false), "locreloff");
- dynsymtabBuilder.AddMember(Type::IntegerType(4, false), "nlocrel");
- Ref<Structure> dynsymtabStruct = dynsymtabBuilder.Finalize();
- QualifiedName dynsymtabName = std::string("dynsymtab");
- std::string dynsymtabTypeId = Type::GenerateAutoTypeId("macho", dynsymtabName);
- Ref<Type> dynsymtabType = Type::StructureType(dynsymtabStruct);
- DefineType(dynsymtabTypeId, dynsymtabName, dynsymtabType);
-
- StructureBuilder uuidBuilder;
- uuidBuilder.AddMember(Type::NamedType(this, QualifiedName("load_command_type_t")), "cmd");
- uuidBuilder.AddMember(Type::IntegerType(4, false), "cmdsize");
- uuidBuilder.AddMember(Type::ArrayType(Type::IntegerType(1, false), 16), "uuid");
- Ref<Structure> uuidStruct = uuidBuilder.Finalize();
- QualifiedName uuidName = std::string("uuid");
- std::string uuidTypeId = Type::GenerateAutoTypeId("macho", uuidName);
- Ref<Type> uuidType = Type::StructureType(uuidStruct);
- DefineType(uuidTypeId, uuidName, uuidType);
-
- StructureBuilder linkeditDataBuilder;
- linkeditDataBuilder.AddMember(Type::NamedType(this, QualifiedName("load_command_type_t")), "cmd");
- linkeditDataBuilder.AddMember(Type::IntegerType(4, false), "cmdsize");
- linkeditDataBuilder.AddMember(Type::IntegerType(4, false), "dataoff");
- linkeditDataBuilder.AddMember(Type::IntegerType(4, false), "datasize");
- Ref<Structure> linkeditDataStruct = linkeditDataBuilder.Finalize();
- QualifiedName linkeditDataName = std::string("linkedit_data");
- std::string linkeditDataTypeId = Type::GenerateAutoTypeId("macho", linkeditDataName);
- Ref<Type> linkeditDataType = Type::StructureType(linkeditDataStruct);
- DefineType(linkeditDataTypeId, linkeditDataName, linkeditDataType);
-
- StructureBuilder encryptionInfoBuilder;
- encryptionInfoBuilder.AddMember(Type::NamedType(this, QualifiedName("load_command_type_t")), "cmd");
- encryptionInfoBuilder.AddMember(Type::IntegerType(4, false), "cmdsize");
- encryptionInfoBuilder.AddMember(Type::IntegerType(4, false), "cryptoff");
- encryptionInfoBuilder.AddMember(Type::IntegerType(4, false), "cryptsize");
- encryptionInfoBuilder.AddMember(Type::IntegerType(4, false), "cryptid");
- Ref<Structure> encryptionInfoStruct = encryptionInfoBuilder.Finalize();
- QualifiedName encryptionInfoName = std::string("encryption_info");
- std::string encryptionInfoTypeId = Type::GenerateAutoTypeId("macho", encryptionInfoName);
- Ref<Type> encryptionInfoType = Type::StructureType(encryptionInfoStruct);
- DefineType(encryptionInfoTypeId, encryptionInfoName, encryptionInfoType);
-
- StructureBuilder versionMinBuilder;
- versionMinBuilder.AddMember(Type::NamedType(this, QualifiedName("load_command_type_t")), "cmd");
- versionMinBuilder.AddMember(Type::IntegerType(4, false), "cmdsize");
- versionMinBuilder.AddMember(Type::IntegerType(4, false), "version");
- versionMinBuilder.AddMember(Type::IntegerType(4, false), "sdk");
- Ref<Structure> versionMinStruct = versionMinBuilder.Finalize();
- QualifiedName versionMinName = std::string("version_min");
- std::string versionMinTypeId = Type::GenerateAutoTypeId("macho", versionMinName);
- Ref<Type> versionMinType = Type::StructureType(versionMinStruct);
- DefineType(versionMinTypeId, versionMinName, versionMinType);
-
- StructureBuilder dyldInfoBuilder;
- dyldInfoBuilder.AddMember(Type::NamedType(this, QualifiedName("load_command_type_t")), "cmd");
- dyldInfoBuilder.AddMember(Type::IntegerType(4, false), "cmdsize");
- dyldInfoBuilder.AddMember(Type::IntegerType(4, false), "rebase_off");
- dyldInfoBuilder.AddMember(Type::IntegerType(4, false), "rebase_size");
- dyldInfoBuilder.AddMember(Type::IntegerType(4, false), "bind_off");
- dyldInfoBuilder.AddMember(Type::IntegerType(4, false), "bind_size");
- dyldInfoBuilder.AddMember(Type::IntegerType(4, false), "weak_bind_off");
- dyldInfoBuilder.AddMember(Type::IntegerType(4, false), "weak_bind_size");
- dyldInfoBuilder.AddMember(Type::IntegerType(4, false), "lazy_bind_off");
- dyldInfoBuilder.AddMember(Type::IntegerType(4, false), "lazy_bind_size");
- dyldInfoBuilder.AddMember(Type::IntegerType(4, false), "export_off");
- dyldInfoBuilder.AddMember(Type::IntegerType(4, false), "export_size");
- Ref<Structure> dyldInfoStruct = dyldInfoBuilder.Finalize();
- QualifiedName dyldInfoName = std::string("dyld_info");
- std::string dyldInfoTypeId = Type::GenerateAutoTypeId("macho", dyldInfoName);
- Ref<Type> dyldInfoType = Type::StructureType(dyldInfoStruct);
- DefineType(dyldInfoTypeId, dyldInfoName, dyldInfoType);
-
- StructureBuilder dylibBuilder;
- dylibBuilder.AddMember(Type::IntegerType(4, false), "name");
- dylibBuilder.AddMember(Type::IntegerType(4, false), "timestamp");
- dylibBuilder.AddMember(Type::IntegerType(4, false), "current_version");
- dylibBuilder.AddMember(Type::IntegerType(4, false), "compatibility_version");
- Ref<Structure> dylibStruct = dylibBuilder.Finalize();
- QualifiedName dylibName = std::string("dylib");
- std::string dylibTypeId = Type::GenerateAutoTypeId("macho", dylibName);
- Ref<Type> dylibType = Type::StructureType(dylibStruct);
- DefineType(dylibTypeId, dylibName, dylibType);
-
- StructureBuilder dylibCommandBuilder;
- dylibCommandBuilder.AddMember(Type::NamedType(this, QualifiedName("load_command_type_t")), "cmd");
- dylibCommandBuilder.AddMember(Type::IntegerType(4, false), "cmdsize");
- dylibCommandBuilder.AddMember(Type::NamedType(this, QualifiedName("dylib")), "dylib");
- Ref<Structure> dylibCommandStruct = dylibCommandBuilder.Finalize();
- QualifiedName dylibCommandName = std::string("dylib_command");
- std::string dylibCommandTypeId = Type::GenerateAutoTypeId("macho", dylibCommandName);
- Ref<Type> dylibCommandType = Type::StructureType(dylibCommandStruct);
- DefineType(dylibCommandTypeId, dylibCommandName, dylibCommandType);
-
- StructureBuilder filesetEntryCommandBuilder;
- filesetEntryCommandBuilder.AddMember(Type::NamedType(this, QualifiedName("load_command_type_t")), "cmd");
- filesetEntryCommandBuilder.AddMember(Type::IntegerType(4, false), "cmdsize");
- filesetEntryCommandBuilder.AddMember(Type::IntegerType(8, false), "vmaddr");
- filesetEntryCommandBuilder.AddMember(Type::IntegerType(8, false), "fileoff");
- filesetEntryCommandBuilder.AddMember(Type::IntegerType(4, false), "entry_id");
- filesetEntryCommandBuilder.AddMember(Type::IntegerType(4, false), "reserved");
- Ref<Structure> filesetEntryCommandStruct = filesetEntryCommandBuilder.Finalize();
- QualifiedName filesetEntryCommandName = std::string("fileset_entry_command");
- std::string filesetEntryCommandTypeId = Type::GenerateAutoTypeId("macho", filesetEntryCommandName);
- Ref<Type> filesetEntryCommandType = Type::StructureType(filesetEntryCommandStruct);
- DefineType(filesetEntryCommandTypeId, filesetEntryCommandName, filesetEntryCommandType);
-
- // uint32_t at 0x10 is offset to mapping table.
- // first mapping struct in that table is base of primary
- // first uint64_t in that struct is the base address of the primary
- // double gpv here because DSCRaw explicitly stops at the start of this mapping table
- uint64_t basePointer = 0;
- GetParentView()->Read(&basePointer, 16, 4);
- if (basePointer == 0)
- {
- LogError("Failed to read base pointer");
- return false;
- }
- uint64_t primaryBase = 0;
- GetParentView()->Read(&primaryBase, basePointer, 8);
- if (primaryBase == 0)
- {
- LogError("Failed to read primary base at 0x%llx", basePointer);
- return false;
- }
-
- uint64_t headerSize = std::min(basePointer, headerType.type->GetWidth());
- // Truncate the `dyld_cache_header` structure to the structure present in the cache file.
- auto newStructure = StructureBuilder(headerType.type->GetStructure()).SetWidth(headerSize).Finalize();
- headerType.type = TypeBuilder::StructureType(newStructure).Finalize();
-
- AddAutoSegment(primaryBase, headerSize, 0, headerSize, SegmentReadable);
- AddAutoSection("__dsc_header", primaryBase, headerSize, ReadOnlyDataSectionSemantics);
- DefineType("dyld_cache_header", headerType.name, headerType.type);
- DefineAutoSymbolAndVariableOrFunction(GetDefaultPlatform(), new Symbol(DataSymbol, "primary_cache_header", primaryBase), headerType.type);
-
- return true;
-}
-
-
-DSCViewType::DSCViewType() : BinaryViewType(VIEW_NAME, VIEW_NAME)
-{
-}
-
-BinaryNinja::Ref<BinaryNinja::BinaryView> DSCViewType::Create(BinaryNinja::BinaryView* data)
-{
- return new DSCView(VIEW_NAME, data, false);
-}
-
-
-Ref<Settings> DSCViewType::GetLoadSettingsForData(BinaryView* data)
-{
- Ref<BinaryView> viewRef = Parse(data);
- if (!viewRef || !viewRef->Init())
- {
- LogWarn("Failed to initialize view of type '%s'. Generating default load settings.", GetName().c_str());
- viewRef = data;
- }
-
- Ref<Settings> settings = GetDefaultLoadSettingsForData(viewRef);
-
- // specify default load settings that can be overridden
- std::vector<std::string> overrides = {"loader.imageBase", "loader.platform"};
- settings->UpdateProperty("loader.imageBase", "message", "Note: File indicates image is not relocatable.");
-
- for (const auto& override : overrides)
- {
- if (settings->Contains(override))
- settings->UpdateProperty(override, "readOnly", false);
- }
-
- Ref<Settings> programSettings = Settings::Instance();
- programSettings->Set("analysis.workflows.functionWorkflow", "core.function.dsc", viewRef);
-
- settings->RegisterSetting("loader.dsc.processCFStrings",
- R"({
- "title" : "Process CFString Metadata",
- "type" : "boolean",
- "default" : true,
- "description" : "Processes CoreFoundation strings, applying string values from encoded metadata"
- })");
-
- settings->RegisterSetting("loader.dsc.autoLoadLibSystem",
- R"({
- "title" : "Auto-Load libSystem",
- "type" : "boolean",
- "default" : true,
- "description" : "Whether to automatically load libsystem_c.dylib. This image contains frequently used noreturn symbols, and not loading it will result in frequently incorrect control flows."
- })");
-
- settings->RegisterSetting("loader.dsc.processObjC",
- R"({
- "title" : "Process Objective-C Metadata",
- "type" : "boolean",
- "default" : true,
- "description" : "Processes Objective-C metadata, applying class and method names from encoded metadata"
- })");
-
- settings->RegisterSetting("loader.dsc.autoLoadObjCStubRequirements",
- R"({
- "title" : "Auto-Load Objective-C Stub Requirements",
- "type" : "boolean",
- "default" : true,
- "description" : "Automatically loads segments required for inlining Objective-C stubs. Recommended you keep this on."
- })");
-
- settings->RegisterSetting("loader.dsc.autoLoadStubsAndDyldData",
- R"({
- "title" : "Auto-Load Stub Islands",
- "type" : "boolean",
- "default" : true,
- "description" : "Automatically loads stub and dylddata regions that contain just branches and pointers. These are required for resolving stub names, and performance impact is minimal. Recommended you keep this on."
- })");
-
- settings->RegisterSetting("loader.dsc.allowLoadingLinkeditSegments",
- R"({
- "title" : "Allow Loading __LINKEDIT Segments",
- "type" : "boolean",
- "default" : false,
- "description" : "Allow mapping __LINKEDIT segments. These are large regions of symbol data that are automatically processed by BinaryNinja without the need for mapping. On newer caches, __LINKEDIT for all images may end up merged and be >300MB in size. This will likely cause severe performance degradation with _zero_ benefit."
- })");
-
- settings->RegisterSetting("loader.dsc.processFunctionStarts",
- R"({
- "title" : "Process Mach-O Function Starts Tables",
- "type" : "boolean",
- "default" : true,
- "description" : "Add function starts sourced from the Function Starts tables to the core for analysis."
- })");
-
- // Merge existing load settings if they exist. This allows for the selection of a specific object file from a Mach-O
- // Universal file. The 'Universal' BinaryViewType generates a schema with 'loader.universal.architectures'. This
- // schema contains an appropriate 'Mach-O' load schema for selecting a specific object file. The embedded schema
- // contains 'loader.macho.universalImageOffset'.
- Ref<Settings> loadSettings = viewRef->GetLoadSettings(GetName());
- if (loadSettings && !loadSettings->IsEmpty())
- settings->DeserializeSchema(loadSettings->SerializeSchema());
-
- return settings;
-}
-
-
-BinaryNinja::Ref<BinaryNinja::BinaryView> DSCViewType::Parse(BinaryNinja::BinaryView* data)
-{
- return new DSCView(VIEW_NAME, data, true);
-}
-
-bool DSCViewType::IsTypeValidForData(BinaryNinja::BinaryView* data)
-{
- if (!data)
- return false;
-
- DataBuffer sig = data->ReadBuffer(data->GetStart(), 4);
- if (sig.GetLength() != 4)
- return false;
-
- const char* magic = (char*)sig.GetData();
- if (strncmp(magic, "dyld", 4) == 0)
- return true;
-
- return false;
-}