Skip to content

Commit

Permalink
cryptex patches
Browse files Browse the repository at this point in the history
  • Loading branch information
asdfugil committed Jan 3, 2025
1 parent cebd2f3 commit eba05df
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 2 deletions.
135 changes: 133 additions & 2 deletions checkra1n/kpf/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1244,6 +1244,48 @@ bool kpf_apfs_root_snapshot_name(struct xnu_pf_patch *patch, uint32_t *opcode_st
return true;
}

bool found_apfs_root_hash_new = false;
bool kpf_apfs_root_hash_new(struct xnu_pf_patch *patch, uint32_t *opcode_stream) {
uint32_t* b = find_prev_insn(opcode_stream, 3, 0x14000000, 0xfc000000);

if (!b) return false;

uint32_t* cbz = find_next_insn(opcode_stream, 10, 0x34000000, 0xff00001f); // cbz w0, Lvalidated_root_hash

if (!cbz) return false;

if ((cbz[-1] & 0xfc000000) != 0x94000000) return false; // bl

if (found_apfs_root_hash_new)
panic("kpf_apfs_root_hash_new: found twice!");

cbz[-1] = 0x52800000; // mov w0, #0

found_apfs_root_hash_new = true;

printf("KPF: found apfs_root_hash_new\n");
return true;
}

void* found_apfs_handle_fsioc_graft = NULL;
bool kpf_apfs_handle_fsioc_graft_new(struct xnu_pf_patch *patch, uint32_t *opcode_stream) {
uint32_t* cbz = find_prev_insn(opcode_stream, 20, 0x34000000, 0xff00001f); // cbz w0, Lvalidated_payload_and_manifest

if (!cbz) return false;

if ((cbz[-1] & 0xfc000000) != 0x94000000) return false; // bl

if (found_apfs_handle_fsioc_graft && found_apfs_handle_fsioc_graft != cbz)
panic("kpf_apfs_handle_fsioc_graft_new: found twice!");

cbz[-1] = 0x52800000; // mov w0, #0

found_apfs_handle_fsioc_graft = cbz;

printf("KPF: found apfs_handle_fsioc_graft_new\n");
return true;
}

#if 0
bool handled_eval_rootauth = false;
bool kpf_apfs_rootauth(struct xnu_pf_patch *patch, uint32_t *opcode_stream) {
Expand Down Expand Up @@ -1295,7 +1337,7 @@ bool kpf_apfs_rootauth_new(struct xnu_pf_patch *patch, uint32_t *opcode_stream)
}
#endif

void kpf_apfs_patches(xnu_pf_patchset_t* patchset, bool have_ssv, bool apfs_vfsop_mount_string_match) {
void kpf_apfs_patches(xnu_pf_patchset_t* patchset, bool have_ssv, bool apfs_vfsop_mount_string_match, bool root_hash_string_match, bool graft_image4_string_match) {
// there is a check in the apfs mount function that makes sure that the kernel task is calling this function (current_task() == kernel_task)
// we also want to call it so we patch that check out
// example from i7 13.3:
Expand Down Expand Up @@ -1448,6 +1490,48 @@ void kpf_apfs_patches(xnu_pf_patchset_t* patchset, bool have_ssv, bool apfs_vfso
xnu_pf_maskmatch(patchset,
"apfs_root_snapshot_name", root_snapshot_matches, root_snapshot_masks, sizeof(root_snapshot_matches) / sizeof(uint64_t), true ,(void *)kpf_apfs_root_snapshot_name);
}

if (root_hash_string_match) {
// Patch root hash verification

uint64_t root_hash_new_matches[] = {
0xd3430c02 // ubfx x2, xN, #3, #1
};

uint64_t root_hash_new_masks[] = {
0xfffffc1f
};

xnu_pf_maskmatch(patchset,
"apfs_graft_new", root_hash_new_matches, root_hash_new_masks, sizeof(root_hash_new_matches) / sizeof(uint64_t), true ,(void *)kpf_apfs_root_hash_new);

}
if (graft_image4_string_match) {
// Patch root hash image4 verification

uint64_t handle_fsioc_graft_matches[] = {
0xaa1003e0, // mov x0, x{16-31}
0xaa1003e1, // mov x1, x{16-31}
0xaa1003e3, // mov x3, x{16-31}
0xd2800004, // mov x4, #0
0xd2800005, // mov x5, #0
0xaa1003e6, // mov x6, x{16-31}
0x14000000 // b
};

uint64_t handle_fsioc_graft_masks[] = {
0xfff0ffff,
0xfff0ffff,
0xfff0ffff,
0xffffffff,
0xffffffff,
0xfff0ffff,
0xfc000000
};

xnu_pf_maskmatch(patchset,
"handle_fsioc_graft_new", handle_fsioc_graft_matches, handle_fsioc_graft_masks, sizeof(handle_fsioc_graft_matches) / sizeof(uint64_t), false ,(void *)kpf_apfs_handle_fsioc_graft_new);
}
}
static uint32_t* amfi_ret;
bool kpf_amfi_execve_tail(struct xnu_pf_patch* patch, uint32_t* opcode_stream) {
Expand Down Expand Up @@ -2383,6 +2467,19 @@ static void kpf_cmd(const char *cmd, char *args)
#endif
}

const char root_hash_string[] = "%s:%d: %s Failed to authenticate root hash (volume type %d): %d\n";
const char* root_hash_string_match = apfs_text_cstring_range ? memmem(apfs_text_cstring_range->cacheable_base, apfs_text_cstring_range->size, root_hash_string, sizeof(root_hash_string)) : NULL;
if (!root_hash_string_match) root_hash_string_match = memmem(text_cstring_range->cacheable_base, text_cstring_range->size, root_hash_string, sizeof(root_hash_string));

const char graft_image4_string[] = "%s:%d: %s Failed to validate image4 payload and manifest for grafting: %d\n";
const char* graft_image4_string_match = apfs_text_cstring_range ? memmem(apfs_text_cstring_range->cacheable_base, apfs_text_cstring_range->size, graft_image4_string, sizeof(graft_image4_string)) : NULL;
if (!graft_image4_string_match) graft_image4_string_match = memmem(text_cstring_range->cacheable_base, text_cstring_range->size, graft_image4_string, sizeof(graft_image4_string));

if (gKernelVersion.darwinMajor < 24 || xnu_platform() != PLATFORM_IOS) {
graft_image4_string_match = NULL;
root_hash_string_match = NULL;
}

#ifdef DEV_BUILD
// 15.0 beta 1 onwards, but only iOS/iPadOS
if((livefs_string_match != NULL) != (
Expand Down Expand Up @@ -2496,7 +2593,7 @@ static void kpf_cmd(const char *cmd, char *args)
}
}

kpf_apfs_patches(apfs_patchset, livefs_string_match != NULL, apfs_vfsop_mount_string_match != NULL);
kpf_apfs_patches(apfs_patchset, livefs_string_match != NULL, apfs_vfsop_mount_string_match != NULL, root_hash_string_match != NULL, graft_image4_string_match != NULL);

if (!(palera1n_flags & palerain_option_rootful) && !(palera1n_flags & palerain_option_rootless)) {
if (livefs_string_match) {
Expand Down Expand Up @@ -2879,6 +2976,40 @@ void module_entry(void)
puts("# Cellebrite (ih8sn0w, cjori, ronyrus et al.)");
puts("#==================");

#if !defined(KPF_TEST)
puts("Fixing up bootargs");


dt_node_t *memory_map = dt_node(gDeviceTree, "/chosen/memory-map");
struct memmap *map = dt_alloc_memmap(memory_map, "FunnyBootArgs");
if(!map)
{
panic("Failed to allocate FunnyBootArgs memory map");
}

struct boot_args* cBootArgs = (struct boot_args*)((uint64_t)gBootArgs - 0x800000000 + kCacheableView);
struct boot_args* new_BootArgs = alloc_static(0x4000);
bzero(new_BootArgs, sizeof(struct boot_args));
new_BootArgs->Revision = 3;
new_BootArgs->Version = 2;
new_BootArgs->virtBase = cBootArgs->virtBase;
new_BootArgs->physBase = cBootArgs->physBase;
new_BootArgs->memSize = cBootArgs->memSize;
new_BootArgs->topOfKernelData = cBootArgs->topOfKernelData;
memcpy(&new_BootArgs->Video, &cBootArgs->Video, sizeof(struct Boot_Video));
new_BootArgs->machineType = cBootArgs->machineType;
new_BootArgs->deviceTreeLength = cBootArgs->deviceTreeLength;
new_BootArgs->deviceTreeP = cBootArgs->deviceTreeP;
memcpy(new_BootArgs->iOS18.CommandLine, cBootArgs->iOS13.CommandLine, BOOT_LINE_LENGTH_iOS13);
new_BootArgs->iOS18.bootFlags = cBootArgs->iOS13.bootFlags;
new_BootArgs->iOS18.memSizeActual = cBootArgs->iOS13.memSizeActual;
gBootArgs = (void*)(((uint64_t)new_BootArgs) + 0x800000000 - kCacheableView);
map->addr = ((uint64_t)new_BootArgs) + 0x800000000 - kCacheableView;
map->size = 0x4000;

*(uint32_t*)dt_prop(dt_find(gDeviceTree, "/chosen"), "debug-enabled", NULL) = 1;
#endif

for(size_t i = 0; i < sizeof(kpf_components)/sizeof(kpf_components[0]); ++i)
{
kpf_component_t *component = kpf_components[i];
Expand Down
7 changes: 7 additions & 0 deletions example/include/pongo.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#define DT_KEY_LEN 0x20
#define BOOT_LINE_LENGTH_iOS12 0x100
#define BOOT_LINE_LENGTH_iOS13 0x260
#define BOOT_LINE_LENGTH_iOS18 0x400

struct Boot_Video {
unsigned long v_baseAddr; /* Base address of video memory */
Expand Down Expand Up @@ -69,6 +70,12 @@ typedef struct boot_args {
uint64_t bootFlags; /* Additional flags specified by the bootloader */
uint64_t memSizeActual; /* Actual size of memory */
} iOS13;
struct {
char CommandLine[BOOT_LINE_LENGTH_iOS18]; /* Passed in command line */
uint32_t __pad;
uint64_t bootFlags; /* Additional flags specified by the bootloader */
uint64_t memSizeActual; /* Actual size of memory */
} iOS18;
};
} __attribute__((packed)) boot_args;

Expand Down
7 changes: 7 additions & 0 deletions src/kernel/pongo.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@

#define BOOT_LINE_LENGTH_iOS12 0x100
#define BOOT_LINE_LENGTH_iOS13 0x260
#define BOOT_LINE_LENGTH_iOS18 0x400

extern int service_cmd(const char* name, int cmd_id, void* data_in, size_t in_size, void* data_out, size_t* out_size);

Expand Down Expand Up @@ -106,6 +107,12 @@ typedef struct boot_args {
uint64_t bootFlags; /* Additional flags specified by the bootloader */
uint64_t memSizeActual; /* Actual size of memory */
} iOS13;
struct {
char CommandLine[BOOT_LINE_LENGTH_iOS18]; /* Passed in command line */
uint32_t __pad;
uint64_t bootFlags; /* Additional flags specified by the bootloader */
uint64_t memSizeActual; /* Actual size of memory */
} iOS18;
};
} __attribute__((packed)) boot_args;

Expand Down

0 comments on commit eba05df

Please sign in to comment.