Skip to content

Commit

Permalink
Fix DSC locker not working on iOS 16, use ChOma for it instead
Browse files Browse the repository at this point in the history
  • Loading branch information
opa334 committed Jan 2, 2025
1 parent 55fa1d2 commit c7ce08c
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 137 deletions.
2 changes: 1 addition & 1 deletion BaseBin/ChOma
29 changes: 16 additions & 13 deletions BaseBin/launchdhook/src/main.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#import <libjailbreak/libjailbreak.h>
#import <libjailbreak/util.h>
#import <libjailbreak/kernel.h>
#import <libjailbreak/dsc_mlock.h>
#import <mach-o/dyld.h>
#import <spawn.h>
#import <substrate.h>
Expand Down Expand Up @@ -79,22 +80,24 @@
initDSCHooks();
initJetsamHook();

// If enabled, reenable oldabi support
jb_set_oldabi_support_enabled(gSystemInfo.jailbreakSettings.oldAbiSupportEnabled);
if (!firstLoad) {
// If enabled, reenable oldabi support
jb_set_oldabi_support_enabled(gSystemInfo.jailbreakSettings.oldAbiSupportEnabled);

#ifdef __arm64e__
if (__builtin_available(iOS 16.0, *)) { /* fall through */ }
else {
// Spinlock panics happen when a lot of processes try to fault in the same TEXT page at the same time
// For some reason, in all panics I personally looked at, the page is inside one of these 5 libraries
// If we mlock all of them (to prevent them from ever being paged out), we can reduce spinlock panics by a significant amount
mlock_library("/System/Library/PrivateFrameworks/BackBoardServices.framework/BackBoardServices");
mlock_library("/System/Library/PrivateFrameworks/HMFoundation.framework/HMFoundation");
mlock_library("/System/Library/PrivateFrameworks/GeoServices.framework/GeoServices");
mlock_library("/System/Library/PrivateFrameworks/BluetoothManager.framework/BluetoothManager");
mlock_library("/System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguration");
}
if (__builtin_available(iOS 16.0, *)) { /* fall through */ }
else {
// Spinlock panics happen when a lot of processes try to fault in the same TEXT page at the same time
// For some reason, in all panics I personally looked at, the page is inside one of these 5 libraries
// If we mlock all of them (to prevent them from ever being paged out), we can reduce spinlock panics by a significant amount
dsc_mlock_library_exec("/System/Library/PrivateFrameworks/BackBoardServices.framework/BackBoardServices");
dsc_mlock_library_exec("/System/Library/PrivateFrameworks/HMFoundation.framework/HMFoundation");
dsc_mlock_library_exec("/System/Library/PrivateFrameworks/GeoServices.framework/GeoServices");
dsc_mlock_library_exec("/System/Library/PrivateFrameworks/BluetoothManager.framework/BluetoothManager");
dsc_mlock_library_exec("/System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguration");
}
#endif
}

// This will ensure launchdhook is always reinjected after userspace reboots
// As this launchd will pass environ to the next launchd...
Expand Down
3 changes: 2 additions & 1 deletion BaseBin/launchdhook/src/oldabi.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "oldabi.h"
#include <libjailbreak/dsc_mlock.h>
#include <libjailbreak/util.h>
#include <libjailbreak/primitives.h>
#include <mach-o/getsect.h>
Expand All @@ -17,7 +18,7 @@ int oldabi_patch_library(const char *name, void **backupdata, size_t *backupsize
memcpy(*backupdata, instructions, sectionSize);
}

mlock_dsc(instructions, sectionSize);
dsc_mlock(instructions, sectionSize);

for (int i = 0; i < (sectionSize / sizeof(uint32_t)); i++) {
if ((instructions[i] & 0xfffffc00) == 0xdac11800) {
Expand Down
2 changes: 1 addition & 1 deletion BaseBin/launchdhook/src/oldabi.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#import <stdbool.h>
#include <stdbool.h>

int jb_set_oldabi_support_enabled(bool enabled);
bool jb_is_oldabi_fix_enabled(void);
4 changes: 2 additions & 2 deletions BaseBin/libjailbreak/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ ADDITIONAL_FLAGS = -g

CC = clang

CFLAGS = -framework Foundation -framework CoreServices -framework Security -framework IOKit -framework IOSurface -I../.include -isysroot $(shell xcrun --sdk iphoneos --show-sdk-path) -arch arm64 -arch arm64e -miphoneos-version-min=15.0 -fobjc-arc -dynamiclib -install_name @loader_path/$(TARGET) -I$(shell brew --prefix)/opt/libarchive/include $(ADDITIONAL_FLAGS)
CFLAGS = -framework Foundation -framework CoreServices -framework Security -framework IOKit -framework IOSurface -I../.include -I../_external/modules/litehook/src -isysroot $(shell xcrun --sdk iphoneos --show-sdk-path) -arch arm64 -arch arm64e -miphoneos-version-min=15.0 -fobjc-arc -dynamiclib -install_name @loader_path/$(TARGET) -I$(shell brew --prefix)/opt/libarchive/include $(ADDITIONAL_FLAGS)
LDFLAGS = -larchive -lbsm -L../.build -lchoma

sign: $(TARGET)
@ldid -S $<

$(TARGET): $(wildcard src/*.c src/*.m src/*.S)
$(TARGET): $(wildcard src/*.c src/*.m src/*.S ../_external/modules/litehook/src/*.c)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^

clean:
Expand Down
52 changes: 52 additions & 0 deletions BaseBin/libjailbreak/src/dsc_mlock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include "dsc_mlock.h"
#include <mach-o/dyld_images.h>
#include <sys/mman.h>
#include <dispatch/dispatch.h>
#include <choma/MachO.h>
#include <litehook.h>

DyldSharedCache *_get_live_dsc(void)
{
static DyldSharedCache *liveDSC = NULL;
static dispatch_once_t ot;
dispatch_once(&ot, ^{
liveDSC = dsc_init_from_path(litehook_locate_dsc());
});
return liveDSC;
}

int dsc_mlock_unslid(uint64_t unslid_addr, size_t size)
{
void *ptr = dsc_find_buffer(_get_live_dsc(), unslid_addr, size);
if (!ptr) return -1;
return mlock(ptr, size);
}

int dsc_mlock(void *addr, size_t size)
{
static uint64_t dscSlide = 0;
static dispatch_once_t ot;
dispatch_once(&ot, ^{
task_dyld_info_data_t dyldInfo;
uint32_t count = TASK_DYLD_INFO_COUNT;
task_info(mach_task_self_, TASK_DYLD_INFO, (task_info_t)&dyldInfo, &count);
struct dyld_all_image_infos *infos = (struct dyld_all_image_infos *)dyldInfo.all_image_info_addr;
dscSlide = infos->sharedCacheSlide;
});
return dsc_mlock_unslid((uint64_t)addr - dscSlide, size);
}

int dsc_mlock_library_exec(const char *name)
{
MachO *macho = dsc_lookup_macho_by_path(_get_live_dsc(), name, NULL);
if (!macho) return -1;

__block int r = 0;
macho_enumerate_segments(macho, ^(struct segment_command_64 *segment, bool *stop) {
if (segment->initprot & PROT_EXEC) {
r = dsc_mlock_unslid(segment->vmaddr, segment->vmsize);
if (r != 0) *stop = true;
}
});
return r;
}
5 changes: 5 additions & 0 deletions BaseBin/libjailbreak/src/dsc_mlock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include <choma/DyldSharedCache.h>

int dsc_mlock_unslid(uint64_t unslid_addr, size_t size);
int dsc_mlock(void *addr, size_t size);
int dsc_mlock_library_exec(const char *name);
116 changes: 0 additions & 116 deletions BaseBin/libjailbreak/src/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -540,122 +540,6 @@ void proc_allow_all_syscalls(uint64_t proc)
}
}

struct dsc_text_segment {
void *mapping;
uint64_t offset;
uint64_t address;
uint64_t size;
};

int mlock_dsc_unslid(uint64_t unslid_addr, size_t size)
{
static struct dsc_text_segment *segments = NULL;
static int segmentCount = 0;
static dispatch_once_t ot;
dispatch_once(&ot, ^{
const char *dscPath = "/System/Library/Caches/com.apple.dyld";
DIR *dir = opendir(dscPath);
if (!dir) {
return;
}

struct dirent *entry;

while ((entry = readdir(dir)) != NULL) {
if (entry->d_name[0] == '.') {
continue; // Skip "." and ".." entries
}

const char *ext = strrchr(entry->d_name, '.');
if (ext && strcmp(ext, ".symbols") == 0) {
continue; // Skip files with ".symbols" extension
}

char filePath[PATH_MAX];
snprintf(filePath, sizeof(filePath), "%s/%s", dscPath, entry->d_name);

int fd = open(filePath, O_RDONLY);
if (fd < 0) {
continue;
}

struct stat sb;
if (fstat(fd, &sb) != 0) {
continue;
}

void *localMap = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
if (localMap == MAP_FAILED) {
continue;
}

struct dyld_cache_header *header = (struct dyld_cache_header *)localMap;
for (uint32_t i = 0; i < header->mappingCount; i++) {
uint32_t curMappingOff = header->mappingOffset + (i * sizeof(struct dyld_cache_mapping_info));
struct dyld_cache_mapping_info *curMapping = (struct dyld_cache_mapping_info *)((uint8_t *)localMap + curMappingOff);

if (curMapping->initProt & PROT_EXEC) {
void *textMap = mmap(NULL, curMapping->size, PROT_READ, MAP_SHARED, fd, curMapping->fileOffset);
if (textMap != MAP_FAILED) {
segmentCount++;
segments = realloc(segments, segmentCount * sizeof(struct dsc_text_segment));
if (!segments) {
munmap(textMap, curMapping->size);
break;
}
segments[segmentCount - 1] = (struct dsc_text_segment){
.mapping = textMap,
.offset = curMapping->fileOffset,
.address = curMapping->address,
.size = curMapping->size,
};
}
}
}

munmap(localMap, sb.st_size);
close(fd);
}
});

for (int i = 0; i < segmentCount; i++) {
struct dsc_text_segment *curSegment = &segments[i];
if (unslid_addr >= curSegment->address && (unslid_addr + size) < (curSegment->address + curSegment->size)) {
uint64_t rel = unslid_addr - curSegment->address;
void *start = (void *)((uint64_t)curSegment->mapping + rel);
return mlock(start, size);
}
}

return -1;
}

int mlock_dsc(void *addr, size_t size)
{
static uint64_t dscSlide = 0;
static dispatch_once_t ot;
dispatch_once(&ot, ^{
task_dyld_info_data_t dyldInfo;
uint32_t count = TASK_DYLD_INFO_COUNT;
task_info(mach_task_self_, TASK_DYLD_INFO, (task_info_t)&dyldInfo, &count);
struct dyld_all_image_infos *infos = (struct dyld_all_image_infos *)dyldInfo.all_image_info_addr;
dscSlide = infos->sharedCacheSlide;
});
return mlock_dsc_unslid((uint64_t)addr - dscSlide, size);
}

int mlock_library(const char *name)
{
dlopen(name, RTLD_NOW);
const struct mach_header *mh = get_mach_header(name);
if (!mh) return -1;

unsigned long sectionSize = 0;
uint32_t *instructions = (uint32_t *)getsectiondata((const struct mach_header_64 *)mh, "__TEXT", "__text", &sectionSize);

return mlock_dsc(instructions, sectionSize);
}

int cmd_wait_for_exit(pid_t pid)
{
int status = 0;
Expand Down
3 changes: 0 additions & 3 deletions BaseBin/libjailbreak/src/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@ uint64_t kptr_sign(uint64_t kaddr, uint64_t pointer, uint16_t salt);

void proc_allow_all_syscalls(uint64_t proc);

int mlock_dsc(void *addr, size_t size);
int mlock_library(const char *name);

void killall(const char *executablePathToKill, bool softly);
int libarchive_unarchive(const char *fileToExtract, const char *extractionPath);

Expand Down

0 comments on commit c7ce08c

Please sign in to comment.