Skip to content

Commit

Permalink
work on jitterd, im gonna sleep
Browse files Browse the repository at this point in the history
  • Loading branch information
hrtowii committed Jul 24, 2024
1 parent d0e76c9 commit c7954e3
Show file tree
Hide file tree
Showing 12 changed files with 202 additions and 150 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Serotonin.tipa: $(wildcard **/*.c **/*.m **/*.swift **/*.plist **/*.xml)
install -m755 RootHelperSample/launchdshim/launchdhook/launchdhooksigned.dylib Payload/Serotonin.app/launchdhooksigned.dylib
install -m755 RootHelperSample/launchdshim/generalhook/generalhook.dylib Payload/Serotonin.app/generalhooksigned.dylib
install -m755 RootHelperSample/launchdshim/xpcproxyhook/xpcproxyhook.dylib Payload/Serotonin.app/xpcproxyhooksigned.dylib
install -m755 RootHelperSample/launchdshim/launchdhook/jitter/jitter Payload/Serotonin.app/jitter
install -m755 RootHelperSample/launchdshim/launchdhook/jitter/jitter Payload/Serotonin.app/jitterd
$(LDID) -S./RootHelperSample/entitlements.plist -Cadhoc Payload/Serotonin.app/{fastPathSign,ldid,serotoninroothelper}
$(LDID) -Sent.plist -Cadhoc Payload/Serotonin.app/Serotonin
zip -vr9 Serotonin.tipa Payload/ -x "*.DS_Store"
Expand Down
53 changes: 1 addition & 52 deletions RootHelperSample/TSUtil.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#import <Foundation/Foundation.h>
#import <spawn.h>
#import <sys/sysctl.h>
#include <IOKit/IOKitLib.h>
#import "jbroot.h"

@interface PSAppDataUsagePolicyCache : NSObject
+ (instancetype)sharedInstance;
Expand Down Expand Up @@ -215,54 +215,3 @@ void respring(void)
killall(@"SpringBoard");
exit(0);
}

int get_boot_manifest_hash(char hash[97])
{
const UInt8 *bytes;
CFIndex length;
io_registry_entry_t chosen = IORegistryEntryFromPath(0, "IODeviceTree:/chosen");
if (!MACH_PORT_VALID(chosen)) return 1;
CFDataRef manifestHash = (CFDataRef)IORegistryEntryCreateCFProperty(chosen, CFSTR("boot-manifest-hash"), kCFAllocatorDefault, 0);
IOObjectRelease(chosen);
if (manifestHash == NULL || CFGetTypeID(manifestHash) != CFDataGetTypeID())
{
if (manifestHash != NULL) CFRelease(manifestHash);
return 1;
}
length = CFDataGetLength(manifestHash);
bytes = CFDataGetBytePtr(manifestHash);
for (int i = 0; i < length; i++)
{
snprintf(&hash[i * 2], 3, "%02X", bytes[i]);
}
CFRelease(manifestHash);
return 0;
}

char* return_boot_manifest_hash_main(void) {
static char hash[97];
int ret = get_boot_manifest_hash(hash);
if (ret != 0) {
fprintf(stderr, "could not get boot manifest hash\n");
return "lmao";
}
static char result[115];
sprintf(result, "/private/preboot/%s", hash);
return result;
}

char* getPatchedLaunchdCopy(void) {
char* prebootpath = return_boot_manifest_hash_main();
static char originallaunchd[256];
sprintf(originallaunchd, "%s/%s", prebootpath, "patchedlaunchd");
NSLog(@"patchedlaunchd: %s", originallaunchd);
return originallaunchd;
}

char* getOriginalLaunchdCopy(void) {
char* prebootpath = return_boot_manifest_hash_main();
static char originallaunchd[256];
sprintf(originallaunchd, "%s/%s", prebootpath, "patchedlaunchd");
NSLog(@"patchedlaunchd: %s", originallaunchd);
return originallaunchd;
}
2 changes: 2 additions & 0 deletions RootHelperSample/jbroot.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#include <Foundation/Foundation.h>
NSString *jbroot(NSString *path);
73 changes: 73 additions & 0 deletions RootHelperSample/jbroot.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#import <stdio.h>
#include <sys/types.h>
#import <Foundation/Foundation.h>

#define JB_ROOT_PREFIX ".jbroot-"
#define JB_RAND_LENGTH (sizeof(uint64_t)*sizeof(char)*2)

int is_jbrand_value(uint64_t value)
{
uint8_t check = value>>8 ^ value >> 16 ^ value>>24 ^ value>>32 ^ value>>40 ^ value>>48 ^ value>>56;
return check == (uint8_t)value;
}

int is_jbroot_name(const char* name)
{
if(strlen(name) != (sizeof(JB_ROOT_PREFIX)-1+JB_RAND_LENGTH))
return 0;

if(strncmp(name, JB_ROOT_PREFIX, sizeof(JB_ROOT_PREFIX)-1) != 0)
return 0;

char* endp=NULL;
uint64_t value = strtoull(name+sizeof(JB_ROOT_PREFIX)-1, &endp, 16);
if(!endp || *endp!='\0')
return 0;

if(!is_jbrand_value(value))
return 0;

return 1;
}

uint64_t resolve_jbrand_value(const char* name)
{
if(strlen(name) != (sizeof(JB_ROOT_PREFIX)-1+JB_RAND_LENGTH))
return 0;

if(strncmp(name, JB_ROOT_PREFIX, sizeof(JB_ROOT_PREFIX)-1) != 0)
return 0;

char* endp=NULL;
uint64_t value = strtoull(name+sizeof(JB_ROOT_PREFIX)-1, &endp, 16);
if(!endp || *endp!='\0')
return 0;

if(!is_jbrand_value(value))
return 0;

return value;
}


NSString* find_jbroot()
{
//jbroot path may change when re-randomize it
NSString * jbroot = nil;
NSArray *subItems = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:@"/var/containers/Bundle/Application/" error:nil];
for (NSString *subItem in subItems) {
if (is_jbroot_name(subItem.UTF8String))
{
NSString* path = [@"/var/containers/Bundle/Application/" stringByAppendingPathComponent:subItem];
jbroot = path;
break;
}
}
return jbroot;
}

NSString *jbroot(NSString *path)
{
NSString* jbroot = find_jbroot();
return [jbroot stringByAppendingPathComponent:path];
}
76 changes: 76 additions & 0 deletions RootHelperSample/launchdshim/launchdhook/jbserver/jbclient_xpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <pthread.h>
#include <mach-o/dyld.h>
#include <dlfcn.h>
#include "sandbox.h"

#define OS_ALLOC_ONCE_KEY_MAX 100

Expand Down Expand Up @@ -252,6 +253,81 @@ int jbclient_process_checkin(char **rootPathOut, char **bootUUIDOut, char **sand
return -1;
}

extern char **environ;
kern_return_t bootstrap_look_up(mach_port_t port, const char *service, mach_port_t *server_port);

bool jitterdSystemWideIsReachable(void)
{
int sbc = sandbox_check(getpid(), "mach-lookup", SANDBOX_FILTER_GLOBAL_NAME | SANDBOX_CHECK_NO_REPORT, "com.hrtowii.jitterd.systemwide");
return sbc == 0;
}

mach_port_t jitterdSystemWideMachPort(void)
{
mach_port_t outPort = MACH_PORT_NULL;
kern_return_t kr = KERN_SUCCESS;

if (getpid() == 1) {
mach_port_t self_host = mach_host_self();
kr = host_get_special_port(self_host, HOST_LOCAL_NODE, 16, &outPort);
mach_port_deallocate(mach_task_self(), self_host);
}
else {
kr = bootstrap_look_up(bootstrap_port, "com.hrtowii.jitterd.systemwide", &outPort);
}

if (kr != KERN_SUCCESS) return MACH_PORT_NULL;
return outPort;
}

xpc_object_t sendLaunchdMessageFallback(xpc_object_t xdict)
{
xpc_dictionary_set_bool(xdict, "jailbreak", true);
xpc_dictionary_set_bool(xdict, "jailbreak-systemwide", true);

void* pipePtr = NULL;
if(_os_alloc_once_table[1].once == -1)
{
pipePtr = _os_alloc_once_table[1].ptr;
}
else
{
pipePtr = _os_alloc_once(&_os_alloc_once_table[1], 472, NULL);
if (!pipePtr) _os_alloc_once_table[1].once = -1;
}

xpc_object_t xreply = NULL;
if (pipePtr) {
struct xpc_global_data* globalData = pipePtr;
xpc_object_t pipe = globalData->xpc_bootstrap_pipe;
if (pipe) {
int err = xpc_pipe_routine_with_flags(pipe, xdict, &xreply, 0);
if (err != 0) {
return NULL;
}
}
}
return xreply;
}

xpc_object_t sendjitterdMessageSystemWide(xpc_object_t xdict)
{
xpc_object_t jitterd_xreply = NULL;
if (jitterdSystemWideIsReachable()) {
mach_port_t jitterdPort = jitterdSystemWideMachPort();
if (jitterdPort != -1) {
xpc_object_t pipe = xpc_pipe_create_from_port(jitterdPort, 0);
if (pipe) {
int err = xpc_pipe_routine(pipe, xdict, &jitterd_xreply);
if (err != 0) jitterd_xreply = NULL;
xpc_release(pipe);
}
mach_port_deallocate(mach_task_self(), jitterdPort);
}
}
return jitterd_xreply;
}

// int jbclient_fork_fix(uint64_t childPid)
// {
// xpc_object_t xargs = xpc_dictionary_create_empty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ int jbclient_cs_drop_get_task_allow(void);
int jbclient_patch_spawn(int pid, bool resume);
int jbclient_patch_exec_add(const char* exec_path, bool resume);
int jbclient_patch_exec_del(const char* exec_path);
xpc_object_t sendjitterdMessageSystemWide(xpc_object_t xdict);
// int jbclient_platform_set_process_debugged(uint64_t pid, bool fullyDebugged);
// int jbclient_platform_stage_jailbreak_update(const char *updateTar);
// int jbclient_platform_jbsettings_get(const char *key, xpc_object_t *valueOut);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,31 @@
#include "spawnRoot.h"
#include <roothide.h>
#include "../fun/memoryControl.h"

#include "jbclient_xpc.h"
#define JBD_MSG_PROC_SET_DEBUGGED 23
#define PT_DETACH 11 /* stop tracing a process */
#define PT_ATTACHEXC 14 /* attach to running process with signal exception */
int ptrace(int _request, pid_t _pid, caddr_t _addr, int _data);

#include <signal.h>

int enableJIT(pid_t pid)
// int enableJIT(pid_t pid)
// {
// int ret = spawnRoot(jbroot("/jitter"), pid, NULL, NULL);
// return ret;
// }
int64_t jitterd(pid_t pid)
{
int ret = spawnRoot(jbroot("/jitter"), pid, NULL, NULL);
return ret;
xpc_object_t message = xpc_dictionary_create_empty();
xpc_dictionary_set_int64(message, "id", JBD_MSG_PROC_SET_DEBUGGED);
xpc_dictionary_set_int64(message, "pid", pid);
xpc_object_t reply = sendjitterdMessageSystemWide(message);
int64_t result = -1;
if (reply) {
result = xpc_dictionary_get_int64(reply, "result");
xpc_release(reply);
}
return result;
}

// extern bool stringStartsWith(const char *str, const char* prefix);
Expand Down Expand Up @@ -171,19 +185,18 @@ static int systemwide_process_checkin(audit_token_t *processToken, char **rootPa

// Generate sandbox extensions for the requesting process
*sandboxExtensionsOut = generate_sandbox_extensions(processToken, isPlatformProcess);

jitterd(pid);
// Allow invalid pages with ptrace instead :trol:
// terrible solution but ideally jitter would become a daemon later. temp fix to see if it works
memorystatus_memlimit_properties2_t mmprops;
int32_t old_memory_limit = 0;
uint32_t new_memory_limit = (uint32_t)(getPhysicalMemorySize() / UINT64_C(1048576)) * 2;
int ret = memorystatus_control(MEMORYSTATUS_CMD_GET_MEMLIMIT_PROPERTIES, pid, 0, &mmprops, sizeof(mmprops));
if (ret == 0)
old_memory_limit = mmprops.v1.memlimit_active;
ret = memorystatus_control(MEMORYSTATUS_CMD_SET_JETSAM_TASK_LIMIT, pid, new_memory_limit, NULL, 0);
enableJIT(pid);
// set it back because yeah
ret = memorystatus_control(MEMORYSTATUS_CMD_SET_JETSAM_TASK_LIMIT, pid, old_memory_limit, NULL, 0);
// memorystatus_memlimit_properties2_t mmprops;
// int32_t old_memory_limit = 0;
// uint32_t new_memory_limit = (uint32_t)(getPhysicalMemorySize() / UINT64_C(1048576)) * 2;
// int ret = memorystatus_control(MEMORYSTATUS_CMD_GET_MEMLIMIT_PROPERTIES, pid, 0, &mmprops, sizeof(mmprops));
// if (ret == 0)
// old_memory_limit = mmprops.v1.memlimit_active;
// ret = memorystatus_control(MEMORYSTATUS_CMD_SET_JETSAM_TASK_LIMIT, pid, new_memory_limit, NULL, 0);
// enableJIT(pid);
// ret = memorystatus_control(MEMORYSTATUS_CMD_SET_JETSAM_TASK_LIMIT, pid, old_memory_limit, NULL, 0);

// bool fullyDebugged = true;
// if (is_app_path(procPath) || is_sub_path(JBRootPath("/Applications"), procPath)) {
Expand Down
7 changes: 4 additions & 3 deletions RootHelperSample/launchdshim/launchdhook/jitter/jitter.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@
#include <mach/mach_init.h>
#include "../fun/memoryControl.h"
#include "../jbserver/bsm/audit.h"
#include "../jbserver/xpc_private.h"

#define PT_DETACH 11 /* stop tracing a process */
#define PT_ATTACHEXC 14 /* attach to running process with signal exception */
#define MEMORYSTATUS_CMD_SET_JETSAM_HIGH_WATER_MARK 5
#define JBD_MSG_DEBUG_ME 24
#define JBD_MSG_PROC_SET_DEBUGGED 23

int ptrace(int request, pid_t pid, caddr_t addr, int data);
// void JBLogError(const char *format, ...);
Expand Down Expand Up @@ -58,8 +59,8 @@ void jitterd_received_message(mach_port_t machPort, bool systemwide)
if (messageType == XPC_TYPE_DICTIONARY) {
audit_token_t auditToken = {};
xpc_dictionary_get_audit_token(message, &auditToken);
uid_t clientUid = audit_token_to_euid(auditToken);
pid_t clientPid = audit_token_to_pid(auditToken);
// uid_t clientUid = audit_token_to_euid(auditToken);
// pid_t clientPid = audit_token_to_pid(auditToken);
msgId = xpc_dictionary_get_int64(message, "id");
char *description = xpc_copy_description(message);
free(description);
Expand Down
6 changes: 3 additions & 3 deletions RootHelperSample/launchdshim/launchdhook/jitter/jitterd.plist
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
<key>com.hrtowii.jitterd.systemwide</key>
<true/>
</dict>
<!-- <key>ProgramArguments</key>
<key>ProgramArguments</key>
<array>
<string>basebin/jailbreakd</string>
</array> -->
<string>jitterd</string>
</array>
<key>UserName</key>
<string>root</string>
<key>RunAtLoad</key>
Expand Down
8 changes: 6 additions & 2 deletions RootHelperSample/launchdshim/launchdhook/main.m
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ bool hook_xpc_dictionary_get_bool(xpc_object_t dictionary, const char *key) {
xpc_object_t hook_xpc_dictionary_get_value(xpc_object_t dict, const char *key) {
xpc_object_t retval = xpc_dictionary_get_value_orig(dict, key);

if (strcmp(key, "Paths") == 0) {
if (!strcmp(key, "Paths")) {
const char *paths[] = {
jbroot("/Library/LaunchDaemons"),
jbroot("/System/Library/LaunchDaemons"),
Expand All @@ -219,7 +219,11 @@ xpc_object_t hook_xpc_dictionary_get_value(xpc_object_t dict, const char *key) {
for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); ++i) {
xpc_array_append_value(retval, xpc_string_create(paths[i]));
}
}
if (xpc_get_type(retval) == XPC_TYPE_ARRAY) {
xpc_array_set_string(retval, XPC_ARRAY_APPEND, jbroot("/Library/LaunchDaemons")); // todo: copy jitterd daemon plist to serotonin app, roothelper copy from app to library/launchdaemons in jbroot
}
}


return retval;
}
Expand Down
Loading

0 comments on commit c7954e3

Please sign in to comment.