Skip to content

Commit

Permalink
Detect buggy ellekit, add functions to bridgehook.dylib
Browse files Browse the repository at this point in the history
  • Loading branch information
asdfugil committed Jul 16, 2024
1 parent 50f5009 commit b7f5337
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 380 deletions.
6 changes: 6 additions & 0 deletions include/universalhooks/hooks.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
#ifndef UNIVERSALHOOKS_HOOKS_H
#define UNIVERSALHOOKS_HOOKS_H

#include <stdint.h>
#include <stdbool.h>

extern uint64_t pflags;
extern bool rootful;

void lsdRootlessInit(void);
void securitydInit(void);
void watchdogdInit(void);
Expand Down
67 changes: 65 additions & 2 deletions src/bridgehook/main.c
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
#include <stdio.h>
#include <objc/objc.h>
#include <objc/runtime.h>
#include <mach-o/dyld.h>
#include <mach-o/loader.h>
#include <mach-o/nlist.h>
#include <string.h>

#define BH_EXPORT __attribute__ ((visibility ("default")))

typedef void* MSImageRef;

int DobbyHook(void *address, void *fake_func, void **out_origin_func);

__attribute__ ((visibility ("default")))
BH_EXPORT
void MSHookFunction(void *address, void *fake_func, void **out_origin_func) {
DobbyHook(address, fake_func, out_origin_func);
}

__attribute__ ((visibility ("default")))
BH_EXPORT
void MSHookMessageEx(Class class_, SEL selector_, IMP replacement, IMP* replacee) {
Method method = class_getInstanceMethod(class_, selector_);
if (!method) {
Expand All @@ -19,3 +27,58 @@ void MSHookMessageEx(Class class_, SEL selector_, IMP replacement, IMP* replacee
IMP orig = method_setImplementation(method, replacement);
if (orig) *replacee = orig;
}

BH_EXPORT
MSImageRef MSGetImageByName(const char *file) {
uint32_t file_index = 0;
for (uint32_t i = 0; i < _dyld_image_count(); i++) {
if(!strcmp(_dyld_get_image_name(i), file)) {
file_index = i;
break;
}
}
if (file_index)
return (void*)_dyld_get_image_header(file_index);
else return NULL;
}

BH_EXPORT
void MSCloseImage(const char* file) {
return;
}

BH_EXPORT
void *MSFindSymbol(MSImageRef image, const char *name) {
void* buf = (char*)image;

struct load_command *after_header = buf + sizeof(struct mach_header_64);
struct mach_header_64 *header = buf;
struct symtab_command *symtab_cmd = NULL;

for (uint32_t i = 0; i < header->ncmds; i++) {
if (after_header->cmd == LC_SYMTAB) {
symtab_cmd = (struct symtab_command *) after_header;

break;
}

after_header = (struct load_command *) ((char *) after_header + after_header->cmdsize);
}

if (!symtab_cmd) return NULL;

struct nlist_64 *symtab = buf + symtab_cmd->symoff;
char *strtab = buf + symtab_cmd->stroff;

for (uint32_t i = 0; i < symtab_cmd->nsyms; i++) {
struct nlist_64 *symbol_nlist = symtab + i;
char *sym_name = strtab + symbol_nlist->n_un.n_strx;

if (strcmp(sym_name, name) == 0) {
return (buf + symbol_nlist->n_value);
}
}

return NULL;
}

16 changes: 16 additions & 0 deletions src/libs/bridgehook.tbd
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
--- !tapi-tbd
tbd-version: 4
targets: [ arm64-ios, arm64-tvos, arm64-bridgeos ]
uuids:
- target: arm64-ios
value: 847B3DA6-A02C-309E-844B-EF89824075EC
- target: arm64-tvos
value: 847B3DA6-A02C-309E-844B-EF89824075EF
- target: arm64-tvos
value: 847B3DA6-A02C-309E-844B-EF89824075AA
flags: [ not_app_extension_safe ]
install-name: '@rpath/CydiaSubstrate.framework/CydiaSubstrate'
exports:
- targets: [ arm64-ios, arm64-tvos, arm64-bridgeos ]
symbols: [ _MSHookFunction, _MSHookMessageEx, _MSGetImageByName, _MSCloseImage, _MSFindSymbol ]
...
359 changes: 0 additions & 359 deletions src/libs/libellekit.tbd

This file was deleted.

8 changes: 4 additions & 4 deletions src/payload_dylib/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#include <mach-o/loader.h>

#define HOOK_DYLIB_PATH "/cores/binpack/usr/lib/systemhook.dylib"
#define ELLEKIT_PATH "/cores/binpack/Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate"
#define HOOKING_FW_PATH "/cores/binpack/Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate"

bool has_verbose_boot;
uint64_t pflags;
Expand Down Expand Up @@ -183,14 +183,14 @@ __attribute__((constructor))void launchd_hook_main(void) {
_panic("symbol spawn_hook_common not found in " HOOK_DYLIB_PATH ": %s\n", dlerror());
}

void* ellekit_handle = dlopen(ELLEKIT_PATH, RTLD_NOW);
void* ellekit_handle = dlopen(HOOKING_FW_PATH, RTLD_NOW);
if (!ellekit_handle) {
_panic("dlopen ellekit failed: %s\n", dlerror());
_panic("dlopen hooking framework failed: %s\n", dlerror());
}

MSHookFunction_p = dlsym(ellekit_handle, "MSHookFunction");
if (!MSHookFunction_p) {
_panic("symbol MSHookFunction not found in " ELLEKIT_PATH ": %s\n", dlerror());
_panic("symbol MSHookFunction not found in " HOOKING_FW_PATH ": %s\n", dlerror());
}

initSpawnHooks();
Expand Down
2 changes: 1 addition & 1 deletion src/universalhooks/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ OBJDIR = obj
C_SRC = $(wildcard *.c)
OBJC_SRC = $(wildcard *.m)
OBJCFLAGS = -fobjc-arc
LIBS = -lobjc ../libs/IOKit.tbd -framework CoreFoundation ../libs/libellekit.tbd
LIBS = -lobjc ../libs/IOKit.tbd -framework CoreFoundation ../libs/bridgehook.tbd
LIBS += -framework Security -framework Foundation ../libjailbreak/libjailbreak.a
OBJS = $(patsubst %,$(OBJDIR)/%,$(OBJC_SRC:.m=.m.o) $(C_SRC:.c=.c.o))

Expand Down
50 changes: 38 additions & 12 deletions src/universalhooks/lsd.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <CoreFoundation/CFURLPriv.h>
#include <mach-o/loader.h>
#include <mach-o/dyld.h>
#include <universalhooks/hooks.h>

NSURL* (*orig_LSGetInboxURLForBundleIdentifier)(NSString* bundleIdentifier)=NULL;
NSURL* new_LSGetInboxURLForBundleIdentifier(NSString* bundleIdentifier)
Expand Down Expand Up @@ -37,19 +38,28 @@ void lsdRootlessInit(void) {
int (*_LSServer_RebuildApplicationDatabases_orig)(void);
int _LSServer_RebuildApplicationDatabases_hook(void) {
int retval = _LSServer_RebuildApplicationDatabases_orig();

pid_t pid;
int ret;

if (platform != PLATFORM_BRIDGEOS) {
if (rootful) {
posix_spawn(&pid, "/usr/bin/uicache", NULL, NULL, (char*[]){ "/usr/bin/uicache", "-a", NULL }, NULL);
} else {
posix_spawn(&pid, "/var/jb/usr/bin/uicache", NULL, NULL, (char*[]){ "/var/jb/usr/bin/uicache", "-a", NULL }, NULL);
}
}

if (platform == PLATFORM_IOS) {
ret = posix_spawn(&pid, "/cores/binpack/usr/bin/uicache", NULL, NULL, (char*[]){ "/cores/binpack/usr/bin/uicache", "-p", "/cores/binpack/Applications/palera1nLoader.app", NULL }, NULL);
NSLog(@"lsd_hook: posix spawn retval: %d\n", ret);
} else if (platform == PLATFORM_TVOS) {
ret = posix_spawn(&pid, "/cores/binpack/usr/bin/uicache", NULL, NULL, (char*[]){ "/cores/binpack/usr/bin/uicache", "-p", "/cores/binpack/Applications/palera1nLoaderTV.app", NULL }, NULL);
NSLog(@"lsd_hook: posix spawn retval: %d\n", ret);
}
return retval;
}

#define COMPAT_BUGGY_ELLEKIT

#ifdef COMPAT_BUGGY_ELLEKIT
static uint32_t* find_insn_maskmatch_match(uint8_t* data, size_t size, uint32_t* matches, uint32_t* masks, int count) {
int found = 0;
if(sizeof(matches) != sizeof(masks))
Expand Down Expand Up @@ -90,10 +100,7 @@ int _LSServer_RebuildApplicationDatabases_hook(void) {
return NULL;
}

extern uint32_t dyld_get_active_platform(void);
void lsdUniversalInit(void) {
NSLog(@"lsdUniversalInit...");
platform = dyld_get_active_platform();
static void* find__LSServer_RebuildApplicationDatabases(void) {
char coreservices_path[PATH_MAX] = "/System/Library/Frameworks/CoreServices.framework/CoreServices";
int coreservices_image_index = 0;
for (uint32_t i = 0; i < _dyld_image_count(); i++) {
Expand Down Expand Up @@ -126,7 +133,7 @@ void lsdUniversalInit(void) {

if (!text_size) {
NSLog(@"failed to find CoreServices __TEXT segment");
return;
return NULL;
}

uint32_t matches[] = {
Expand All @@ -152,19 +159,38 @@ void lsdUniversalInit(void) {
uint32_t* __LSServer_RebuildApplicationDatabases = NULL;
uint32_t* __LSServer_RebuildApplicationDatabases_mid = find_insn_maskmatch_match((uint8_t*)text_start, text_size, matches, masks, sizeof(matches)/sizeof(uint32_t));
NSLog(@"__LSServer_RebuildApplicationDatabases_mid=%p", __LSServer_RebuildApplicationDatabases_mid);

if (__LSServer_RebuildApplicationDatabases_mid) {
__LSServer_RebuildApplicationDatabases = find_prev_insn(__LSServer_RebuildApplicationDatabases_mid, 25, 0xd10003ff, 0xffc003ff); // sub sp, sp, *
if (__LSServer_RebuildApplicationDatabases[-1] == 0xd503237f) __LSServer_RebuildApplicationDatabases -= 1; // pacibsp

NSLog(@"__LSServer_RebuildApplicationDatabases=%p", __LSServer_RebuildApplicationDatabases);
}

return __LSServer_RebuildApplicationDatabases;
}
#endif

extern uint32_t dyld_get_active_platform(void);
void lsdUniversalInit(void) {
NSLog(@"lsdUniversalInit...");
platform = dyld_get_active_platform();
MSImageRef coreServicesImage = MSGetImageByName("/System/Library/Frameworks/CoreServices.framework/CoreServices");
void* __LSServer_RebuildApplicationDatabases = MSFindSymbol(coreServicesImage, "__LSServer_RebuildApplicationDatabases");

#ifdef COMPAT_BUGGY_ELLEKIT
// Currently ellekit tvOS has a bug where private symbols can't be found
// TODO: Remove
if (!__LSServer_RebuildApplicationDatabases) {
NSLog(@"Buggy ellekit detected!");
__LSServer_RebuildApplicationDatabases = find__LSServer_RebuildApplicationDatabases();
}
#endif

if (__LSServer_RebuildApplicationDatabases) {
MSHookFunction(__LSServer_RebuildApplicationDatabases, (void*)&_LSServer_RebuildApplicationDatabases_hook, (void**)&_LSServer_RebuildApplicationDatabases_orig);
} else {
NSLog(@"failed to find __LSServer_RebuildApplicationDatabases");
NSLog(@"Could not find __LSServer_RebuildApplicationDatabases");
}

}


6 changes: 4 additions & 2 deletions src/universalhooks/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@ struct hook_info info[] = {
{ "/Applications/HeadBoard.app/HeadBoard", NULL, NULL, headboardInit },
};

uint64_t pflags;
bool rootful;
__attribute__((constructor))void universalhooks_main(void) {
uint64_t pflags = strtoull(getenv("JB_PINFO_FLAGS"), NULL, 0);
bool rootful = pflags & palerain_option_rootful;
pflags = strtoull(getenv("JB_PINFO_FLAGS"), NULL, 0);
rootful = pflags & palerain_option_rootful;

char path[PATH_MAX];
uint32_t pathmax = PATH_MAX;
Expand Down

0 comments on commit b7f5337

Please sign in to comment.