Created
March 8, 2012 09:14
-
-
Save emonti/1999839 to your computer and use it in GitHub Desktop.
dyldcache.c dyld_shared_cache dumper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdint.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <string.h> | |
#include <fcntl.h> | |
#include <sys/mman.h> | |
#include <sys/stat.h> | |
struct dyld_cache_header | |
{ | |
char magic[16]; // e.g. "dyld_v0 ppc" | |
uint32_t mappingOffset; // file offset to first shared_file_mapping | |
uint32_t mappingCount; // number of shared_file_mapping entries | |
uint32_t imagesOffset; // file offset to first dyld_cache_image_info | |
uint32_t imagesCount; // number of dyld_cache_image_info entries | |
uint64_t dyldBaseAddress; // base address of dyld when cache was built | |
uint64_t codeSignOffset; // speculation? | |
}; | |
struct shared_file_mapping { | |
uint64_t address; | |
uint64_t size; | |
uint64_t file_offset; | |
uint32_t max_prot; | |
uint32_t init_prot; | |
}; | |
struct dyld_cache_image_info | |
{ | |
uint64_t address; | |
uint64_t modTime; | |
uint64_t inode; | |
uint32_t pathFileOffset; | |
uint32_t pad; | |
}; | |
void dump_dyld_shared_cache(void *data, size_t fsize) { | |
struct dyld_cache_header *header = data; | |
size_t i; | |
printf("dyld_cache_header:\n"); | |
printf(" magic = %s\n", header->magic); | |
printf(" mappingOffset = 0x%08lx\n", header->mappingOffset); | |
printf(" mappingCount = %lu\n", header->mappingCount); | |
printf(" imagesOffset = 0x%08lx\n", header->imagesOffset); | |
printf(" imagesCount = %lu\n", header->imagesCount); | |
printf(" dyldBaseAddress = 0x%08llx\n", header->dyldBaseAddress); | |
printf(" codesignOffset = 0x%08llx\n\n", header->codeSignOffset); | |
struct shared_file_mapping *sfm = data + header->mappingOffset; | |
for (i=0; i < header->mappingCount; i++) { | |
printf("shared_file_mapping[%i]:\n", i); | |
printf(" address = 0x%08llx\n", sfm->address); | |
printf(" size = 0x%08llx\n", sfm->size); | |
printf(" file_offset = 0x%08llx\n", sfm->file_offset); | |
printf(" max_prot = 0x%08lx\n", sfm->max_prot); | |
printf(" init_prot = 0x%08lx\n\n", sfm->init_prot); | |
sfm ++; | |
} | |
struct dyld_cache_image_info *dcimg = data + header->imagesOffset; | |
for (i=0; i < header->imagesCount; i++) { | |
printf("dyld_cache_image_info[%i]:\n", i); | |
printf(" pathFileOff = 0x%08lx\n", dcimg->pathFileOffset); | |
printf(" pathFile = %s\n", (char *)data+dcimg->pathFileOffset); | |
printf(" address = 0x%08lx\n", dcimg->address); | |
printf(" modTime = 0x%08lx\n", dcimg->modTime); | |
printf(" inode = 0x%08lx\n", dcimg->inode); | |
dcimg++; | |
} | |
} | |
void dump_dyld_shared_cache_file(char *fname) { | |
void *cachedata; | |
struct stat st; | |
int fd; | |
if ((fd = open(fname, O_RDONLY)) >=0 ) { | |
if (fstat(fd, &st) >= 0) { | |
cachedata = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); | |
if (cachedata) { | |
dump_dyld_shared_cache(cachedata, st.st_size); | |
munmap(cachedata, st.st_size); | |
} | |
else | |
perror("Cannot mmap()"); | |
} else { | |
perror("Cannot fstat() file-descriptor"); | |
} | |
close(fd); | |
} else { | |
perror("Cannot open file"); | |
} | |
} | |
int main(int argc, char **argv) { | |
int i; | |
for (i=1; i < argc; i++) | |
dump_dyld_shared_cache_file(argv[i]); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment