Loading...
--- dyld/dyld-1162/common/ProcessAtlas.cpp
+++ dyld/dyld-1241.17/common/ProcessAtlas.cpp
@@ -79,6 +79,8 @@
#define _transactionalAllocator Allocator::defaultAllocator()
#endif
+#define BLEND_KERN_RETURN_LOCATION(kr, loc) (kr) = ((kr & 0x00ffffff) | loc<<24);
+
namespace {
static const size_t kCachePeekSize = 0x4000;
@@ -421,7 +423,7 @@
}
// mmap whole file temporarily
- void* tempMapping = ::mmap(nullptr, (size_t)sb.st_size, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);
+ void* tempMapping = ::mmap(nullptr, (size_t)sb.st_size, PROT_READ, MAP_FILE | MAP_PRIVATE | MAP_RESILIENT_CODESIGN, fd, 0);
if ( tempMapping == MAP_FAILED ) {
::close(fd);
return nullptr;
@@ -524,14 +526,14 @@
off_t roundedOffset = offset & (-1*PAGE_SIZE);
extraBytes = (size_t)offset - (size_t)roundedOffset;
newMapping = mmap(nullptr, (size_t)size+extraBytes, PROT_READ, MAP_FILE | MAP_PRIVATE, mapping.fd, roundedOffset);
- if (newMapping == (void*)-1) {
+ if (newMapping == MAP_FAILED) {
// fprintf(stderr, "mmap failed: %s (%d)\n", strerror(errno), errno);
- return {(void*)1, false};
+ return {nullptr, false};
}
return {(void*)((uintptr_t)newMapping+extraBytes),true};
}
}
- return {(void*)-1, false};
+ return {nullptr, false};
}
void Mapper::unmap(const void* addr, uint64_t size) const {
@@ -594,10 +596,10 @@
if (fileID.inode() && fileID.device()) {
_file = state->fileManager.fileRecordForFileID(ldr->fileID(*state));
if ( _file.volume().empty() ) {
- _file = state->fileManager.fileRecordForPath(ephemeralAllocator, ldr->path());
+ _file = state->fileManager.fileRecordForPath(ephemeralAllocator, ldr->path(*state));
}
} else {
- _file = state->fileManager.fileRecordForPath(ephemeralAllocator, ldr->path());
+ _file = state->fileManager.fileRecordForPath(ephemeralAllocator, ldr->path(*state));
}
}
#endif
@@ -654,6 +656,10 @@
return nullptr;
}
_ml = _mapper->map<MachOLoaded>(slidML, 4096);
+ if (!_ml) {
+ _mapperFailed = true;
+ return nullptr;
+ }
size_t size = _ml->sizeofcmds;
if ( _ml->magic == MH_MAGIC_64 ) {
size += sizeof(mach_header_64);
@@ -662,6 +668,10 @@
}
if (size > 4096) {
_ml = _mapper->map<MachOLoaded>(slidML, size);
+ if (!_ml) {
+ _mapperFailed = true;
+ return nullptr;
+ }
}
}
// This is a bit of a mess. With compact info this will be unified, but for now we use a lot of hacky abstactions here to deal with
@@ -1229,6 +1239,8 @@
pid_t pid;
*kr = pid_for_task(_task, &pid);
if ( *kr != KERN_SUCCESS ) {
+ BLEND_KERN_RETURN_LOCATION(*kr, 0xea);
+ *kr |= 0xeb000000UL;
return nullptr;
}
@@ -1236,6 +1248,7 @@
mach_msg_type_number_t count = MACH_TASK_BASIC_INFO_COUNT;
*kr = task_info(_task, MACH_TASK_BASIC_INFO, (task_info_t)&ti, &count);
if ( *kr != KERN_SUCCESS ) {
+ BLEND_KERN_RETURN_LOCATION(*kr, 0xe9);
return nullptr;
}
@@ -1259,6 +1272,7 @@
mach_vm_size_t readSize = 0;
*kr = mach_vm_read_overwrite(_task, address, size, (mach_vm_address_t)&unsafeBytes[0], &readSize);
if ( *kr != KERN_SUCCESS ) {
+ BLEND_KERN_RETURN_LOCATION(*kr, 0xe8);
return;
}
auto mf = MachOFile::isMachO((const void*)unsafeBytes);
@@ -1319,10 +1333,12 @@
task_dyld_info_data_t task_dyld_info;
*kr = task_info(_task, TASK_DYLD_INFO, (task_info_t)&task_dyld_info, &count);
if ( *kr != KERN_SUCCESS ) {
+ BLEND_KERN_RETURN_LOCATION(*kr, 0xef);
return nullptr;
}
//The kernel will return MACH_VM_MIN_ADDRESS for an executable that has not had dyld loaded
if (task_dyld_info.all_image_info_addr == MACH_VM_MIN_ADDRESS) {
+ BLEND_KERN_RETURN_LOCATION(*kr, 0xee);
return nullptr;
}
uint8_t remoteBuffer[16*1024];
@@ -1333,6 +1349,7 @@
*kr = mach_vm_read_overwrite(_task, task_dyld_info.all_image_info_addr, task_dyld_info.all_image_info_size,
(mach_vm_address_t)&remoteBuffer[0], &readSize);
if (*kr != KERN_SUCCESS) {
+ BLEND_KERN_RETURN_LOCATION(*kr, 0xed);
// If we cannot read the all image info this is game over
return nullptr;
}
@@ -1353,6 +1370,7 @@
auto compactInfo = UniquePtr<std::byte>((std::byte*)_transactionalAllocator.malloc((size_t)compactInfoSize));
*kr = mach_vm_read_overwrite(_task, compactInfoAddress, compactInfoSize, (mach_vm_address_t)&*compactInfo, &readSize);
if (*kr != KERN_SUCCESS) {
+ BLEND_KERN_RETURN_LOCATION(*kr, 0xec);
// The read failed, chances are the process mutated the compact info, retry
continue;
}
@@ -1361,6 +1379,7 @@
if (!result->valid()) {
// Something blew up we don't know what
*kr = KERN_FAILURE;
+ BLEND_KERN_RETURN_LOCATION(*kr, 0xeb);
return nullptr;
}
return result;
@@ -1719,8 +1738,8 @@
_bitmap = _transactionalAllocator.makeUnique<Bitmap>(_transactionalAllocator, _sharedCache->imageCount());
}
+/// Assumes the mach_header parameter is in the range of the shared cache. Otherwise asserts
void ProcessSnapshot::addSharedCacheImage(const struct mach_header* mh) {
- assert(mh->flags & MH_DYLIB_IN_CACHE);
auto header = (dyld_cache_header*)_sharedCache->rebasedAddress();
auto headerBytes = (uint8_t*)header;
auto slide = (uint64_t)header - header->sharedRegionStart;