tries to hook checkra1n

This commit is contained in:
Nick Chan committed 2026-05-24 22:17:02 +08:00
1 parent b0348f1174
commit 3d29bb8dc5
12 files changed
+227 -24

No files matched your search

+1 -1
View File
@@ -22,7 +22,7 @@ extern uint32_t binpack_dmg_len;
extern uint8_t Pongo_bin[];
extern uint32_t Pongo_bin_len;
#if defined(__APPLE__) && (TARGET_OS_IPHONE || defined(DEV_BUILD) || defined(FORCE_HELPER))
#if defined(__APPLE__)
extern uint8_t libcheckra1nhelper_dylib[];
extern uint32_t libcheckra1nhelper_dylib_len;
#endif
+7 -10
View File
@@ -4,6 +4,8 @@ OBJDIR = obj
GENDIR = gen
RESOURCES_DIR = resources
export RESOURCES_DIR OBJDIR GENDIR
C_SRC = $(wildcard *.c)
OBJS = $(patsubst %,$(OBJDIR)/%,$(C_SRC:.c=.c.o))
@@ -23,13 +25,9 @@ ifeq ($(DFUHELPER_AUTO_ONLY),1)
CFLAGS += -DDFUHELPER_AUTO_ONLY
endif
ifeq ($(FORCE_HELPER),1)
ifneq ($(NO_EMBED_HELPER),1)
ifeq ($(TARGET_OS),Darwin)
C_SRC += $(GENDIR)/gen-libcheckra1nhelper.dylib.c
endif
CFLAGS += -DFORCE_HELPER
BUILD_OPTIONS += FORCE_HELPER
endif
ifneq ($(NO_RAMDISK),1)
C_SRC += $(GENDIR)/gen-ramdisk.dmg.lzma.c
@@ -149,7 +147,6 @@ $(GENDIR)/gen-%.c: $(RESOURCES_DIR)/%
echo '#include <stdint.h>' > $(RESOURCES_DIR)/../$@
cd $(RESOURCES_DIR) && xxd -iC $$(echo $< | cut -d/ -f2) | sed -e 's/unsigned int/uint32_t/' -e 's/unsigned char/uint8_t/' >> ../$@
$(OBJDIR)/pongo_helper.c.o: pongo_helper.c $(wildcard ../include/*.h) $(RESOURCES_DIR)/ramdisk.dmg $(RESOURCES_DIR)/checkra1n-kpf-pongo
$(CC) -c -o $@ $(CFLAGS) -DRAMDISK_UNCOMPRESSED_SIZE="\"$$(wc -c < $(RESOURCES_DIR)/ramdisk.dmg | tr -d ' ')\"" -DKPF_UNCOMPRESSED_SIZE="\"$$(wc -c < $(RESOURCES_DIR)/checkra1n-kpf-pongo | tr -d ' ')\"" $<
@@ -167,8 +164,8 @@ ifneq (,$(findstring version-min=, $(CFLAGS)))
endif
endif
$(RESOURCES_DIR)/libcheckra1nhelper.dylib: chkstk.S
$(CC) $(CFLAGS) $(LDFLAGS) -shared chkstk.S -o $@
$(RESOURCES_DIR)/libcheckra1nhelper.dylib:
$(MAKE) -C helper
$(RESOURCES_DIR)/checkra1n-kpf-pongo:
curl -Lfo $@ https://cdn.nickchan.lol/palera1n/artifacts/kpf/iOS15/checkra1n-kpf-pongo
@@ -189,9 +186,9 @@ $(RESOURCES_DIR)/Pongo.bin:
curl -Lfo $@ https://cdn.nickchan.lol/palera1n/artifacts/kpf/iOS15/Pongo.bin
clean:
rm -rf $(OBJDIR)/*.o $(GENDIR)/*.c $(GENDIR)/*.o palera1n palera1n.dSYM libcheckra1nhelper.dylib
rm -rf $(OBJDIR)/*.o $(GENDIR)/*.c $(GENDIR)/*.o palera1n palera1n.dSYM $(RESOURCES_DIR)/libcheckra1nhelper.dylib
distclean: clean
rm -rf $(RESOURCES_DIR)/*
.PHONY: all clean
.PHONY: all clean $(RESOURCES_DIR)/libcheckra1nhelper.dylib
+17 -13
View File
@@ -100,16 +100,23 @@ int exec_checkra1n(void) {
return -1;
}
}
#if defined(__APPLE__) && defined(__arm64__) && (TARGET_OS_IPHONE || defined(FORCE_HELPER))
#if defined(__APPLE__)
char resolved_c1_path[PATH_MAX], *resolved;
resolved = realpath(checkra1n_path, resolved_c1_path);
if (!resolved) {
LOG(LOG_FATAL, "Cannot resolve checkra1n path %s: %d (%s)", checkra1n_path, errno, strerror(errno));
if (ext_checkra1n == NULL) {
unlink(checkra1n_path);
free(checkra1n_path);
}
checkra1n_path = NULL;
return -1;
}
char* libcheckra1nhelper_dylib_path = NULL;
{
struct utsname name;
uname(&name);
unsigned long darwinMajor = strtoul(name.release, NULL, 10);
assert(darwinMajor != 0);
#if !defined(FORCE_HELPER)
if (darwinMajor < 20) {
#endif
if (ext_checkra1n == NULL || gOverrideLibcheckra1nHelper) {
setenv("LIBCHECKRA1NHELPER_CHECKRA1N_PATH", resolved_c1_path, 1);
if (gOverrideLibcheckra1nHelper) {
libcheckra1nhelper_dylib_path = gOverrideLibcheckra1nHelper;
goto setenv_ra1n;
@@ -141,9 +148,6 @@ int exec_checkra1n(void) {
}
setenv_ra1n:
setenv("DYLD_INSERT_LIBRARIES", libcheckra1nhelper_dylib_path, 1);
#if !defined(FORCE_HELPER)
}
#endif
}
#endif
char args[0x10] = "-E";
@@ -193,7 +197,7 @@ setenv_ra1n:
}
if (pongo_path != NULL) free(pongo_path);
pongo_path = NULL;
#if defined(__APPLE__) && defined(__arm64__) && (TARGET_OS_IPHONE || defined(FORCE_HELPER))
#if defined(__APPLE__)
if (libcheckra1nhelper_dylib_path != NULL) {
if (!gOverrideLibcheckra1nHelper) unlink(libcheckra1nhelper_dylib_path);
unsetenv("DYLD_INSERT_LIBRARIES");
+27
View File
@@ -0,0 +1,27 @@
C_SRC = $(wildcard *.c)
C_OBJS = $(patsubst %,../$(OBJDIR)/%,$(C_SRC:.c=.c.o))
S_SRC = $(wildcard *.S)
S_OBJS = $(patsubst %,../$(OBJDIR)/%,$(S_SRC:.S=.S.o))
CFLAGS += -fvisibility=hidden
C_OBJS += ../$(GENDIR)/gen-payload-t7000.c.o ../$(GENDIR)/gen-payload-t8011.c.o ../$(GENDIR)/gen-payload-t8012.c.o
all: ../$(RESOURCES_DIR)/libcheckra1nhelper.dylib
../$(OBJDIR)/%.c.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
../$(OBJDIR)/%.S.o: %.S
$(CC) $(CFLAGS) -c -o $@ $<
../$(RESOURCES_DIR)/libcheckra1nhelper.dylib: $(C_OBJS) $(S_OBJS) $(wildcard *.h)
$(CC) $(CFLAGS) $(LDFLAGS) -shared $(C_OBJS) $(S_OBJS) -o $@
../$(GENDIR)/gen-payload-%.c: payloads/%.bin
echo '#include <stdint.h>' > $@
cd payloads && xxd -iC $$(echo $< | cut -d/ -f2) | sed -e 's/unsigned int/uint32_t/' -e 's/unsigned char/uint8_t/' >> ../$@
../$(GENDIR)/gen-payload-%.c.o: ../$(GENDIR)/gen-payload-%.c
$(CC) $(CFLAGS) -c -o $@ $<
+5
View File
@@ -1,3 +1,7 @@
#include <TargetConditionals.h>
#if defined(__APPLE__) && defined(__arm64__) && TARGET_OS_IPHONE
#define _PTHREAD_STRUCT_DIRECT_STACKADDR_OFFSET -48
#define _PTHREAD_STRUCT_DIRECT_STACKBOTTOM_OFFSET -40
@@ -63,3 +67,4 @@ Lend:
sub x10, x10, x9
ldr x11, [x10]
b Lexit
#endif
+83
View File
@@ -0,0 +1,83 @@
#include <mach-o/loader.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <mach-o/dyld.h>
#include <sys/ptrace.h>
#include <spawn.h>
#include <string.h>
#include <limits.h>
#include <TargetConditionals.h>
#include "phookra1n.h"
extern char ***_NSGetArgv(void);
extern int *_NSGetArgc(void);
__attribute__((constructor)) void ctor(void)
{
char ***argvp = _NSGetArgv();
int *argcp = _NSGetArgc();
assert(argvp);
assert(argcp);
int argc = *argcp;
char **argv = *argvp;
#if TARGET_OS_IPHONE
if (argc == 2 && strcmp(argv[1], "__CHECKRA1N_JIT_PLEASE__") == 0) {
assert(ptrace(PT_TRACE_ME, 0, 0, 0) == 0);
exit(0);
} else {
char exe_path[PATH_MAX];
uint32_t exe_path_size = PATH_MAX;
assert(_NSGetExecutablePath(exe_path, &exe_path_size) == 0);
pid_t pid;
assert(posix_spawnp(&pid, exe_path, NULL, NULL, (char*[]){"__CHECKRA1N_JIT_PLEASE__",NULL}, NULL) == 0);
assert(waitpid(pid, NULL, 0) == pid);
}
#endif
char *c1_path = getenv("LIBCHECKRA1NHELPER_CHECKRA1N_PATH");
assert(c1_path);
dprintf("Welcome to Checkra1n Hook!\n");
int c1_image_index = 0;
for (uint32_t i = 0; i < _dyld_image_count(); i++) {
if(!strcmp(_dyld_get_image_name(i), c1_path)) {
c1_image_index = i;
break;
}
}
intptr_t slide = _dyld_get_image_vmaddr_slide(c1_image_index);
struct mach_header_64 *mach_header = (struct mach_header_64*)_dyld_get_image_header(c1_image_index);
uintptr_t cmd_current = (uintptr_t)(mach_header + 1);
uintptr_t cmd_end = cmd_current + mach_header->sizeofcmds;
const struct segment_command_64 *__TEXT = NULL;
for (uint32_t i = 0; i < mach_header->ncmds && cmd_current <= cmd_end; i++) {
const struct segment_command_64 *cmd;
cmd = (struct segment_command_64*)cmd_current;
cmd_current += cmd->cmdsize;
if (cmd->cmd != LC_SEGMENT_64 || strcmp(cmd->segname, "__TEXT")) {
continue;
}
__TEXT = cmd;
}
assert(__TEXT);
#if defined(__arm64__)
assert(__TEXT->vmsize == 0x24000);
setup_hooks_arm64((void*)(__TEXT->vmaddr + slide));
#endif
}
+65
View File
@@ -0,0 +1,65 @@
#include <stdio.h>
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <mach/mach.h>
#include <mach/error.h>
#include <mach/vm_prot.h>
#include <libkern/OSCacheControl.h>
#include "phookra1n.h"
#if defined(__arm64__)
static void patch(uint32_t *stream, const uint8_t *payload, const uint32_t payload_len)
{
uint64_t from = (uint64_t)stream;
uint64_t to = (uint64_t)payload;
uint32_t adrp_off = ((to & ~0xfff) - (from & ~0xfff)) >> 12;
uint32_t add_off = to & 0xfff;
dprintf("from 0x%llx to 0x%llx 0x%llx 0x%x\n", from, to, ((from & ~0xfff) + (adrp_off << 12)), add_off);
uint8_t adrp_reg = stream[0] & 0x1f;
uint8_t add_reg = stream[1] & 0x1f;
uint8_t mov1_reg = stream[2] & 0x1f;
uint8_t mov2_reg = stream[3] & 0x1f;
uint8_t immlo = adrp_off & 0x3;
uint8_t immhi = (adrp_off >> 2) & 0x7ffff;
stream[0] = 0x90000000 | adrp_reg | immlo << 29 | (immhi << 5);
stream[1] = 0x91000000 | add_reg | add_reg << 5 | (add_off & 0xfff) << 10;
stream[2] = 0x52800000 | mov1_reg | ((payload_len & 0xffff) << 5);
stream[3] = 0x52800000 | mov2_reg | ((payload_len & 0xffff) << 5);
dprintf("patched: 0x%x 0x%x 0x%x 0x%x\n", stream[0], stream[1], stream[2], stream[3]);
}
void setup_hooks_arm64(void *stream)
{
uint32_t
*t8011_patch_base = (uint32_t*)((char*)stream + 0x102E0),
*t7000_patch_base = (uint32_t*)((char*)stream + 0x102F4),
*t8012_patch_base = (uint32_t*)((char*)stream + 0x10290);
vm_address_t page = (vm_address_t)((char*)stream + 0x10000);
assert(*t8011_patch_base == 0x90000081); // T8011
assert(*t7000_patch_base == 0x90000061); // T7000
assert(*t8012_patch_base == 0xd0000081); // T8012
assert(vm_protect(mach_task_self(), page, 0x4000, false, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_COPY) == 0);
patch(t7000_patch_base, t7000_bin, t7000_bin_len);
patch(t8011_patch_base, t8011_bin, t8011_bin_len);
patch(t8012_patch_base, t8012_bin, t8012_bin_len);
assert(vm_protect(mach_task_self(), page, 0x4000, false, VM_PROT_READ | VM_PROT_EXECUTE) == 0);
sys_icache_invalidate((void*)page, 0x4000);
dprintf("patched checkra1n\n");
}
#endif
Binary file not shown.
Binary file not shown.
Binary file not shown.
+20
View File
@@ -0,0 +1,20 @@
#ifndef PALERA1N_CHECKRA1N_HELPER_H
#define PALERA1N_CHECKRA1N_HELPER_H
#include <stdint.h>
#include <stdio.h>
#define dprintf(...) // printf(__VA_ARGS__)
extern uint8_t t7000_bin[];
extern uint32_t t7000_bin_len;
extern uint8_t t8011_bin[];
extern uint32_t t8011_bin_len;
extern uint8_t t8012_bin[];
extern uint32_t t8012_bin_len;
void setup_hooks_arm64(void *stream);
#endif
+2
View File
@@ -3,6 +3,8 @@
<dict>
<key>platform-application</key>
<true/>
<key>get-task-allow</key>
<true/>
<key>com.apple.private.security.no-container</key>
<true/>
<key>com.apple.security.iokit-user-client-class</key>