Add support for dyldcache headers up to dyld-1042.1 (#3536)
Newer dyldcaches have more fields in the header. This change adds heuristics for determining the version and reading and displaying the newer fields if available.
This commit is contained in:
parent
c5978e158c
commit
ea04e76d1b
5 changed files with 752 additions and 92 deletions
|
|
@ -16,7 +16,10 @@ static RzDyldLocSym *rz_dyld_locsym_new(RzDyldCache *cache);
|
|||
* \param magic zero-terminated string from the beginning of some file
|
||||
*/
|
||||
RZ_API bool rz_dyldcache_check_magic(const char *magic) {
|
||||
return !strcmp(magic, "dyld_v1 arm64") || !strcmp(magic, "dyld_v1 arm64e") || !strcmp(magic, "dyld_v1 x86_64") || !strcmp(magic, "dyld_v1 x86_64h");
|
||||
return !strncmp(magic, "dyld_v1 arm64", 16) ||
|
||||
!strncmp(magic, "dyld_v1 arm64e", 16) ||
|
||||
!strncmp(magic, "dyld_v1 x86_64", 16) ||
|
||||
!strncmp(magic, "dyld_v1 x86_64h", 16);
|
||||
}
|
||||
|
||||
static ut64 va2pa(uint64_t addr, ut32 n_maps, cache_map_t *maps, RzBuffer *cache_buf, ut64 slide, ut32 *offset, ut32 *left) {
|
||||
|
|
@ -49,33 +52,173 @@ static void free_bin(RzDyldBinImage *bin) {
|
|||
free(bin);
|
||||
}
|
||||
|
||||
static cache_hdr_t *read_cache_header(RzBuffer *cache_buf, ut64 offset) {
|
||||
static RzDyldCacheHeader *read_cache_header(RzBuffer *cache_buf, ut64 offset) {
|
||||
if (!cache_buf) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cache_hdr_t *hdr = RZ_NEW0(cache_hdr_t);
|
||||
RzDyldCacheHeader *hdr = RZ_NEW0(RzDyldCacheHeader);
|
||||
if (!hdr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ut64 size = sizeof(cache_hdr_t);
|
||||
if (rz_buf_fread_at(cache_buf, offset, (ut8 *)hdr, "16c4i7l16clii4l", 1) != size) {
|
||||
free(hdr);
|
||||
return NULL;
|
||||
}
|
||||
if (!rz_dyldcache_check_magic(hdr->magic)) {
|
||||
free(hdr);
|
||||
return NULL;
|
||||
ut64 cur = offset;
|
||||
if (!rz_buf_read_offset(cache_buf, &cur, (ut8 *)hdr->magic, sizeof(hdr->magic)) ||
|
||||
!rz_dyldcache_check_magic(hdr->magic) ||
|
||||
!rz_buf_read_le32_offset(cache_buf, &cur, &hdr->mappingOffset) ||
|
||||
!rz_buf_read_le32_offset(cache_buf, &cur, &hdr->mappingCount) ||
|
||||
!rz_buf_read_le32_offset(cache_buf, &cur, &hdr->imagesOffset) ||
|
||||
!rz_buf_read_le32_offset(cache_buf, &cur, &hdr->imagesCount) ||
|
||||
!rz_buf_read_le64_offset(cache_buf, &cur, &hdr->dyldBaseAddress) ||
|
||||
!rz_buf_read_le64_offset(cache_buf, &cur, &hdr->codeSignatureOffset) ||
|
||||
!rz_buf_read_le64_offset(cache_buf, &cur, &hdr->codeSignatureSize) ||
|
||||
!rz_buf_read_le64_offset(cache_buf, &cur, &hdr->slideInfoOffset) ||
|
||||
!rz_buf_read_le64_offset(cache_buf, &cur, &hdr->slideInfoSize) ||
|
||||
!rz_buf_read_le64_offset(cache_buf, &cur, &hdr->localSymbolsOffset) ||
|
||||
!rz_buf_read_le64_offset(cache_buf, &cur, &hdr->localSymbolsSize) ||
|
||||
!rz_buf_read_offset(cache_buf, &cur, hdr->uuid, sizeof(hdr->uuid)) ||
|
||||
!rz_buf_read_le64_offset(cache_buf, &cur, &hdr->cacheType) ||
|
||||
!rz_buf_read_le32_offset(cache_buf, &cur, &hdr->branchPoolsOffset) ||
|
||||
!rz_buf_read_le32_offset(cache_buf, &cur, &hdr->branchPoolsCount) ||
|
||||
!rz_buf_read_le64_offset(cache_buf, &cur, &hdr->accelerateInfoAddr) ||
|
||||
!rz_buf_read_le64_offset(cache_buf, &cur, &hdr->accelerateInfoSize) ||
|
||||
!rz_buf_read_le64_offset(cache_buf, &cur, &hdr->imagesTextOffset) ||
|
||||
!rz_buf_read_le64_offset(cache_buf, &cur, &hdr->imagesTextCount)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!hdr->imagesCount && !hdr->imagesOffset) {
|
||||
if (!rz_buf_read_le32_at(cache_buf, 0x1c0 + offset, &hdr->imagesOffset) || !rz_buf_read_le32_at(cache_buf, 0x1c4 + offset, &hdr->imagesCount)) {
|
||||
free(hdr);
|
||||
return NULL;
|
||||
}
|
||||
// Size of the header was continuously expanded during versions as newer fields got added.
|
||||
// There is no dedicated header size stored in the file, but in practice the mappingOffset is
|
||||
// directly after the header, so we use this as an indicator on how far we may read.
|
||||
ut64 hdr_end_offset = offset + hdr->mappingOffset;
|
||||
#define READ_OR_FINISH(bits, dst) \
|
||||
do { \
|
||||
if (cur + bits / 8 > hdr_end_offset || !rz_buf_read_le##bits##_offset(cache_buf, &cur, dst)) { \
|
||||
goto finish; \
|
||||
} \
|
||||
} while (0)
|
||||
READ_OR_FINISH(64, &hdr->patchInfoAddr);
|
||||
READ_OR_FINISH(64, &hdr->patchInfoSize);
|
||||
READ_OR_FINISH(64, &hdr->otherImageGroupAddrUnused);
|
||||
READ_OR_FINISH(64, &hdr->otherImageGroupSizeUnused);
|
||||
READ_OR_FINISH(64, &hdr->progClosuresAddr);
|
||||
READ_OR_FINISH(64, &hdr->progClosuresSize);
|
||||
READ_OR_FINISH(64, &hdr->progClosuresTrieAddr);
|
||||
READ_OR_FINISH(64, &hdr->progClosuresTrieSize);
|
||||
READ_OR_FINISH(32, &hdr->platform);
|
||||
|
||||
ut32 flags;
|
||||
READ_OR_FINISH(32, &flags);
|
||||
hdr->formatVersion = flags & rz_num_bitmask(8);
|
||||
flags >>= 8;
|
||||
hdr->dylibsExpectedOnDisk = flags & 1;
|
||||
flags >>= 1;
|
||||
hdr->simulator = flags & 1;
|
||||
flags >>= 1;
|
||||
hdr->locallyBuiltCache = flags & 1;
|
||||
flags >>= 1;
|
||||
hdr->builtFromChainedFixups = flags & 1;
|
||||
flags >>= 1;
|
||||
hdr->padding = flags;
|
||||
|
||||
READ_OR_FINISH(64, &hdr->sharedRegionStart);
|
||||
READ_OR_FINISH(64, &hdr->sharedRegionSize);
|
||||
READ_OR_FINISH(64, &hdr->maxSlide);
|
||||
READ_OR_FINISH(64, &hdr->dylibsImageArrayAddr);
|
||||
READ_OR_FINISH(64, &hdr->dylibsImageArraySize);
|
||||
READ_OR_FINISH(64, &hdr->dylibsTrieAddr);
|
||||
READ_OR_FINISH(64, &hdr->dylibsTrieSize);
|
||||
READ_OR_FINISH(64, &hdr->otherImageArrayAddr);
|
||||
READ_OR_FINISH(64, &hdr->otherImageArraySize);
|
||||
READ_OR_FINISH(64, &hdr->otherTrieAddr);
|
||||
READ_OR_FINISH(64, &hdr->otherTrieSize);
|
||||
READ_OR_FINISH(32, &hdr->mappingWithSlideOffset);
|
||||
READ_OR_FINISH(32, &hdr->mappingWithSlideCount);
|
||||
|
||||
READ_OR_FINISH(64, &hdr->dylibsPBLStateArrayAddrUnused);
|
||||
READ_OR_FINISH(64, &hdr->dylibsPBLSetAddr);
|
||||
READ_OR_FINISH(64, &hdr->programsPBLSetPoolAddr);
|
||||
READ_OR_FINISH(64, &hdr->programsPBLSetPoolSize);
|
||||
READ_OR_FINISH(64, &hdr->programTrieAddr);
|
||||
READ_OR_FINISH(32, &hdr->programTrieSize);
|
||||
READ_OR_FINISH(32, &hdr->osVersion);
|
||||
READ_OR_FINISH(32, &hdr->altPlatform);
|
||||
READ_OR_FINISH(32, &hdr->altOsVersion);
|
||||
READ_OR_FINISH(64, &hdr->swiftOptsOffset);
|
||||
READ_OR_FINISH(64, &hdr->swiftOptsSize);
|
||||
READ_OR_FINISH(32, &hdr->subCacheArrayOffset);
|
||||
READ_OR_FINISH(32, &hdr->subCacheArrayCount);
|
||||
|
||||
if (cur + sizeof(hdr->symbolFileUUID) > hdr_end_offset ||
|
||||
!rz_buf_read_offset(cache_buf, &cur, hdr->symbolFileUUID, sizeof(hdr->symbolFileUUID))) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
READ_OR_FINISH(64, &hdr->rosettaReadOnlyAddr);
|
||||
READ_OR_FINISH(64, &hdr->rosettaReadOnlySize);
|
||||
READ_OR_FINISH(64, &hdr->rosettaReadWriteAddr);
|
||||
READ_OR_FINISH(64, &hdr->rosettaReadWriteSize);
|
||||
|
||||
// This intentionally overrides the imagesOffset/imagesCount above as these
|
||||
// two fields were moved down here in dyld-940:
|
||||
READ_OR_FINISH(32, &hdr->imagesOffset);
|
||||
READ_OR_FINISH(32, &hdr->imagesCount);
|
||||
|
||||
READ_OR_FINISH(32, &hdr->cacheSubType);
|
||||
cur += 4; // 8-alignment/padding
|
||||
READ_OR_FINISH(64, &hdr->objcOptsOffset);
|
||||
READ_OR_FINISH(64, &hdr->objcOptsSize);
|
||||
READ_OR_FINISH(64, &hdr->cacheAtlasOffset);
|
||||
READ_OR_FINISH(64, &hdr->cacheAtlasSize);
|
||||
READ_OR_FINISH(64, &hdr->dynamicDataOffset);
|
||||
READ_OR_FINISH(64, &hdr->dynamicDataMaxSize);
|
||||
|
||||
#undef READ_OR_FINISH
|
||||
finish:
|
||||
return hdr;
|
||||
fail:
|
||||
free(hdr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RZ_API RZ_NONNULL const char *rz_dyldcache_get_platform_str(RzDyldCache *cache) {
|
||||
switch (cache->hdr->platform) {
|
||||
case 1:
|
||||
return "macOS";
|
||||
case 2:
|
||||
return "iOS";
|
||||
case 3:
|
||||
return "tvOS";
|
||||
case 4:
|
||||
return "watchOS";
|
||||
case 5:
|
||||
return "bridgeOS";
|
||||
case 6:
|
||||
return "iOSMac";
|
||||
case 7:
|
||||
return "iOS_simulator";
|
||||
case 8:
|
||||
return "tvOS_simulator";
|
||||
case 9:
|
||||
return "watchOS_simulator";
|
||||
case 10:
|
||||
return "driverKit";
|
||||
default:
|
||||
return "darwin"; // unknown
|
||||
}
|
||||
}
|
||||
|
||||
RZ_API RZ_NONNULL const char *rz_dyldcache_get_type_str(RzDyldCache *cache) {
|
||||
switch (cache->hdr->cacheType) {
|
||||
case 0:
|
||||
return "development";
|
||||
case 1:
|
||||
return "production";
|
||||
case 2:
|
||||
return "multi-cache";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
#define SHIFT_MAYBE(x) \
|
||||
|
|
@ -90,7 +233,7 @@ static void populate_cache_headers(RzDyldCache *cache) {
|
|||
return;
|
||||
}
|
||||
|
||||
cache_hdr_t *h;
|
||||
RzDyldCacheHeader *h;
|
||||
ut64 offsets[MAX_N_HDR];
|
||||
ut64 offset = 0;
|
||||
do {
|
||||
|
|
@ -119,7 +262,7 @@ static void populate_cache_headers(RzDyldCache *cache) {
|
|||
goto beach;
|
||||
}
|
||||
|
||||
cache->hdr = RZ_NEWS0(cache_hdr_t, cache->n_hdr);
|
||||
cache->hdr = RZ_NEWS0(RzDyldCacheHeader, cache->n_hdr);
|
||||
if (!cache->hdr) {
|
||||
cache->n_hdr = 0;
|
||||
goto beach;
|
||||
|
|
@ -136,12 +279,12 @@ static void populate_cache_headers(RzDyldCache *cache) {
|
|||
|
||||
ut32 i = 0;
|
||||
RzListIter *iter;
|
||||
cache_hdr_t *item;
|
||||
RzDyldCacheHeader *item;
|
||||
rz_list_foreach (hdrs, iter, item) {
|
||||
if (i >= cache->n_hdr) {
|
||||
break;
|
||||
}
|
||||
memcpy(&cache->hdr[i++], item, sizeof(cache_hdr_t));
|
||||
memcpy(&cache->hdr[i++], item, sizeof(RzDyldCacheHeader));
|
||||
}
|
||||
|
||||
beach:
|
||||
|
|
@ -157,7 +300,7 @@ static void populate_cache_maps(RzDyldCache *cache) {
|
|||
ut32 n_maps = 0;
|
||||
ut64 max_count = 0;
|
||||
for (i = 0; i < cache->n_hdr; i++) {
|
||||
cache_hdr_t *hdr = &cache->hdr[i];
|
||||
RzDyldCacheHeader *hdr = &cache->hdr[i];
|
||||
if (!hdr->mappingCount || !hdr->mappingOffset) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -181,7 +324,7 @@ static void populate_cache_maps(RzDyldCache *cache) {
|
|||
ut32 last_idx = UT32_MAX;
|
||||
ut64 max_address = 0;
|
||||
for (i = 0; i < cache->n_hdr; i++) {
|
||||
cache_hdr_t *hdr = &cache->hdr[i];
|
||||
RzDyldCacheHeader *hdr = &cache->hdr[i];
|
||||
cache->maps_index[i] = next_map;
|
||||
|
||||
if (!hdr->mappingCount || !hdr->mappingOffset) {
|
||||
|
|
@ -213,8 +356,8 @@ static void populate_cache_maps(RzDyldCache *cache) {
|
|||
}
|
||||
}
|
||||
|
||||
static cache_accel_t *read_cache_accel(RzBuffer *cache_buf, cache_hdr_t *hdr, cache_map_t *maps) {
|
||||
if (!cache_buf || !hdr || !hdr->accelerateInfoSize || !hdr->accelerateInfoAddr) {
|
||||
static cache_accel_t *read_cache_accel(RzBuffer *cache_buf, RzDyldCacheHeader *hdr, cache_map_t *maps) {
|
||||
if (!cache_buf || !hdr || !rz_dyldcache_header_may_have_accel(hdr) || !hdr->accelerateInfoSize || !hdr->accelerateInfoAddr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -315,7 +458,7 @@ beach:
|
|||
return result;
|
||||
}
|
||||
|
||||
static cache_img_t *read_cache_images(RzBuffer *cache_buf, cache_hdr_t *hdr, ut64 hdr_offset) {
|
||||
static cache_img_t *read_cache_images(RzBuffer *cache_buf, RzDyldCacheHeader *hdr, ut64 hdr_offset) {
|
||||
if (!cache_buf || !hdr) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -385,7 +528,7 @@ static void match_bin_entries(RzDyldCache *cache, void *entries) {
|
|||
RZ_FREE(imgs);
|
||||
}
|
||||
|
||||
static cache_imgxtr_t *read_cache_imgextra(RzBuffer *cache_buf, cache_hdr_t *hdr, cache_accel_t *accel) {
|
||||
static cache_imgxtr_t *read_cache_imgextra(RzBuffer *cache_buf, RzDyldCacheHeader *hdr, cache_accel_t *accel) {
|
||||
if (!cache_buf || !hdr || !hdr->imagesCount || !accel || !accel->imageExtrasCount || !accel->imagesExtrasOffset) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -418,7 +561,7 @@ static int string_contains(const void *a, const void *b) {
|
|||
return !strstr((const char *)a, (const char *)b);
|
||||
}
|
||||
|
||||
static HtPU *create_path_to_index(RzBuffer *cache_buf, cache_img_t *img, cache_hdr_t *hdr) {
|
||||
static HtPU *create_path_to_index(RzBuffer *cache_buf, cache_img_t *img, RzDyldCacheHeader *hdr) {
|
||||
HtPU *path_to_idx = ht_pu_new0();
|
||||
if (!path_to_idx) {
|
||||
return NULL;
|
||||
|
|
@ -510,7 +653,7 @@ static RzList /*<RzDyldBinImage *>*/ *create_cache_bins(RzDyldCache *cache) {
|
|||
|
||||
ut32 i;
|
||||
for (i = 0; i < cache->n_hdr; i++) {
|
||||
cache_hdr_t *hdr = &cache->hdr[i];
|
||||
RzDyldCacheHeader *hdr = &cache->hdr[i];
|
||||
ut64 hdr_offset = cache->hdr_offset[i];
|
||||
ut64 symbols_off = cache->symbols_off_base - hdr_offset;
|
||||
ut32 maps_index = cache->maps_index[i];
|
||||
|
|
@ -1270,7 +1413,7 @@ static RzDyldLocSym *rz_dyld_locsym_new(RzDyldCache *cache) {
|
|||
|
||||
ut32 i;
|
||||
for (i = 0; i < cache->n_hdr; i++) {
|
||||
cache_hdr_t *hdr = &cache->hdr[i];
|
||||
RzDyldCacheHeader *hdr = &cache->hdr[i];
|
||||
if (!hdr || !hdr->localSymbolsSize || !hdr->localSymbolsOffset) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,131 @@
|
|||
|
||||
#include "mach0.h"
|
||||
|
||||
typedef struct rz_dyld_cache_header_t {
|
||||
char magic[16];
|
||||
ut32 mappingOffset;
|
||||
ut32 mappingCount;
|
||||
ut32 imagesOffset;
|
||||
ut32 imagesCount;
|
||||
ut64 dyldBaseAddress;
|
||||
ut64 codeSignatureOffset;
|
||||
ut64 codeSignatureSize;
|
||||
ut64 slideInfoOffset;
|
||||
ut64 slideInfoSize;
|
||||
ut64 localSymbolsOffset;
|
||||
ut64 localSymbolsSize;
|
||||
ut8 uuid[16];
|
||||
ut64 cacheType;
|
||||
ut32 branchPoolsOffset;
|
||||
ut32 branchPoolsCount;
|
||||
union {
|
||||
struct {
|
||||
ut64 accelerateInfoAddr;
|
||||
ut64 accelerateInfoSize;
|
||||
}; ///< used if rz_dyldcache_header_may_have_accel() == true
|
||||
struct {
|
||||
ut64 dyldInCacheMH;
|
||||
ut64 dyldInCacheEntry;
|
||||
}; ///< used if rz_dyldcache_header_may_have_accel() == false
|
||||
};
|
||||
ut64 imagesTextOffset;
|
||||
ut64 imagesTextCount;
|
||||
ut64 patchInfoAddr;
|
||||
ut64 patchInfoSize;
|
||||
ut64 otherImageGroupAddrUnused;
|
||||
ut64 otherImageGroupSizeUnused;
|
||||
ut64 progClosuresAddr;
|
||||
ut64 progClosuresSize;
|
||||
ut64 progClosuresTrieAddr;
|
||||
ut64 progClosuresTrieSize;
|
||||
ut32 platform;
|
||||
ut32 formatVersion : 8,
|
||||
dylibsExpectedOnDisk : 1,
|
||||
simulator : 1,
|
||||
locallyBuiltCache : 1,
|
||||
builtFromChainedFixups : 1,
|
||||
padding : 20;
|
||||
ut64 sharedRegionStart;
|
||||
ut64 sharedRegionSize;
|
||||
ut64 maxSlide;
|
||||
ut64 dylibsImageArrayAddr;
|
||||
ut64 dylibsImageArraySize;
|
||||
ut64 dylibsTrieAddr;
|
||||
ut64 dylibsTrieSize;
|
||||
ut64 otherImageArrayAddr;
|
||||
ut64 otherImageArraySize;
|
||||
ut64 otherTrieAddr;
|
||||
ut64 otherTrieSize;
|
||||
ut32 mappingWithSlideOffset;
|
||||
ut32 mappingWithSlideCount;
|
||||
|
||||
// offset = 0x140
|
||||
|
||||
// below added in dyld-940
|
||||
ut64 dylibsPBLStateArrayAddrUnused;
|
||||
ut64 dylibsPBLSetAddr;
|
||||
ut64 programsPBLSetPoolAddr;
|
||||
ut64 programsPBLSetPoolSize;
|
||||
ut64 programTrieAddr;
|
||||
ut32 programTrieSize;
|
||||
ut32 osVersion;
|
||||
ut32 altPlatform;
|
||||
ut32 altOsVersion;
|
||||
ut64 swiftOptsOffset;
|
||||
ut64 swiftOptsSize;
|
||||
ut32 subCacheArrayOffset;
|
||||
ut32 subCacheArrayCount;
|
||||
ut8 symbolFileUUID[16];
|
||||
ut64 rosettaReadOnlyAddr;
|
||||
ut64 rosettaReadOnlySize;
|
||||
ut64 rosettaReadWriteAddr;
|
||||
ut64 rosettaReadWriteSize;
|
||||
// ut32 imagesOffset; (consolidated with imageOffset above)
|
||||
// ut32 imagesCount; (consolidated with imagesCount above)
|
||||
|
||||
// offset = 0x1c8
|
||||
|
||||
// below added in dyld-1042.1
|
||||
ut32 cacheSubType;
|
||||
ut64 objcOptsOffset;
|
||||
ut64 objcOptsSize;
|
||||
ut64 cacheAtlasOffset;
|
||||
ut64 cacheAtlasSize;
|
||||
ut64 dynamicDataOffset;
|
||||
ut64 dynamicDataMaxSize;
|
||||
// offset = 0x200
|
||||
} RzDyldCacheHeader;
|
||||
|
||||
typedef enum rz_dyld_cache_header_version {
|
||||
RZ_DYLD_CACHE_HEADER_BEFORE_940,
|
||||
RZ_DYLD_CACHE_HEADER_940_OR_AFTER,
|
||||
RZ_DYLD_CACHE_HEADER_1042_1_OR_AFTER
|
||||
} RzDyldCacheHeaderVersion;
|
||||
|
||||
/**
|
||||
* Guess the dyld version that \p hdr was created from
|
||||
*/
|
||||
static inline RzDyldCacheHeaderVersion rz_dyldcache_header_version(RzDyldCacheHeader *hdr) {
|
||||
// Fields were added during different dyld versions, so we can use the size of the header to guess
|
||||
// the version. Even though there is no explicit header size field, mappingOffset is usually directly
|
||||
// after the header, so we use this to measure size.
|
||||
if (hdr->mappingOffset < 0x1c8) {
|
||||
return RZ_DYLD_CACHE_HEADER_BEFORE_940;
|
||||
} else if (hdr->mappingOffset < 0x200) {
|
||||
return RZ_DYLD_CACHE_HEADER_940_OR_AFTER;
|
||||
} else {
|
||||
return RZ_DYLD_CACHE_HEADER_1042_1_OR_AFTER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the accelerateInfoAddr/accelerateInfoSize fields are available in the header,
|
||||
* as opposed to dyldInCacheMH/dyldInCacheEntry
|
||||
*/
|
||||
static inline bool rz_dyldcache_header_may_have_accel(RzDyldCacheHeader *hdr) {
|
||||
return rz_dyldcache_header_version(hdr) < RZ_DYLD_CACHE_HEADER_1042_1_OR_AFTER;
|
||||
}
|
||||
|
||||
typedef struct rz_dyld_rebase_info_t {
|
||||
ut8 version;
|
||||
ut64 slide;
|
||||
|
|
@ -93,7 +218,7 @@ typedef struct rz_bin_dyld_image_t {
|
|||
typedef struct rz_dyldcache_t {
|
||||
ut8 magic[8];
|
||||
|
||||
cache_hdr_t *hdr;
|
||||
RzDyldCacheHeader *hdr;
|
||||
ut64 *hdr_offset;
|
||||
ut64 symbols_off_base;
|
||||
ut32 *maps_index;
|
||||
|
|
@ -113,6 +238,8 @@ typedef struct rz_dyldcache_t {
|
|||
RZ_API bool rz_dyldcache_check_magic(const char *magic);
|
||||
RZ_API RzDyldCache *rz_dyldcache_new_buf(RzBuffer *buf);
|
||||
RZ_API void rz_dyldcache_free(RzDyldCache *cache);
|
||||
RZ_API RZ_NONNULL const char *rz_dyldcache_get_platform_str(RzDyldCache *cache);
|
||||
RZ_API RZ_NONNULL const char *rz_dyldcache_get_type_str(RzDyldCache *cache);
|
||||
RZ_API ut64 rz_dyldcache_va2pa(RzDyldCache *cache, uint64_t vaddr, ut32 *offset, ut32 *left);
|
||||
RZ_API ut64 rz_dyldcache_get_slide(RzDyldCache *cache);
|
||||
RZ_API objc_cache_opt_info *rz_dyldcache_get_objc_opt_info(RzBinFile *bf, RzDyldCache *cache);
|
||||
|
|
|
|||
|
|
@ -189,47 +189,6 @@ struct arm_thread_state64 {
|
|||
ut32 cpsr;
|
||||
};
|
||||
|
||||
/* Cache header */
|
||||
|
||||
struct cache_header {
|
||||
char version[16];
|
||||
ut32 baseaddroff; // mappingOffset
|
||||
ut32 mappingCount;
|
||||
ut32 startaddr;
|
||||
ut32 numlibs;
|
||||
ut64 dyldaddr;
|
||||
ut64 codeSignatureOffset;
|
||||
ut64 codeSignatureSize;
|
||||
ut64 slideInfoOffset;
|
||||
ut64 slideInfoSize;
|
||||
ut64 localSymbolsOffset;
|
||||
ut64 localSymbolsSize;
|
||||
};
|
||||
|
||||
// dupe?
|
||||
typedef struct {
|
||||
char magic[16];
|
||||
uint32_t mappingOffset;
|
||||
uint32_t mappingCount;
|
||||
uint32_t imagesOffset;
|
||||
uint32_t imagesCount;
|
||||
uint64_t dyldBaseAddress;
|
||||
uint64_t codeSignatureOffset;
|
||||
uint64_t codeSignatureSize;
|
||||
uint64_t slideInfoOffset;
|
||||
uint64_t slideInfoSize;
|
||||
uint64_t localSymbolsOffset;
|
||||
uint64_t localSymbolsSize;
|
||||
uint8_t uuid[16];
|
||||
uint64_t cacheType;
|
||||
uint32_t branchPoolsOffset;
|
||||
uint32_t branchPoolsCount;
|
||||
uint64_t accelerateInfoAddr;
|
||||
uint64_t accelerateInfoSize;
|
||||
uint64_t imagesTextOffset;
|
||||
uint64_t imagesTextCount;
|
||||
} cache_hdr_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t uuid[16];
|
||||
uint64_t loadAddress;
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ static RzBinInfo *info(RzBinFile *bf) {
|
|||
}
|
||||
ret->file = strdup(bf->file);
|
||||
ret->bclass = strdup("dyldcache");
|
||||
ret->os = strdup("Darwin"); // TODO: actual OS info is available. See the platform member of struct dyld_cache_header in dyld source.
|
||||
ret->os = strdup(rz_dyldcache_get_platform_str(cache));
|
||||
if (strstr(cache->hdr->magic, "x86_64")) {
|
||||
ret->arch = strdup("x86");
|
||||
ret->bits = 64;
|
||||
|
|
@ -121,7 +121,8 @@ static RzBinInfo *info(RzBinFile *bf) {
|
|||
}
|
||||
ret->machine = strdup(ret->arch);
|
||||
ret->subsystem = strdup("xnu");
|
||||
ret->type = strdup("library-cache");
|
||||
ret->guid = rz_hex_bin2strdup((ut8 *)cache->hdr->uuid, sizeof(cache->hdr->uuid));
|
||||
ret->type = strdup(rz_dyldcache_get_type_str(cache));
|
||||
ret->has_va = true;
|
||||
ret->big_endian = big_endian;
|
||||
ret->dbg_info = 0;
|
||||
|
|
@ -515,6 +516,21 @@ static void header(RzBinFile *bf) {
|
|||
}
|
||||
|
||||
pj_o(pj);
|
||||
|
||||
pj_k(pj, "version");
|
||||
RzDyldCacheHeaderVersion ver = rz_dyldcache_header_version(cache->hdr);
|
||||
switch (ver) {
|
||||
case RZ_DYLD_CACHE_HEADER_BEFORE_940:
|
||||
pj_s(pj, "<940");
|
||||
break;
|
||||
case RZ_DYLD_CACHE_HEADER_940_OR_AFTER:
|
||||
pj_s(pj, "940");
|
||||
break;
|
||||
case RZ_DYLD_CACHE_HEADER_1042_1_OR_AFTER:
|
||||
pj_s(pj, "1042.1");
|
||||
break;
|
||||
}
|
||||
|
||||
pj_k(pj, "header");
|
||||
pj_o(pj);
|
||||
pj_ks(pj, "magic", cache->hdr->magic);
|
||||
|
|
@ -535,10 +551,73 @@ static void header(RzBinFile *bf) {
|
|||
pj_ks(pj, "cacheType", (cache->hdr->cacheType == 0) ? "development" : "production");
|
||||
pj_kn(pj, "branchPoolsOffset", cache->hdr->branchPoolsOffset);
|
||||
pj_kn(pj, "branchPoolsCount", cache->hdr->branchPoolsCount);
|
||||
pj_kn(pj, "accelerateInfoAddr", cache->hdr->accelerateInfoAddr + slide);
|
||||
pj_kn(pj, "accelerateInfoSize", cache->hdr->accelerateInfoSize);
|
||||
if (rz_dyldcache_header_may_have_accel(cache->hdr)) {
|
||||
pj_kn(pj, "accelerateInfoAddr", cache->hdr->accelerateInfoAddr + slide);
|
||||
pj_kn(pj, "accelerateInfoSize", cache->hdr->accelerateInfoSize);
|
||||
} else {
|
||||
pj_kn(pj, "dyldInCacheMH", cache->hdr->dyldInCacheMH);
|
||||
pj_kn(pj, "dyldInCacheEntry", cache->hdr->dyldInCacheEntry);
|
||||
}
|
||||
pj_kn(pj, "imagesTextOffset", cache->hdr->imagesTextOffset);
|
||||
pj_kn(pj, "imagesTextCount", cache->hdr->imagesTextCount);
|
||||
pj_kn(pj, "patchInfoAddr", cache->hdr->patchInfoAddr);
|
||||
pj_kn(pj, "patchInfoSize", cache->hdr->patchInfoSize);
|
||||
pj_kn(pj, "otherImageGroupAddrUnused", cache->hdr->otherImageGroupAddrUnused);
|
||||
pj_kn(pj, "otherImageGroupSizeUnused", cache->hdr->otherImageGroupSizeUnused);
|
||||
pj_kn(pj, "progClosuresAddr", cache->hdr->progClosuresAddr);
|
||||
pj_kn(pj, "progClosuresSize", cache->hdr->progClosuresSize);
|
||||
pj_kn(pj, "progClosuresTrieAddr", cache->hdr->progClosuresTrieAddr);
|
||||
pj_kn(pj, "progClosuresTrieSize", cache->hdr->progClosuresTrieSize);
|
||||
pj_kn(pj, "platform", cache->hdr->platform);
|
||||
pj_kn(pj, "formatVersion", cache->hdr->formatVersion);
|
||||
pj_kn(pj, "dylibsExpectedOnDisk", cache->hdr->dylibsExpectedOnDisk);
|
||||
pj_kn(pj, "simulator", cache->hdr->simulator);
|
||||
pj_kn(pj, "locallyBuiltCache", cache->hdr->locallyBuiltCache);
|
||||
pj_kn(pj, "builtFromChainedFixups", cache->hdr->builtFromChainedFixups);
|
||||
pj_kn(pj, "padding", cache->hdr->padding);
|
||||
pj_kn(pj, "sharedRegionStart", cache->hdr->sharedRegionStart);
|
||||
pj_kn(pj, "sharedRegionSize", cache->hdr->sharedRegionSize);
|
||||
pj_kn(pj, "maxSlide", cache->hdr->maxSlide);
|
||||
pj_kn(pj, "dylibsImageArrayAddr", cache->hdr->dylibsImageArrayAddr);
|
||||
pj_kn(pj, "dylibsImageArraySize", cache->hdr->dylibsImageArraySize);
|
||||
pj_kn(pj, "dylibsTrieAddr", cache->hdr->dylibsTrieAddr);
|
||||
pj_kn(pj, "dylibsTrieSize", cache->hdr->dylibsTrieSize);
|
||||
pj_kn(pj, "otherImageArrayAddr", cache->hdr->otherImageArrayAddr);
|
||||
pj_kn(pj, "otherImageArraySize", cache->hdr->otherImageArraySize);
|
||||
pj_kn(pj, "otherTrieAddr", cache->hdr->otherTrieAddr);
|
||||
pj_kn(pj, "otherTrieSize", cache->hdr->otherTrieSize);
|
||||
pj_kn(pj, "mappingWithSlideOffset", cache->hdr->mappingWithSlideOffset);
|
||||
pj_kn(pj, "mappingWithSlideCount", cache->hdr->mappingWithSlideCount);
|
||||
if (ver >= RZ_DYLD_CACHE_HEADER_940_OR_AFTER) {
|
||||
pj_kn(pj, "dylibsPBLStateArrayAddrUnused", cache->hdr->dylibsPBLStateArrayAddrUnused);
|
||||
pj_kn(pj, "dylibsPBLSetAddr", cache->hdr->dylibsPBLSetAddr);
|
||||
pj_kn(pj, "programsPBLSetPoolAddr", cache->hdr->programsPBLSetPoolAddr);
|
||||
pj_kn(pj, "programsPBLSetPoolSize", cache->hdr->programsPBLSetPoolSize);
|
||||
pj_kn(pj, "programTrieAddr", cache->hdr->programTrieAddr);
|
||||
pj_kn(pj, "programTrieSize", cache->hdr->programTrieSize);
|
||||
pj_kn(pj, "osVersion", cache->hdr->osVersion);
|
||||
pj_kn(pj, "altPlatform", cache->hdr->altPlatform);
|
||||
pj_kn(pj, "altOsVersion", cache->hdr->altOsVersion);
|
||||
pj_kn(pj, "swiftOptsOffset", cache->hdr->swiftOptsOffset);
|
||||
pj_kn(pj, "swiftOptsSize", cache->hdr->swiftOptsSize);
|
||||
pj_kn(pj, "subCacheArrayOffset", cache->hdr->subCacheArrayOffset);
|
||||
pj_kn(pj, "subCacheArrayCount", cache->hdr->subCacheArrayCount);
|
||||
rz_hex_bin2str(cache->hdr->symbolFileUUID, sizeof(cache->hdr->symbolFileUUID), uuidstr);
|
||||
pj_ks(pj, "symbolFileUUID", uuidstr);
|
||||
pj_kn(pj, "rosettaReadOnlyAddr", cache->hdr->rosettaReadOnlyAddr);
|
||||
pj_kn(pj, "rosettaReadOnlySize", cache->hdr->rosettaReadOnlySize);
|
||||
pj_kn(pj, "rosettaReadWriteAddr", cache->hdr->rosettaReadWriteAddr);
|
||||
pj_kn(pj, "rosettaReadWriteSize", cache->hdr->rosettaReadWriteSize);
|
||||
}
|
||||
if (ver >= RZ_DYLD_CACHE_HEADER_1042_1_OR_AFTER) {
|
||||
pj_kn(pj, "cacheSubType", cache->hdr->cacheSubType);
|
||||
pj_kn(pj, "objcOptsOffset", cache->hdr->objcOptsOffset);
|
||||
pj_kn(pj, "objcOptsSize", cache->hdr->objcOptsSize);
|
||||
pj_kn(pj, "cacheAtlasOffset", cache->hdr->cacheAtlasOffset);
|
||||
pj_kn(pj, "cacheAtlasSize", cache->hdr->cacheAtlasSize);
|
||||
pj_kn(pj, "dynamicDataOffset", cache->hdr->dynamicDataOffset);
|
||||
pj_kn(pj, "dynamicDataMaxSize", cache->hdr->dynamicDataMaxSize);
|
||||
}
|
||||
pj_end(pj);
|
||||
|
||||
if (cache->accel) {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ CMDS=<<EOF
|
|||
i
|
||||
is
|
||||
iS
|
||||
iH
|
||||
iH~{}
|
||||
oml
|
||||
pi 4@ sym._what_is_cool
|
||||
EOF
|
||||
|
|
@ -17,7 +17,7 @@ mode r-x
|
|||
format dyldcache
|
||||
iorw false
|
||||
block 0x100
|
||||
type library-cache
|
||||
type production
|
||||
arch arm
|
||||
cpu N/A
|
||||
baddr 0x180000000
|
||||
|
|
@ -30,14 +30,14 @@ compiler N/A
|
|||
dbg_file N/A
|
||||
endian LE
|
||||
hdr.csum N/A
|
||||
guid N/A
|
||||
guid 857bce1a017e34649909d58ee21cf8dc
|
||||
intrp N/A
|
||||
laddr 0x00000000
|
||||
lang N/A
|
||||
machine arm
|
||||
maxopsz 4
|
||||
minopsz 4
|
||||
os Darwin
|
||||
os macOS
|
||||
cc N/A
|
||||
pcalign 4
|
||||
rpath N/A
|
||||
|
|
@ -66,7 +66,90 @@ paddr size vaddr vsize align perm name
|
|||
0x00004fb0 0x50 0x180004fb0 0x50 0x0 -r-x lib_liba-1.0.dylib.2.__TEXT.__unwind_info
|
||||
0x00008fa0 0x18 0x180008fa0 0x18 0x0 -r-x lib_libb-1.0.dylib.0.__TEXT.__text
|
||||
0x00008fb8 0x48 0x180008fb8 0x48 0x0 -r-x lib_libb-1.0.dylib.1.__TEXT.__unwind_info
|
||||
{"header":{"magic":"dyld_v1 arm64","mappingOffset":320,"mappingCount":3,"imagesOffset":656,"imagesCount":2,"dyldBaseAddress":0,"codeSignatureOffset":196608,"codeSignatureSize":16384,"slideInfoOffset":0,"slideInfoSize":0,"localSymbolsOffset":0,"localSymbolsSize":0,"uuid":"857bce1a017e34649909d58ee21cf8dc","cacheType":"production","branchPoolsOffset":0,"branchPoolsCount":0,"accelerateInfoAddr":0,"accelerateInfoSize":0,"imagesTextOffset":720,"imagesTextCount":2},"slideInfo":[{"start":98304,"end":114688,"version":2,"slide":0,"page_starts_count":4,"page_extras_count":0,"delta_mask":72056494526300160,"value_mask":18374687579183251455,"value_add":0,"delta_shift":38,"page_size":4096}],"images":[{"uuid":"ccbf29d455693a1592314e14d41a542a","address":6442455040,"textSegmentSize":16384,"path":"/usr/lib/liba-1.0.dylib","name":"liba-1.0.dylib"},{"uuid":"60d2f3d644a2391087503a56a3d8ff07","address":6442471424,"textSegmentSize":16384,"path":"/usr/lib/libb-1.0.dylib","name":"libb-1.0.dylib"}]}
|
||||
{
|
||||
"version": "<940",
|
||||
"header": {
|
||||
"magic": "dyld_v1 arm64",
|
||||
"mappingOffset": 320,
|
||||
"mappingCount": 3,
|
||||
"imagesOffset": 656,
|
||||
"imagesCount": 2,
|
||||
"dyldBaseAddress": 0,
|
||||
"codeSignatureOffset": 196608,
|
||||
"codeSignatureSize": 16384,
|
||||
"slideInfoOffset": 0,
|
||||
"slideInfoSize": 0,
|
||||
"localSymbolsOffset": 0,
|
||||
"localSymbolsSize": 0,
|
||||
"uuid": "857bce1a017e34649909d58ee21cf8dc",
|
||||
"cacheType": "production",
|
||||
"branchPoolsOffset": 0,
|
||||
"branchPoolsCount": 0,
|
||||
"accelerateInfoAddr": 0,
|
||||
"accelerateInfoSize": 0,
|
||||
"imagesTextOffset": 720,
|
||||
"imagesTextCount": 2,
|
||||
"patchInfoAddr": 6509723956,
|
||||
"patchInfoSize": 80,
|
||||
"otherImageGroupAddrUnused": 0,
|
||||
"otherImageGroupSizeUnused": 0,
|
||||
"progClosuresAddr": 6509740032,
|
||||
"progClosuresSize": 0,
|
||||
"progClosuresTrieAddr": 6509740032,
|
||||
"progClosuresTrieSize": 8,
|
||||
"platform": 1,
|
||||
"formatVersion": 10,
|
||||
"dylibsExpectedOnDisk": 0,
|
||||
"simulator": 0,
|
||||
"locallyBuiltCache": 1,
|
||||
"builtFromChainedFixups": 0,
|
||||
"padding": 0,
|
||||
"sharedRegionStart": 6442450944,
|
||||
"sharedRegionSize": 4294967296,
|
||||
"maxSlide": 2147385344,
|
||||
"dylibsImageArrayAddr": 6509723648,
|
||||
"dylibsImageArraySize": 240,
|
||||
"dylibsTrieAddr": 6509723888,
|
||||
"dylibsTrieSize": 68,
|
||||
"otherImageArrayAddr": 0,
|
||||
"otherImageArraySize": 0,
|
||||
"otherTrieAddr": 0,
|
||||
"otherTrieSize": 0,
|
||||
"mappingWithSlideOffset": 488,
|
||||
"mappingWithSlideCount": 3
|
||||
},
|
||||
"slideInfo": [
|
||||
{
|
||||
"start": 98304,
|
||||
"end": 114688,
|
||||
"version": 2,
|
||||
"slide": 0,
|
||||
"page_starts_count": 4,
|
||||
"page_extras_count": 0,
|
||||
"delta_mask": 72056494526300160,
|
||||
"value_mask": 18374687579183251455,
|
||||
"value_add": 0,
|
||||
"delta_shift": 38,
|
||||
"page_size": 4096
|
||||
}
|
||||
],
|
||||
"images": [
|
||||
{
|
||||
"uuid": "ccbf29d455693a1592314e14d41a542a",
|
||||
"address": 6442455040,
|
||||
"textSegmentSize": 16384,
|
||||
"path": "/usr/lib/liba-1.0.dylib",
|
||||
"name": "liba-1.0.dylib"
|
||||
},
|
||||
{
|
||||
"uuid": "60d2f3d644a2391087503a56a3d8ff07",
|
||||
"address": 6442471424,
|
||||
"textSegmentSize": 16384,
|
||||
"path": "/usr/lib/libb-1.0.dylib",
|
||||
"name": "libb-1.0.dylib"
|
||||
}
|
||||
]
|
||||
}
|
||||
1 fd: 4 +0x00000000 0x180000000 - 0x180017fff r-x vmap.cache_map.0
|
||||
2 fd: 4 +0x00018000 0x182018000 - 0x18201bfff r-- vmap.cache_map.1
|
||||
3 fd: 4 +0x0001c000 0x18401c000 - 0x18402ffff r-- vmap.cache_map.2
|
||||
|
|
@ -85,7 +168,7 @@ o bins/dyldcache/dyld_shared_cache_arm64-macOS
|
|||
i
|
||||
is
|
||||
iS
|
||||
iH
|
||||
iH~{}
|
||||
oml
|
||||
pi 4@ sym._what_is_cool
|
||||
EOF
|
||||
|
|
@ -98,7 +181,7 @@ mode r-x
|
|||
format dyldcache
|
||||
iorw false
|
||||
block 0x100
|
||||
type library-cache
|
||||
type production
|
||||
arch arm
|
||||
cpu N/A
|
||||
baddr 0x180000000
|
||||
|
|
@ -111,14 +194,14 @@ compiler N/A
|
|||
dbg_file N/A
|
||||
endian LE
|
||||
hdr.csum N/A
|
||||
guid N/A
|
||||
guid 857bce1a017e34649909d58ee21cf8dc
|
||||
intrp N/A
|
||||
laddr 0x00000000
|
||||
lang N/A
|
||||
machine arm
|
||||
maxopsz 4
|
||||
minopsz 4
|
||||
os Darwin
|
||||
os macOS
|
||||
cc N/A
|
||||
pcalign 4
|
||||
rpath N/A
|
||||
|
|
@ -144,7 +227,90 @@ paddr size vaddr vsize align perm name
|
|||
0x00004f60 0x48 0x180004f60 0x48 0x0 -r-x lib_liba-1.0.dylib.0.__TEXT.__text
|
||||
0x00004fa8 0x6 0x180004fa8 0x6 0x0 -r-x lib_liba-1.0.dylib.1.__TEXT.__cstring
|
||||
0x00004fb0 0x50 0x180004fb0 0x50 0x0 -r-x lib_liba-1.0.dylib.2.__TEXT.__unwind_info
|
||||
{"header":{"magic":"dyld_v1 arm64","mappingOffset":320,"mappingCount":3,"imagesOffset":656,"imagesCount":2,"dyldBaseAddress":0,"codeSignatureOffset":196608,"codeSignatureSize":16384,"slideInfoOffset":0,"slideInfoSize":0,"localSymbolsOffset":0,"localSymbolsSize":0,"uuid":"857bce1a017e34649909d58ee21cf8dc","cacheType":"production","branchPoolsOffset":0,"branchPoolsCount":0,"accelerateInfoAddr":0,"accelerateInfoSize":0,"imagesTextOffset":720,"imagesTextCount":2},"slideInfo":[{"start":98304,"end":114688,"version":2,"slide":0,"page_starts_count":4,"page_extras_count":0,"delta_mask":72056494526300160,"value_mask":18374687579183251455,"value_add":0,"delta_shift":38,"page_size":4096}],"images":[{"uuid":"ccbf29d455693a1592314e14d41a542a","address":6442455040,"textSegmentSize":16384,"path":"/usr/lib/liba-1.0.dylib","name":"liba-1.0.dylib"},{"uuid":"60d2f3d644a2391087503a56a3d8ff07","address":6442471424,"textSegmentSize":16384,"path":"/usr/lib/libb-1.0.dylib","name":"libb-1.0.dylib"}]}
|
||||
{
|
||||
"version": "<940",
|
||||
"header": {
|
||||
"magic": "dyld_v1 arm64",
|
||||
"mappingOffset": 320,
|
||||
"mappingCount": 3,
|
||||
"imagesOffset": 656,
|
||||
"imagesCount": 2,
|
||||
"dyldBaseAddress": 0,
|
||||
"codeSignatureOffset": 196608,
|
||||
"codeSignatureSize": 16384,
|
||||
"slideInfoOffset": 0,
|
||||
"slideInfoSize": 0,
|
||||
"localSymbolsOffset": 0,
|
||||
"localSymbolsSize": 0,
|
||||
"uuid": "857bce1a017e34649909d58ee21cf8dc",
|
||||
"cacheType": "production",
|
||||
"branchPoolsOffset": 0,
|
||||
"branchPoolsCount": 0,
|
||||
"accelerateInfoAddr": 0,
|
||||
"accelerateInfoSize": 0,
|
||||
"imagesTextOffset": 720,
|
||||
"imagesTextCount": 2,
|
||||
"patchInfoAddr": 6509723956,
|
||||
"patchInfoSize": 80,
|
||||
"otherImageGroupAddrUnused": 0,
|
||||
"otherImageGroupSizeUnused": 0,
|
||||
"progClosuresAddr": 6509740032,
|
||||
"progClosuresSize": 0,
|
||||
"progClosuresTrieAddr": 6509740032,
|
||||
"progClosuresTrieSize": 8,
|
||||
"platform": 1,
|
||||
"formatVersion": 10,
|
||||
"dylibsExpectedOnDisk": 0,
|
||||
"simulator": 0,
|
||||
"locallyBuiltCache": 1,
|
||||
"builtFromChainedFixups": 0,
|
||||
"padding": 0,
|
||||
"sharedRegionStart": 6442450944,
|
||||
"sharedRegionSize": 4294967296,
|
||||
"maxSlide": 2147385344,
|
||||
"dylibsImageArrayAddr": 6509723648,
|
||||
"dylibsImageArraySize": 240,
|
||||
"dylibsTrieAddr": 6509723888,
|
||||
"dylibsTrieSize": 68,
|
||||
"otherImageArrayAddr": 0,
|
||||
"otherImageArraySize": 0,
|
||||
"otherTrieAddr": 0,
|
||||
"otherTrieSize": 0,
|
||||
"mappingWithSlideOffset": 488,
|
||||
"mappingWithSlideCount": 3
|
||||
},
|
||||
"slideInfo": [
|
||||
{
|
||||
"start": 98304,
|
||||
"end": 114688,
|
||||
"version": 2,
|
||||
"slide": 0,
|
||||
"page_starts_count": 4,
|
||||
"page_extras_count": 0,
|
||||
"delta_mask": 72056494526300160,
|
||||
"value_mask": 18374687579183251455,
|
||||
"value_add": 0,
|
||||
"delta_shift": 38,
|
||||
"page_size": 4096
|
||||
}
|
||||
],
|
||||
"images": [
|
||||
{
|
||||
"uuid": "ccbf29d455693a1592314e14d41a542a",
|
||||
"address": 6442455040,
|
||||
"textSegmentSize": 16384,
|
||||
"path": "/usr/lib/liba-1.0.dylib",
|
||||
"name": "liba-1.0.dylib"
|
||||
},
|
||||
{
|
||||
"uuid": "60d2f3d644a2391087503a56a3d8ff07",
|
||||
"address": 6442471424,
|
||||
"textSegmentSize": 16384,
|
||||
"path": "/usr/lib/libb-1.0.dylib",
|
||||
"name": "libb-1.0.dylib"
|
||||
}
|
||||
]
|
||||
}
|
||||
1 fd: 4 +0x00000000 0x180000000 - 0x180017fff r-x vmap.cache_map.0
|
||||
2 fd: 4 +0x00018000 0x182018000 - 0x18201bfff r-- vmap.cache_map.1
|
||||
3 fd: 4 +0x0001c000 0x18401c000 - 0x18402ffff r-- vmap.cache_map.2
|
||||
|
|
@ -177,7 +343,7 @@ mode r-x
|
|||
format dyldcache
|
||||
iorw false
|
||||
block 0x100
|
||||
type library-cache
|
||||
type production
|
||||
arch arm
|
||||
cpu N/A
|
||||
baddr 0x180000000
|
||||
|
|
@ -190,14 +356,14 @@ compiler N/A
|
|||
dbg_file N/A
|
||||
endian LE
|
||||
hdr.csum N/A
|
||||
guid N/A
|
||||
guid 0051c062211e3a669af7d590307d245c
|
||||
intrp N/A
|
||||
laddr 0x00000000
|
||||
lang N/A
|
||||
machine arm
|
||||
maxopsz 4
|
||||
minopsz 4
|
||||
os Darwin
|
||||
os macOS
|
||||
cc N/A
|
||||
pcalign 4
|
||||
rpath N/A
|
||||
|
|
@ -270,7 +436,7 @@ mode r-x
|
|||
format dyldcache
|
||||
iorw false
|
||||
block 0x100
|
||||
type library-cache
|
||||
type production
|
||||
arch arm
|
||||
cpu N/A
|
||||
baddr 0x180000000
|
||||
|
|
@ -283,14 +449,14 @@ compiler N/A
|
|||
dbg_file N/A
|
||||
endian LE
|
||||
hdr.csum N/A
|
||||
guid N/A
|
||||
guid b3d4bd16c88a378c961fcfefb34344b9
|
||||
intrp N/A
|
||||
laddr 0x00000000
|
||||
lang N/A
|
||||
machine arm
|
||||
maxopsz 4
|
||||
minopsz 4
|
||||
os Darwin
|
||||
os macOS
|
||||
cc N/A
|
||||
pcalign 4
|
||||
rpath N/A
|
||||
|
|
@ -434,4 +600,190 @@ q
|
|||
EOF
|
||||
EXPECT=<<EOF
|
||||
EOF
|
||||
RUN
|
||||
RUN
|
||||
|
||||
NAME=dyldcache 1042.1 header
|
||||
FILE=bins/dyldcache/dyld_shared_cache_arm64-macOS-1042.1
|
||||
CMDS=<<EOF
|
||||
i
|
||||
is
|
||||
iS
|
||||
iH~{}
|
||||
oml
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
fd 3
|
||||
file bins/dyldcache/dyld_shared_cache_arm64-macOS-1042.1
|
||||
size 0x20000
|
||||
humansz 128K
|
||||
mode r-x
|
||||
format dyldcache
|
||||
iorw false
|
||||
block 0x100
|
||||
type development
|
||||
arch arm
|
||||
cpu N/A
|
||||
baddr 0x180000000
|
||||
binsz 0x00020000
|
||||
bintype N/A
|
||||
bits 64
|
||||
retguard false
|
||||
class dyldcache
|
||||
compiler N/A
|
||||
dbg_file N/A
|
||||
endian LE
|
||||
hdr.csum N/A
|
||||
guid c0a042e3c0db394caa455cd7e767643f
|
||||
intrp N/A
|
||||
laddr 0x00000000
|
||||
lang N/A
|
||||
machine arm
|
||||
maxopsz 4
|
||||
minopsz 4
|
||||
os macOS
|
||||
cc N/A
|
||||
pcalign 4
|
||||
rpath N/A
|
||||
subsys xnu
|
||||
stripped false
|
||||
crypto false
|
||||
havecode true
|
||||
va true
|
||||
sanitiz false
|
||||
static true
|
||||
linenum false
|
||||
lsyms false
|
||||
canary false
|
||||
PIE false
|
||||
RELROCS false
|
||||
NX false
|
||||
nth paddr vaddr bind type size lib name
|
||||
--------------------------------------------------------------------------
|
||||
0 0x00007fb4 0x180007fb4 GLOBAL FUNC 0 _i_am_libSystem
|
||||
0 0x0000bfb0 0x18000bfb0 GLOBAL FUNC 0 _say_hello
|
||||
0 0x0000ff38 0x18000ff38 GLOBAL FUNC 0 dyld3::entryVectorForDyld
|
||||
1 0x0000ff34 0x18000ff34 GLOBAL FUNC 0 _i_am_libdyld
|
||||
0 0x00013fb4 0x180013fb4 GLOBAL FUNC 0 _i_am_libsystem_kernel
|
||||
paddr size vaddr vsize align perm name type flags
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
0x00007fb4 0x4 0x180007fb4 0x4 0x0 -r-x lib_libSystem.B.dylib.0.__TEXT.__text
|
||||
0x00007fb8 0x48 0x180007fb8 0x48 0x0 -r-x lib_libSystem.B.dylib.1.__TEXT.__unwind_info
|
||||
0x0000bfb0 0x8 0x18000bfb0 0x8 0x0 -r-x lib_libhello.dylib.0.__TEXT.__text
|
||||
0x0000bfb8 0x48 0x18000bfb8 0x48 0x0 -r-x lib_libhello.dylib.1.__TEXT.__unwind_info
|
||||
0x0000ff34 0x4 0x18000ff34 0x4 0x0 -r-x system_libdyld.dylib.0.__TEXT.__text
|
||||
0x0000ff38 0x80 0x18000ff38 0x80 0x0 -r-x system_libdyld.dylib.1.__TEXT.__const
|
||||
0x0000ffb8 0x48 0x18000ffb8 0x48 0x0 -r-x system_libdyld.dylib.2.__TEXT.__unwind_info
|
||||
0x00013fb4 0x4 0x180013fb4 0x4 0x0 -r-x system_libsystem_kernel.dylib.0.__TEXT.__text
|
||||
0x00013fb8 0x48 0x180013fb8 0x48 0x0 -r-x system_libsystem_kernel.dylib.1.__TEXT.__unwind_info
|
||||
{
|
||||
"version": "1042.1",
|
||||
"header": {
|
||||
"magic": "dyld_v1 arm64",
|
||||
"mappingOffset": 512,
|
||||
"mappingCount": 2,
|
||||
"imagesOffset": 736,
|
||||
"imagesCount": 4,
|
||||
"dyldBaseAddress": 0,
|
||||
"codeSignatureOffset": 114688,
|
||||
"codeSignatureSize": 16384,
|
||||
"slideInfoOffset": 0,
|
||||
"slideInfoSize": 0,
|
||||
"localSymbolsOffset": 0,
|
||||
"localSymbolsSize": 0,
|
||||
"uuid": "c0a042e3c0db394caa455cd7e767643f",
|
||||
"cacheType": "development",
|
||||
"branchPoolsOffset": 0,
|
||||
"branchPoolsCount": 0,
|
||||
"dyldInCacheMH": 0,
|
||||
"dyldInCacheEntry": 0,
|
||||
"imagesTextOffset": 864,
|
||||
"imagesTextCount": 4,
|
||||
"patchInfoAddr": 6442532976,
|
||||
"patchInfoSize": 264,
|
||||
"otherImageGroupAddrUnused": 0,
|
||||
"otherImageGroupSizeUnused": 0,
|
||||
"progClosuresAddr": 0,
|
||||
"progClosuresSize": 0,
|
||||
"progClosuresTrieAddr": 0,
|
||||
"progClosuresTrieSize": 0,
|
||||
"platform": 1,
|
||||
"formatVersion": 0,
|
||||
"dylibsExpectedOnDisk": 0,
|
||||
"simulator": 0,
|
||||
"locallyBuiltCache": 1,
|
||||
"builtFromChainedFixups": 0,
|
||||
"padding": 0,
|
||||
"sharedRegionStart": 6442450944,
|
||||
"sharedRegionSize": 131072,
|
||||
"maxSlide": 2147401728,
|
||||
"dylibsImageArrayAddr": 0,
|
||||
"dylibsImageArraySize": 0,
|
||||
"dylibsTrieAddr": 6442532864,
|
||||
"dylibsTrieSize": 112,
|
||||
"otherImageArrayAddr": 0,
|
||||
"otherImageArraySize": 0,
|
||||
"otherTrieAddr": 0,
|
||||
"otherTrieSize": 0,
|
||||
"mappingWithSlideOffset": 624,
|
||||
"mappingWithSlideCount": 2,
|
||||
"dylibsPBLStateArrayAddrUnused": 0,
|
||||
"dylibsPBLSetAddr": 6442533240,
|
||||
"programsPBLSetPoolAddr": 6442534280,
|
||||
"programsPBLSetPoolSize": 16384,
|
||||
"programTrieAddr": 6442550664,
|
||||
"programTrieSize": 88,
|
||||
"osVersion": 851968,
|
||||
"altPlatform": 0,
|
||||
"altOsVersion": 0,
|
||||
"swiftOptsOffset": 0,
|
||||
"swiftOptsSize": 0,
|
||||
"subCacheArrayOffset": 992,
|
||||
"subCacheArrayCount": 0,
|
||||
"symbolFileUUID": "00000000000000000000000000000000",
|
||||
"rosettaReadOnlyAddr": 0,
|
||||
"rosettaReadOnlySize": 0,
|
||||
"rosettaReadWriteAddr": 0,
|
||||
"rosettaReadWriteSize": 0,
|
||||
"cacheSubType": 0,
|
||||
"objcOptsOffset": 0,
|
||||
"objcOptsSize": 0,
|
||||
"cacheAtlasOffset": 0,
|
||||
"cacheAtlasSize": 0,
|
||||
"dynamicDataOffset": 114688,
|
||||
"dynamicDataMaxSize": 16384
|
||||
},
|
||||
"images": [
|
||||
{
|
||||
"uuid": "e0a310e1c61e3b289c5df43f04e71a44",
|
||||
"address": 6442467328,
|
||||
"textSegmentSize": 16384,
|
||||
"path": "/usr/lib/libSystem.B.dylib",
|
||||
"name": "libSystem.B.dylib"
|
||||
},
|
||||
{
|
||||
"uuid": "f2c8e54bd02937e69928edd8b4bbec63",
|
||||
"address": 6442483712,
|
||||
"textSegmentSize": 16384,
|
||||
"path": "/usr/lib/libhello.dylib",
|
||||
"name": "libhello.dylib"
|
||||
},
|
||||
{
|
||||
"uuid": "439351ae77ca308ebf1da32729a79709",
|
||||
"address": 6442500096,
|
||||
"textSegmentSize": 16384,
|
||||
"path": "/usr/lib/system/libdyld.dylib",
|
||||
"name": "libdyld.dylib"
|
||||
},
|
||||
{
|
||||
"uuid": "4ce071b5dd373397aca699d517bdb6e7",
|
||||
"address": 6442516480,
|
||||
"textSegmentSize": 16384,
|
||||
"path": "/usr/lib/system/libsystem_kernel.dylib",
|
||||
"name": "libsystem_kernel.dylib"
|
||||
}
|
||||
]
|
||||
}
|
||||
1 fd: 3 +0x00000000 0x180000000 - 0x180013fff r-x fmap.cache_map.0
|
||||
2 fd: 3 +0x00014000 0x180014000 - 0x18001bfff r-- fmap.cache_map.1
|
||||
EOF
|
||||
RUN
|
||||
|
|
|
|||
Loading…
Reference in a new issue