95 lines
2.7 KiB
Objective-C
95 lines
2.7 KiB
Objective-C
#import <Foundation/Foundation.h>
|
|
#import "PLLogOutputView.h"
|
|
#import "SurfaceViewController.h"
|
|
#import "ios_uikit_bridge.h"
|
|
#import "utils.h"
|
|
|
|
#include "external/fishhook/fishhook.h"
|
|
|
|
void (*orig_abort)();
|
|
void (*orig_exit)(int code);
|
|
void* (*orig_dlopen)(const char* path, int mode);
|
|
int (*orig_open)(const char *path, int oflag, ...);
|
|
|
|
void handle_fatal_exit(int code) {
|
|
if (NSThread.isMainThread) {
|
|
return;
|
|
}
|
|
|
|
[PLLogOutputView handleExitCode:code];
|
|
|
|
if (fatalExitGroup != nil) {
|
|
// Likely other threads are crashing, put them to sleep
|
|
sleep(INT_MAX);
|
|
}
|
|
fatalExitGroup = dispatch_group_create();
|
|
dispatch_group_enter(fatalExitGroup);
|
|
dispatch_group_wait(fatalExitGroup, DISPATCH_TIME_FOREVER);
|
|
}
|
|
|
|
void hooked_abort() {
|
|
NSLog(@"abort() called");
|
|
handle_fatal_exit(SIGABRT);
|
|
orig_abort();
|
|
}
|
|
|
|
void hooked___assert_rtn(const char* func, const char* file, int line, const char* failedexpr)
|
|
{
|
|
if (func == NULL) {
|
|
fprintf(stderr, "Assertion failed: (%s), file %s, line %d.\n", failedexpr, file, line);
|
|
} else {
|
|
fprintf(stderr, "Assertion failed: (%s), function %s, file %s, line %d.\n", failedexpr, func, file, line);
|
|
}
|
|
hooked_abort();
|
|
}
|
|
|
|
void hooked_exit(int code) {
|
|
NSLog(@"exit(%d) called", code);
|
|
if (code == 0) {
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[UIApplication.sharedApplication performSelector:@selector(suspend)];
|
|
});
|
|
usleep(100*1000);
|
|
orig_exit(0);
|
|
return;
|
|
}
|
|
handle_fatal_exit(code);
|
|
|
|
orig_exit(code);
|
|
}
|
|
|
|
void* hooked_dlopen(const char* path, int mode) {
|
|
const char *home = getenv("HOME");
|
|
// Only proceed to check if dylib is in the home dir
|
|
char fullpath[PATH_MAX];
|
|
if (!path || !realpath(path, fullpath) || !strstr(fullpath, home)) {
|
|
return orig_dlopen(path, mode);
|
|
}
|
|
|
|
PLPatchMachOPlatformForFile(path);
|
|
return orig_dlopen(path, mode);
|
|
}
|
|
|
|
int hooked_open(const char *path, int oflag, ...) {
|
|
va_list args;
|
|
va_start(args, oflag);
|
|
mode_t mode = va_arg(args, int);
|
|
va_end(args);
|
|
if (path && !strcmp(path, "/etc/resolv.conf")) {
|
|
return orig_open([NSString stringWithFormat:@"%s/resolv.conf", getenv("POJAV_HOME")].UTF8String, oflag, mode);
|
|
}
|
|
|
|
return orig_open(path, oflag, mode);
|
|
}
|
|
|
|
void init_hookFunctions() {
|
|
struct rebinding rebindings[] = (struct rebinding[]){
|
|
{"abort", hooked_abort, (void *)&orig_abort},
|
|
{"__assert_rtn", hooked___assert_rtn, NULL},
|
|
{"exit", hooked_exit, (void *)&orig_exit},
|
|
{"dlopen", hooked_dlopen, (void *)&orig_dlopen},
|
|
{"open", hooked_open, (void *)&orig_open}
|
|
};
|
|
rebind_symbols(rebindings, sizeof(rebindings)/sizeof(struct rebinding));
|
|
}
|