add data
This commit is contained in:
102
data/dyldcache/binary.c
Normal file
102
data/dyldcache/binary.c
Normal file
@ -0,0 +1,102 @@
|
||||
#include "binary.h"
|
||||
#include "../mach-o/headers/loader.h"
|
||||
#include "headers/dyld_cache_format.h"
|
||||
|
||||
#define downcast(val, typ) ({ typeof(val) v = (val); typ t = (typ) v; if(t != v) die("out of range %s", #val); t; })
|
||||
|
||||
void b_prange_load_dyldcache(struct binary *binary, prange_t pr, const char *name) {
|
||||
#define _arg name
|
||||
|
||||
binary->valid = true;
|
||||
binary->pointer_size = 4;
|
||||
binary->dyld = calloc(1, sizeof(*binary->dyld));
|
||||
binary->valid_range = pr;
|
||||
|
||||
if(pr.size < sizeof(*binary->dyld->hdr)) {
|
||||
die("truncated (no room for dyld cache header)");
|
||||
}
|
||||
binary->dyld->hdr = pr.start;
|
||||
|
||||
if(memcmp(binary->dyld->hdr->magic, "dyld_", 5)) {
|
||||
die("not a dyld cache");
|
||||
}
|
||||
char *thing = binary->dyld->hdr->magic + sizeof(binary->dyld->hdr->magic) - 7;
|
||||
if(!memcmp(thing, " armv7", 7)) {
|
||||
binary->cputype = CPU_TYPE_ARM;
|
||||
binary->cpusubtype = CPU_SUBTYPE_ARM_V7;
|
||||
} else if(!memcmp(thing, " armv6", 7)) {
|
||||
binary->cputype = CPU_TYPE_ARM;
|
||||
binary->cpusubtype = CPU_SUBTYPE_ARM_V6;
|
||||
} else {
|
||||
die("unknown processor in magic: %.6s", thing);
|
||||
}
|
||||
|
||||
if(binary->dyld->hdr->mappingCount > 1000) {
|
||||
die("insane mapping count: %u", binary->dyld->hdr->mappingCount);
|
||||
}
|
||||
binary->nsegments = binary->dyld->hdr->mappingCount;
|
||||
binary->segments = malloc(sizeof(*binary->segments) * binary->nsegments);
|
||||
struct shared_file_mapping_np *mappings = rangeconv_off((range_t) {binary, binary->dyld->hdr->mappingOffset, binary->dyld->hdr->mappingCount * sizeof(struct shared_file_mapping_np)}, MUST_FIND).start;
|
||||
for(uint32_t i = 0; i < binary->dyld->hdr->mappingCount; i++) {
|
||||
struct data_segment *seg = &binary->segments[i];
|
||||
seg->vm_range.binary = seg->file_range.binary = binary;
|
||||
seg->native_segment = &mappings[i];
|
||||
seg->vm_range.start = downcast(mappings[i].sfm_address, addr_t);
|
||||
seg->file_range.start = downcast(mappings[i].sfm_file_offset, addr_t);
|
||||
seg->file_range.size = seg->vm_range.size = downcast(mappings[i].sfm_size, size_t);
|
||||
}
|
||||
|
||||
|
||||
for(unsigned int i = 0; i < binary->dyld->nmappings; i++) {
|
||||
struct shared_file_mapping_np *mapping = &binary->dyld->mappings[i];
|
||||
if(mapping->sfm_file_offset >= pr.size || mapping->sfm_size > pr.size - mapping->sfm_file_offset) {
|
||||
die("truncated (no room for dyld cache mapping %d)", i);
|
||||
}
|
||||
}
|
||||
#undef _arg
|
||||
}
|
||||
|
||||
void b_dyldcache_load_macho(const struct binary *binary, const char *filename, struct binary *out) {
|
||||
if(binary == out) {
|
||||
die("uck");
|
||||
}
|
||||
|
||||
if(binary->dyld->hdr->imagesCount > 1000) {
|
||||
die("insane images count");
|
||||
}
|
||||
|
||||
struct dyld_cache_image_info *info = rangeconv_off((range_t) {binary, binary->dyld->hdr->imagesOffset, binary->dyld->hdr->imagesCount * sizeof(*info)}, MUST_FIND).start;
|
||||
for(unsigned int i = 0; i < binary->dyld->hdr->imagesCount; i++) {
|
||||
char *name = rangeconv_off((range_t) {binary, info[i].pathFileOffset, 128}, MUST_FIND).start;
|
||||
|
||||
if(strncmp(name, filename, 128)) {
|
||||
continue;
|
||||
}
|
||||
// we found it
|
||||
b_prange_load_macho(out, binary->valid_range,range_to_off_range((range_t) {binary, (uint32_t) info[i].address, 0}, MUST_FIND).start, filename);
|
||||
|
||||
// look for reexports (maybe blowing the stack)
|
||||
int count = 0;
|
||||
CMD_ITERATE(b_mach_hdr(out), cmd) {
|
||||
if(cmd->cmd == LC_REEXPORT_DYLIB) count++;
|
||||
}
|
||||
if(count > 0 && count < 1000) {
|
||||
out->nreexports = (unsigned int) count;
|
||||
struct binary *p = out->reexports = malloc(out->nreexports * sizeof(struct binary));
|
||||
CMD_ITERATE(b_mach_hdr(out), cmd) {
|
||||
if(cmd->cmd == LC_REEXPORT_DYLIB) {
|
||||
const char *name = convert_lc_str(cmd, ((struct dylib_command *) cmd)->dylib.name.offset);
|
||||
b_dyldcache_load_macho(binary, name, p);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
die("couldn't find %s in dyld cache", filename);
|
||||
}
|
||||
|
||||
void b_load_dyldcache(struct binary *binary, const char *filename) {
|
||||
return b_prange_load_dyldcache(binary, load_file(filename, true, NULL), filename);
|
||||
}
|
20
data/dyldcache/binary.h
Normal file
20
data/dyldcache/binary.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
#include "../binary.h"
|
||||
#include "../mach-o/binary.h"
|
||||
|
||||
struct dyldcache_binary {
|
||||
struct dyld_cache_header *hdr;
|
||||
struct shared_file_mapping_np *mappings;
|
||||
uint32_t nmappings;
|
||||
struct shared_file_mapping_np *last_sfm;
|
||||
};
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
void b_prange_load_dyldcache(struct binary *binary, prange_t range, const char *name);
|
||||
void b_dyldcache_load_macho(const struct binary *binary, const char *filename, struct binary *out);
|
||||
|
||||
void b_load_dyldcache(struct binary *binary, const char *filename);
|
||||
|
||||
|
||||
__END_DECLS
|
52
data/dyldcache/headers/dyld_cache_format.h
Normal file
52
data/dyldcache/headers/dyld_cache_format.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
struct shared_file_mapping_np {
|
||||
uint64_t sfm_address;
|
||||
uint64_t sfm_size;
|
||||
uint64_t sfm_file_offset;
|
||||
int sfm_max_prot;
|
||||
int sfm_init_prot;
|
||||
};
|
||||
|
||||
// v1 apparently has some extra gunk at the end, oh well
|
||||
struct dyld_cache_header
|
||||
{
|
||||
char magic[16]; // e.g. "dyld_v0 ppc"
|
||||
uint32_t mappingOffset; // file offset to first shared_file_mapping_np
|
||||
uint32_t mappingCount; // number of shared_file_mapping_np 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
|
||||
};
|
||||
|
||||
struct dyld_cache_image_info
|
||||
{
|
||||
uint64_t address;
|
||||
uint64_t modTime;
|
||||
uint64_t inode;
|
||||
uint32_t pathFileOffset;
|
||||
uint32_t pad;
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user