From 85a16afa806444d5fba59cedffa8f596c886c1f3 Mon Sep 17 00:00:00 2001 From: Mateico <116546494+mateicoes@users.noreply.github.com> Date: Fri, 15 May 2026 15:04:08 +0200 Subject: [PATCH] remove data_cave offset and use page alloc for sc args --- include/config.h | 5 ++- include/loader.h | 1 - include/offsets.h | 1 - include/prepare_resume.h | 4 +-- include/utils.h | 6 ++++ source/loader.c | 66 +++------------------------------------- source/offsets.c | 9 ------ source/prepare_resume.c | 36 +++++++++++----------- source/utils.c | 58 +++++++++++++++++++++++++++++++++++ 9 files changed, 92 insertions(+), 94 deletions(-) diff --git a/include/config.h b/include/config.h index f2fd709..812ea2e 100644 --- a/include/config.h +++ b/include/config.h @@ -18,9 +18,12 @@ #define hv_stack_size 0x1000ULL // This is used as transitional storage from ProsperoOS to Kernel shellcode -#define kernel_cave_files 0xFFFF800000000000 +#define kernel_cave 0xFFFF800000000000 +#define kernel_cave_arguments kernel_cave +#define kernel_cave_files kernel_cave_arguments + PAGE_SIZE #define kernel_cave_linux_info kernel_cave_files #define kernel_cave_bzImage kernel_cave_linux_info + PAGE_SIZE + // #define kernel_cave_initrd // Allocated dynamically after bzImage // Linux boot config diff --git a/include/loader.h b/include/loader.h index d1c1389..ebb3a12 100644 --- a/include/loader.h +++ b/include/loader.h @@ -3,7 +3,6 @@ #include "utils.h" #include -uint64_t alloc_page(void); void install_page(uintptr_t pml4, vm_offset_t va, vm_paddr_t pa, int bits); void pte_store(uintptr_t ptep, uint64_t pte); int read_file(const char *path, void *buf, size_t bufsize); diff --git a/include/offsets.h b/include/offsets.h index 110620a..f06ff67 100644 --- a/include/offsets.h +++ b/include/offsets.h @@ -12,7 +12,6 @@ typedef struct _offset_list { /* Shellcode Kernel */ uint64_t HOOK_ACPI_WAKEUP_MACHDEP; uint64_t KERNEL_CODE_CAVE; - uint64_t KERNEL_DATA_CAVE; uint64_t FUN_PRINTF; uint64_t FUN_HV_IOMMU_SET_BUFFERS; uint64_t FUN_HV_IOMM_WAIT_COMPLETION; diff --git a/include/prepare_resume.h b/include/prepare_resume.h index d4145a5..f019691 100644 --- a/include/prepare_resume.h +++ b/include/prepare_resume.h @@ -5,8 +5,8 @@ extern struct linux_info linux_i; int prepare_resume(void); -int update_sck_data_ptr(void *sc, uint64_t dest_text, uint64_t dest_data); +uint64_t prepare_sck_args(void); +int update_sck_args_ptr(uint64_t shellcode, uint64_t args); void hook_call_near(uint64_t hook, uint64_t dst); -void prepare_sck_args(uint64_t dest_data); #endif diff --git a/include/utils.h b/include/utils.h index e37acdb..79d8bb3 100644 --- a/include/utils.h +++ b/include/utils.h @@ -167,4 +167,10 @@ enum kit_type { KIT_RETAIL, KIT_TESTKIT, KIT_DEVKIT }; enum kit_type get_kit_type(void); +#define MINI_SYSCORE_PID 1 + +uint64_t alloc_page(void); +void pte_store(uintptr_t ptep, uint64_t pte); +void install_page(uintptr_t pml4, vm_offset_t va, vm_paddr_t pa, int bits); +void install_page_syscore(vm_offset_t va, vm_paddr_t pa, int bits); #endif diff --git a/source/loader.c b/source/loader.c index 00e1cbf..2742e02 100644 --- a/source/loader.c +++ b/source/loader.c @@ -19,59 +19,6 @@ #include #include -#define MINI_SYSCORE_PID 1 - -uint64_t alloc_page(void) { - void *page = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, - MAP_SHARED | MAP_ANONYMOUS, -1, 0); - - // Fault it to force physical allocation - *(uint8_t *)page = 0; - - return vtophys_user((uintptr_t)page); -} - -void install_page(uintptr_t pml4, vm_offset_t va, vm_paddr_t pa, int bits) { - uint64_t entry; - - uintptr_t pml4e = pml4 + pmap_pml4e_index(va) * 8; - entry = kread64(pml4e); - if (!PAGE_P(entry)) { - uint64_t page = alloc_page(); - entry = page | PG_B_RW | PG_B_P | bits; - kwrite64(pml4e, entry); - } - - uintptr_t pdpe = pa_to_dmap(PAGE_PA(entry)) + pmap_pdpe_index(va) * 8; - entry = kread64(pdpe); - if (!(entry & PG_B_P)) { - uint64_t page = alloc_page(); - entry = page | PG_B_RW | PG_B_P | bits; - kwrite64(pdpe, entry); - } - - uintptr_t pde = pa_to_dmap(PAGE_PA(entry)) + pmap_pde_index(va) * 8; - entry = kread64(pde); - if (!(entry & PG_B_P)) { - uint64_t page = alloc_page(); - entry = page | PG_B_RW | PG_B_P | bits; - kwrite64(pde, entry); - } - - uintptr_t pte = pa_to_dmap(PAGE_PA(entry)) + pmap_pte_index(va) * 8; - entry = pa | PG_B_RW | PG_B_P | bits; - pte_store(pte, entry); -} - -void pte_store(uintptr_t ptep, uint64_t pte) { - static_assert((PAGE_SIZE % 0x1000) == 0, - "PAGE_SIZE should be a multiple of 0x1000"); - - for (uint64_t i = 0; i < (PAGE_SIZE / 0x1000); i++) { - kwrite64(ptep + i * 8, pte + i * 0x1000); - } -} - const char *file_paths[] = { "/mnt/usb0/", "/mnt/usb1/", "/mnt/usb2/", "/mnt/usb3/", "/mnt/usb0/PS5/Linux/", "/mnt/usb1/PS5/Linux/", @@ -179,9 +126,6 @@ void trim_newline(char *s) { } int fetch_linux(struct linux_info *info) { - uintptr_t syscore_pmap = getpmap(kernel_get_proc(MINI_SYSCORE_PID)); - uintptr_t syscore_pml4 = kread64(syscore_pmap + 0x20); - char bzimage_path[256]; char initrd_path[256]; @@ -269,16 +213,16 @@ int fetch_linux(struct linux_info *info) { uint64_t page = alloc_page(); kwrite(pa_to_dmap(page), info, sizeof(struct linux_info)); - install_page(syscore_pml4, kernel_cave_linux_info, page, 0); + install_page_syscore(kernel_cave_linux_info, page, 0); for (int i = 0; i < bzimage_size; i += PAGE_SIZE) { - install_page(syscore_pml4, info->bzimage + i, - vtophys_user((uintptr_t)bzimage + i), 0); + install_page_syscore(info->bzimage + i, + vtophys_user((uintptr_t)bzimage + i), 0); } for (int i = 0; i < initrd_size; i += PAGE_SIZE) { - install_page(syscore_pml4, info->initrd + i, - vtophys_user((uintptr_t)initrd + i), 0); + install_page_syscore(info->initrd + i, vtophys_user((uintptr_t)initrd + i), + 0); } return 0; diff --git a/source/offsets.c b/source/offsets.c index b58d57d..e527a69 100644 --- a/source/offsets.c +++ b/source/offsets.c @@ -7,7 +7,6 @@ offset_list off_0300 = { .DATA_BASE_GVMSPACE = 0x06423F80, .HOOK_ACPI_WAKEUP_MACHDEP = 0x0390E73, .KERNEL_CODE_CAVE = 0x500, - .KERNEL_DATA_CAVE = 0xC01300, .FUN_PRINTF = 0x048B9A0, .FUN_HV_IOMMU_SET_BUFFERS = 0x0B33E20, .FUN_HV_IOMM_WAIT_COMPLETION = 0x0B33D50, @@ -33,7 +32,6 @@ offset_list off_0310 = { .DATA_BASE_GVMSPACE = 0x06423F80, .HOOK_ACPI_WAKEUP_MACHDEP = 0x0390EB3, .KERNEL_CODE_CAVE = 0x500, - .KERNEL_DATA_CAVE = 0xC01300, .FUN_PRINTF = 0x048B9E0, .FUN_HV_IOMMU_SET_BUFFERS = 0x0B33E60, .FUN_HV_IOMM_WAIT_COMPLETION = 0x0B33D90, @@ -59,7 +57,6 @@ offset_list off_0320 = { .DATA_BASE_GVMSPACE = 0x06423F80, .HOOK_ACPI_WAKEUP_MACHDEP = 0x391203, .KERNEL_CODE_CAVE = 0x500, - .KERNEL_DATA_CAVE = 0xC01300, .FUN_PRINTF = 0x48BD30, .FUN_HV_IOMMU_SET_BUFFERS = 0xB34320, .FUN_HV_IOMM_WAIT_COMPLETION = 0xB34250, @@ -85,7 +82,6 @@ offset_list off_0321 = { .DATA_BASE_GVMSPACE = 0x06423F80, .HOOK_ACPI_WAKEUP_MACHDEP = 0x391203, .KERNEL_CODE_CAVE = 0x500, - .KERNEL_DATA_CAVE = 0xC01300, .FUN_PRINTF = 0x48BD30, .FUN_HV_IOMMU_SET_BUFFERS = 0xB34320, .FUN_HV_IOMM_WAIT_COMPLETION = 0xB34250, @@ -112,7 +108,6 @@ offset_list off_0400 = { .HOOK_ACPI_WAKEUP_MACHDEP = 0x3A7613, .FUN_PRINTF = 0x4A3240, .KERNEL_CODE_CAVE = 0x500, - .KERNEL_DATA_CAVE = 0xC01300, .FUN_HV_IOMMU_SET_BUFFERS = 0xB638F0, .FUN_HV_IOMM_WAIT_COMPLETION = 0xB63830, .FUN_SMP_RENDEZVOUS = 0xA6C920, @@ -137,7 +132,6 @@ offset_list off_0402 = { .DATA_BASE_GVMSPACE = 0x064C3F80, .HOOK_ACPI_WAKEUP_MACHDEP = 0x3A7613, .KERNEL_CODE_CAVE = 0x500, - .KERNEL_DATA_CAVE = 0xC01300, .FUN_PRINTF = 0x4A3240, .FUN_HV_IOMMU_SET_BUFFERS = 0xB63950, .FUN_HV_IOMM_WAIT_COMPLETION = 0xB63890, @@ -163,7 +157,6 @@ offset_list off_0403 = { .DATA_BASE_GVMSPACE = 0x064C3F80, .HOOK_ACPI_WAKEUP_MACHDEP = 0x3A7613, .KERNEL_CODE_CAVE = 0x500, - .KERNEL_DATA_CAVE = 0xC01300, .FUN_PRINTF = 0x4A3240, .FUN_HV_IOMMU_SET_BUFFERS = 0xB639F0, .FUN_HV_IOMM_WAIT_COMPLETION = 0xB63930, @@ -189,7 +182,6 @@ offset_list off_0450 = { .DATA_BASE_GVMSPACE = 0x064C3F80, .HOOK_ACPI_WAKEUP_MACHDEP = 0x03A75E3, .KERNEL_CODE_CAVE = 0x500, - .KERNEL_DATA_CAVE = 0xC01300, .FUN_PRINTF = 0x04A3270, .FUN_HV_IOMMU_SET_BUFFERS = 0xB63BB0, .FUN_HV_IOMM_WAIT_COMPLETION = 0xB63AF0, @@ -215,7 +207,6 @@ offset_list off_0451 = { .DATA_BASE_GVMSPACE = 0x64C3F80, .HOOK_ACPI_WAKEUP_MACHDEP = 0x3A75E3, .KERNEL_CODE_CAVE = 0x500, - .KERNEL_DATA_CAVE = 0xC01300, .FUN_PRINTF = 0x4A3270, .FUN_HV_IOMMU_SET_BUFFERS = 0xB63FE0, .FUN_HV_IOMM_WAIT_COMPLETION = 0xB63F20, diff --git a/source/prepare_resume.c b/source/prepare_resume.c index a8da9bb..20979f2 100644 --- a/source/prepare_resume.c +++ b/source/prepare_resume.c @@ -1,6 +1,7 @@ #include "prepare_resume.h" #include "../shellcode_kernel/shellcode_kernel.h" #include "../shellcode_kernel/shellcode_kernel_args.h" +#include "config.h" #include "iommu.h" #include "offsets.h" #include "utils.h" @@ -14,21 +15,14 @@ int prepare_resume(void) { return -1; } - if (env_offset.KERNEL_DATA_CAVE == 0) { - printf("Error: missing data cave offset\n"); - return -1; - } - - uint64_t dest_text = ktext + env_offset.KERNEL_CODE_CAVE; - uint64_t dest_data = ktext + env_offset.KERNEL_DATA_CAVE; - - kwrite_large(dest_text, shellcode_kernel_bin, shellcode_kernel_bin_len); - prepare_sck_args(dest_data); - - if (update_sck_data_ptr(shellcode_kernel_bin, dest_text, dest_data)) + uint64_t args_va = prepare_sck_args(); + if (update_sck_args_ptr((uint64_t)shellcode_kernel_bin, args_va)) return -1; - hook_call_near(ktext + env_offset.HOOK_ACPI_WAKEUP_MACHDEP, dest_text); + uint64_t sck_va = ktext + env_offset.KERNEL_CODE_CAVE; + kwrite_large(sck_va, shellcode_kernel_bin, shellcode_kernel_bin_len); + + hook_call_near(ktext + env_offset.HOOK_ACPI_WAKEUP_MACHDEP, sck_va); kwrite8(ktext + env_offset.KERNEL_DEBUG_PATCH, 0xC3); kwrite8(ktext + env_offset.KERNEL_CFI_CHECK, 0xC3); @@ -36,11 +30,11 @@ int prepare_resume(void) { return 0; } -int update_sck_data_ptr(void *sc, uint64_t dest_text, uint64_t dest_data) { +int update_sck_args_ptr(uint64_t shellcode, uint64_t args) { // Find the address 0x11AA11AA11AA11AA used as marker int offset = -1; - for (int i = 0; i < 0x40; i++) { - if (*(uint64_t *)((uint64_t)sc + i) == 0x11AA11AA11AA11AA) { + for (uint64_t i = 0; i < 0x40; i++) { + if (*(uint64_t *)(shellcode + i) == 0x11AA11AA11AA11AA) { offset = i; break; } @@ -49,7 +43,7 @@ int update_sck_data_ptr(void *sc, uint64_t dest_text, uint64_t dest_data) { notify("Could not find offset of args_ptr address - Aborting\n"); return -1; } - kwrite64(dest_text + offset, dest_data); + *(uint64_t *)(shellcode + offset) = args; return 0; } @@ -62,7 +56,7 @@ void hook_call_near(uint64_t hook, uint64_t dst) { DEBUG_PRINT("Instruction patched\n"); } -void prepare_sck_args(uint64_t dest_data) { +uint64_t prepare_sck_args(void) { shellcode_kernel_args args; args.fw_version = fw; args.ktext = ktext; @@ -94,5 +88,9 @@ void prepare_sck_args(uint64_t dest_data) { args.linux_info_va = linux_i.linux_info; - kernel_copyin(&args, dest_data, sizeof(args)); + uint64_t args_cave = alloc_page(); + kernel_copyin(&args, pa_to_dmap(args_cave), sizeof(args)); + install_page_syscore(kernel_cave_arguments, args_cave, 0); + + return kernel_cave_arguments; } \ No newline at end of file diff --git a/source/utils.c b/source/utils.c index 638a412..128a830 100644 --- a/source/utils.c +++ b/source/utils.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -284,3 +285,60 @@ enum kit_type get_kit_type(void) { notify("Retail console detected\n"); return KIT_RETAIL; } + +uint64_t alloc_page(void) { + void *page = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, -1, 0); + + // Fault it to force physical allocation + *(uint8_t *)page = 0; + + return vtophys_user((uintptr_t)page); +} + +void install_page(uintptr_t pml4, vm_offset_t va, vm_paddr_t pa, int bits) { + uint64_t entry; + + uintptr_t pml4e = pml4 + pmap_pml4e_index(va) * 8; + entry = kread64(pml4e); + if (!PAGE_P(entry)) { + uint64_t page = alloc_page(); + entry = page | PG_B_RW | PG_B_P | bits; + kwrite64(pml4e, entry); + } + + uintptr_t pdpe = pa_to_dmap(PAGE_PA(entry)) + pmap_pdpe_index(va) * 8; + entry = kread64(pdpe); + if (!(entry & PG_B_P)) { + uint64_t page = alloc_page(); + entry = page | PG_B_RW | PG_B_P | bits; + kwrite64(pdpe, entry); + } + + uintptr_t pde = pa_to_dmap(PAGE_PA(entry)) + pmap_pde_index(va) * 8; + entry = kread64(pde); + if (!(entry & PG_B_P)) { + uint64_t page = alloc_page(); + entry = page | PG_B_RW | PG_B_P | bits; + kwrite64(pde, entry); + } + + uintptr_t pte = pa_to_dmap(PAGE_PA(entry)) + pmap_pte_index(va) * 8; + entry = pa | PG_B_RW | PG_B_P | bits; + pte_store(pte, entry); +} + +void pte_store(uintptr_t ptep, uint64_t pte) { + static_assert((PAGE_SIZE % 0x1000) == 0, + "PAGE_SIZE should be a multiple of 0x1000"); + + for (uint64_t i = 0; i < (PAGE_SIZE / 0x1000); i++) { + kwrite64(ptep + i * 8, pte + i * 0x1000); + } +} + +void install_page_syscore(vm_offset_t va, vm_paddr_t pa, int bits) { + uintptr_t syscore_pmap = getpmap(kernel_get_proc(MINI_SYSCORE_PID)); + uintptr_t syscore_pml4 = kread64(syscore_pmap + 0x20); + install_page(syscore_pml4, va, pa, bits); +}