mirror of
https://github.com/ish-app/ish.git
synced 2026-01-25 14:06:40 +00:00
A bunch of people have tried to build the app from source and got confused when it crashed, because they customized the app group but didn't update the preprocessor macro. Now the app reads its app group off the mach-o on disk. This also fixes AltStore, which has to change app group names too. Fixes #650
98 lines
3.0 KiB
Objective-C
98 lines
3.0 KiB
Objective-C
//
|
|
// AppGroup.m
|
|
// iSH
|
|
//
|
|
// Created by Theodore Dubois on 2/28/20.
|
|
//
|
|
|
|
#import <Foundation/Foundation.h>
|
|
#include <mach-o/loader.h>
|
|
#include <dlfcn.h>
|
|
|
|
struct cs_blob_index {
|
|
uint32_t type;
|
|
uint32_t offset;
|
|
};
|
|
|
|
struct cs_superblob {
|
|
uint32_t magic;
|
|
uint32_t length;
|
|
uint32_t count;
|
|
struct cs_blob_index index[];
|
|
};
|
|
|
|
struct cs_entitlements {
|
|
uint32_t magic;
|
|
uint32_t length;
|
|
char entitlements[];
|
|
};
|
|
|
|
static NSDictionary *AppEntitlements() {
|
|
static NSDictionary *entitlements;
|
|
if (entitlements != nil)
|
|
return entitlements;
|
|
|
|
// Inspired by codesign.c in Darwin sources for Security.framework
|
|
|
|
// Find our mach-o header
|
|
Dl_info dl_info;
|
|
if (dladdr(AppEntitlements, &dl_info) == 0)
|
|
return nil;
|
|
if (dl_info.dli_fbase == NULL)
|
|
return nil;
|
|
uint8_t *base = dl_info.dli_fbase;
|
|
struct mach_header_64 *header = dl_info.dli_fbase;
|
|
if (header->magic != MH_MAGIC_64)
|
|
return nil;
|
|
|
|
// Find the LC_CODE_SIGNATURE
|
|
struct load_command *lc = (void *) (base + sizeof(*header));
|
|
struct linkedit_data_command *cs_lc = NULL;
|
|
for (uint32_t i = 0; i < header->ncmds; i++) {
|
|
if (lc->cmd == LC_CODE_SIGNATURE) {
|
|
cs_lc = (void *) lc;
|
|
break;
|
|
}
|
|
lc = (void *) ((uint8_t *) lc + lc->cmdsize);
|
|
}
|
|
if (cs_lc == NULL)
|
|
return nil;
|
|
|
|
// Read the code signature off disk, as it's apparently not loaded into memory
|
|
NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingFromURL:NSBundle.mainBundle.executableURL error:nil];
|
|
if (fileHandle == nil)
|
|
return nil;
|
|
[fileHandle seekToFileOffset:cs_lc->dataoff];
|
|
NSData *csData = [fileHandle readDataOfLength:cs_lc->datasize];
|
|
[fileHandle closeFile];
|
|
const struct cs_superblob *cs = csData.bytes;
|
|
if (ntohl(cs->magic) != 0xfade0cc0)
|
|
return nil;
|
|
|
|
// Find the entitlements in the code signature
|
|
NSData *entitlementsData = nil;
|
|
for (uint32_t i = 0; i < ntohl(cs->count); i++) {
|
|
struct cs_entitlements *ents = (void *) ((uint8_t *) cs + ntohl(cs->index[i].offset));
|
|
if (ntohl(ents->magic) == 0xfade7171) {
|
|
entitlementsData = [NSData dataWithBytes:ents->entitlements
|
|
length:ntohl(ents->length) - offsetof(struct cs_entitlements, entitlements)];
|
|
}
|
|
}
|
|
if (entitlementsData == nil)
|
|
return nil;
|
|
|
|
return entitlements = [NSPropertyListSerialization propertyListWithData:entitlementsData
|
|
options:NSPropertyListImmutable
|
|
format:nil
|
|
error:nil];
|
|
}
|
|
|
|
NSArray<NSString *> *CurrentAppGroups() {
|
|
return AppEntitlements()[@"com.apple.security.application-groups"];
|
|
}
|
|
|
|
NSURL *ContainerURL() {
|
|
NSString *appGroup = CurrentAppGroups()[0];
|
|
return [NSFileManager.defaultManager containerURLForSecurityApplicationGroupIdentifier:appGroup];
|
|
}
|