mirror of
https://github.com/ps5-linux/ps5-linux-loader.git
synced 2026-07-18 03:50:59 +00:00
remove data_cave offset and use page alloc for sc args
This commit is contained in:
@@ -18,9 +18,12 @@
|
|||||||
#define hv_stack_size 0x1000ULL
|
#define hv_stack_size 0x1000ULL
|
||||||
|
|
||||||
// This is used as transitional storage from ProsperoOS to Kernel shellcode
|
// 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_linux_info kernel_cave_files
|
||||||
#define kernel_cave_bzImage kernel_cave_linux_info + PAGE_SIZE
|
#define kernel_cave_bzImage kernel_cave_linux_info + PAGE_SIZE
|
||||||
|
|
||||||
// #define kernel_cave_initrd // Allocated dynamically after bzImage
|
// #define kernel_cave_initrd // Allocated dynamically after bzImage
|
||||||
|
|
||||||
// Linux boot config
|
// Linux boot config
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
uint64_t alloc_page(void);
|
|
||||||
void install_page(uintptr_t pml4, vm_offset_t va, vm_paddr_t pa, int bits);
|
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);
|
void pte_store(uintptr_t ptep, uint64_t pte);
|
||||||
int read_file(const char *path, void *buf, size_t bufsize);
|
int read_file(const char *path, void *buf, size_t bufsize);
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ typedef struct _offset_list {
|
|||||||
/* Shellcode Kernel */
|
/* Shellcode Kernel */
|
||||||
uint64_t HOOK_ACPI_WAKEUP_MACHDEP;
|
uint64_t HOOK_ACPI_WAKEUP_MACHDEP;
|
||||||
uint64_t KERNEL_CODE_CAVE;
|
uint64_t KERNEL_CODE_CAVE;
|
||||||
uint64_t KERNEL_DATA_CAVE;
|
|
||||||
uint64_t FUN_PRINTF;
|
uint64_t FUN_PRINTF;
|
||||||
uint64_t FUN_HV_IOMMU_SET_BUFFERS;
|
uint64_t FUN_HV_IOMMU_SET_BUFFERS;
|
||||||
uint64_t FUN_HV_IOMM_WAIT_COMPLETION;
|
uint64_t FUN_HV_IOMM_WAIT_COMPLETION;
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
extern struct linux_info linux_i;
|
extern struct linux_info linux_i;
|
||||||
|
|
||||||
int prepare_resume(void);
|
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 hook_call_near(uint64_t hook, uint64_t dst);
|
||||||
void prepare_sck_args(uint64_t dest_data);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -167,4 +167,10 @@ enum kit_type { KIT_RETAIL, KIT_TESTKIT, KIT_DEVKIT };
|
|||||||
|
|
||||||
enum kit_type get_kit_type(void);
|
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
|
#endif
|
||||||
|
|||||||
@@ -19,59 +19,6 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#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[] = {
|
const char *file_paths[] = {
|
||||||
"/mnt/usb0/", "/mnt/usb1/", "/mnt/usb2/",
|
"/mnt/usb0/", "/mnt/usb1/", "/mnt/usb2/",
|
||||||
"/mnt/usb3/", "/mnt/usb0/PS5/Linux/", "/mnt/usb1/PS5/Linux/",
|
"/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) {
|
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 bzimage_path[256];
|
||||||
char initrd_path[256];
|
char initrd_path[256];
|
||||||
|
|
||||||
@@ -269,16 +213,16 @@ int fetch_linux(struct linux_info *info) {
|
|||||||
|
|
||||||
uint64_t page = alloc_page();
|
uint64_t page = alloc_page();
|
||||||
kwrite(pa_to_dmap(page), info, sizeof(struct linux_info));
|
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) {
|
for (int i = 0; i < bzimage_size; i += PAGE_SIZE) {
|
||||||
install_page(syscore_pml4, info->bzimage + i,
|
install_page_syscore(info->bzimage + i,
|
||||||
vtophys_user((uintptr_t)bzimage + i), 0);
|
vtophys_user((uintptr_t)bzimage + i), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < initrd_size; i += PAGE_SIZE) {
|
for (int i = 0; i < initrd_size; i += PAGE_SIZE) {
|
||||||
install_page(syscore_pml4, info->initrd + i,
|
install_page_syscore(info->initrd + i, vtophys_user((uintptr_t)initrd + i),
|
||||||
vtophys_user((uintptr_t)initrd + i), 0);
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ offset_list off_0300 = {
|
|||||||
.DATA_BASE_GVMSPACE = 0x06423F80,
|
.DATA_BASE_GVMSPACE = 0x06423F80,
|
||||||
.HOOK_ACPI_WAKEUP_MACHDEP = 0x0390E73,
|
.HOOK_ACPI_WAKEUP_MACHDEP = 0x0390E73,
|
||||||
.KERNEL_CODE_CAVE = 0x500,
|
.KERNEL_CODE_CAVE = 0x500,
|
||||||
.KERNEL_DATA_CAVE = 0xC01300,
|
|
||||||
.FUN_PRINTF = 0x048B9A0,
|
.FUN_PRINTF = 0x048B9A0,
|
||||||
.FUN_HV_IOMMU_SET_BUFFERS = 0x0B33E20,
|
.FUN_HV_IOMMU_SET_BUFFERS = 0x0B33E20,
|
||||||
.FUN_HV_IOMM_WAIT_COMPLETION = 0x0B33D50,
|
.FUN_HV_IOMM_WAIT_COMPLETION = 0x0B33D50,
|
||||||
@@ -33,7 +32,6 @@ offset_list off_0310 = {
|
|||||||
.DATA_BASE_GVMSPACE = 0x06423F80,
|
.DATA_BASE_GVMSPACE = 0x06423F80,
|
||||||
.HOOK_ACPI_WAKEUP_MACHDEP = 0x0390EB3,
|
.HOOK_ACPI_WAKEUP_MACHDEP = 0x0390EB3,
|
||||||
.KERNEL_CODE_CAVE = 0x500,
|
.KERNEL_CODE_CAVE = 0x500,
|
||||||
.KERNEL_DATA_CAVE = 0xC01300,
|
|
||||||
.FUN_PRINTF = 0x048B9E0,
|
.FUN_PRINTF = 0x048B9E0,
|
||||||
.FUN_HV_IOMMU_SET_BUFFERS = 0x0B33E60,
|
.FUN_HV_IOMMU_SET_BUFFERS = 0x0B33E60,
|
||||||
.FUN_HV_IOMM_WAIT_COMPLETION = 0x0B33D90,
|
.FUN_HV_IOMM_WAIT_COMPLETION = 0x0B33D90,
|
||||||
@@ -59,7 +57,6 @@ offset_list off_0320 = {
|
|||||||
.DATA_BASE_GVMSPACE = 0x06423F80,
|
.DATA_BASE_GVMSPACE = 0x06423F80,
|
||||||
.HOOK_ACPI_WAKEUP_MACHDEP = 0x391203,
|
.HOOK_ACPI_WAKEUP_MACHDEP = 0x391203,
|
||||||
.KERNEL_CODE_CAVE = 0x500,
|
.KERNEL_CODE_CAVE = 0x500,
|
||||||
.KERNEL_DATA_CAVE = 0xC01300,
|
|
||||||
.FUN_PRINTF = 0x48BD30,
|
.FUN_PRINTF = 0x48BD30,
|
||||||
.FUN_HV_IOMMU_SET_BUFFERS = 0xB34320,
|
.FUN_HV_IOMMU_SET_BUFFERS = 0xB34320,
|
||||||
.FUN_HV_IOMM_WAIT_COMPLETION = 0xB34250,
|
.FUN_HV_IOMM_WAIT_COMPLETION = 0xB34250,
|
||||||
@@ -85,7 +82,6 @@ offset_list off_0321 = {
|
|||||||
.DATA_BASE_GVMSPACE = 0x06423F80,
|
.DATA_BASE_GVMSPACE = 0x06423F80,
|
||||||
.HOOK_ACPI_WAKEUP_MACHDEP = 0x391203,
|
.HOOK_ACPI_WAKEUP_MACHDEP = 0x391203,
|
||||||
.KERNEL_CODE_CAVE = 0x500,
|
.KERNEL_CODE_CAVE = 0x500,
|
||||||
.KERNEL_DATA_CAVE = 0xC01300,
|
|
||||||
.FUN_PRINTF = 0x48BD30,
|
.FUN_PRINTF = 0x48BD30,
|
||||||
.FUN_HV_IOMMU_SET_BUFFERS = 0xB34320,
|
.FUN_HV_IOMMU_SET_BUFFERS = 0xB34320,
|
||||||
.FUN_HV_IOMM_WAIT_COMPLETION = 0xB34250,
|
.FUN_HV_IOMM_WAIT_COMPLETION = 0xB34250,
|
||||||
@@ -112,7 +108,6 @@ offset_list off_0400 = {
|
|||||||
.HOOK_ACPI_WAKEUP_MACHDEP = 0x3A7613,
|
.HOOK_ACPI_WAKEUP_MACHDEP = 0x3A7613,
|
||||||
.FUN_PRINTF = 0x4A3240,
|
.FUN_PRINTF = 0x4A3240,
|
||||||
.KERNEL_CODE_CAVE = 0x500,
|
.KERNEL_CODE_CAVE = 0x500,
|
||||||
.KERNEL_DATA_CAVE = 0xC01300,
|
|
||||||
.FUN_HV_IOMMU_SET_BUFFERS = 0xB638F0,
|
.FUN_HV_IOMMU_SET_BUFFERS = 0xB638F0,
|
||||||
.FUN_HV_IOMM_WAIT_COMPLETION = 0xB63830,
|
.FUN_HV_IOMM_WAIT_COMPLETION = 0xB63830,
|
||||||
.FUN_SMP_RENDEZVOUS = 0xA6C920,
|
.FUN_SMP_RENDEZVOUS = 0xA6C920,
|
||||||
@@ -137,7 +132,6 @@ offset_list off_0402 = {
|
|||||||
.DATA_BASE_GVMSPACE = 0x064C3F80,
|
.DATA_BASE_GVMSPACE = 0x064C3F80,
|
||||||
.HOOK_ACPI_WAKEUP_MACHDEP = 0x3A7613,
|
.HOOK_ACPI_WAKEUP_MACHDEP = 0x3A7613,
|
||||||
.KERNEL_CODE_CAVE = 0x500,
|
.KERNEL_CODE_CAVE = 0x500,
|
||||||
.KERNEL_DATA_CAVE = 0xC01300,
|
|
||||||
.FUN_PRINTF = 0x4A3240,
|
.FUN_PRINTF = 0x4A3240,
|
||||||
.FUN_HV_IOMMU_SET_BUFFERS = 0xB63950,
|
.FUN_HV_IOMMU_SET_BUFFERS = 0xB63950,
|
||||||
.FUN_HV_IOMM_WAIT_COMPLETION = 0xB63890,
|
.FUN_HV_IOMM_WAIT_COMPLETION = 0xB63890,
|
||||||
@@ -163,7 +157,6 @@ offset_list off_0403 = {
|
|||||||
.DATA_BASE_GVMSPACE = 0x064C3F80,
|
.DATA_BASE_GVMSPACE = 0x064C3F80,
|
||||||
.HOOK_ACPI_WAKEUP_MACHDEP = 0x3A7613,
|
.HOOK_ACPI_WAKEUP_MACHDEP = 0x3A7613,
|
||||||
.KERNEL_CODE_CAVE = 0x500,
|
.KERNEL_CODE_CAVE = 0x500,
|
||||||
.KERNEL_DATA_CAVE = 0xC01300,
|
|
||||||
.FUN_PRINTF = 0x4A3240,
|
.FUN_PRINTF = 0x4A3240,
|
||||||
.FUN_HV_IOMMU_SET_BUFFERS = 0xB639F0,
|
.FUN_HV_IOMMU_SET_BUFFERS = 0xB639F0,
|
||||||
.FUN_HV_IOMM_WAIT_COMPLETION = 0xB63930,
|
.FUN_HV_IOMM_WAIT_COMPLETION = 0xB63930,
|
||||||
@@ -189,7 +182,6 @@ offset_list off_0450 = {
|
|||||||
.DATA_BASE_GVMSPACE = 0x064C3F80,
|
.DATA_BASE_GVMSPACE = 0x064C3F80,
|
||||||
.HOOK_ACPI_WAKEUP_MACHDEP = 0x03A75E3,
|
.HOOK_ACPI_WAKEUP_MACHDEP = 0x03A75E3,
|
||||||
.KERNEL_CODE_CAVE = 0x500,
|
.KERNEL_CODE_CAVE = 0x500,
|
||||||
.KERNEL_DATA_CAVE = 0xC01300,
|
|
||||||
.FUN_PRINTF = 0x04A3270,
|
.FUN_PRINTF = 0x04A3270,
|
||||||
.FUN_HV_IOMMU_SET_BUFFERS = 0xB63BB0,
|
.FUN_HV_IOMMU_SET_BUFFERS = 0xB63BB0,
|
||||||
.FUN_HV_IOMM_WAIT_COMPLETION = 0xB63AF0,
|
.FUN_HV_IOMM_WAIT_COMPLETION = 0xB63AF0,
|
||||||
@@ -215,7 +207,6 @@ offset_list off_0451 = {
|
|||||||
.DATA_BASE_GVMSPACE = 0x64C3F80,
|
.DATA_BASE_GVMSPACE = 0x64C3F80,
|
||||||
.HOOK_ACPI_WAKEUP_MACHDEP = 0x3A75E3,
|
.HOOK_ACPI_WAKEUP_MACHDEP = 0x3A75E3,
|
||||||
.KERNEL_CODE_CAVE = 0x500,
|
.KERNEL_CODE_CAVE = 0x500,
|
||||||
.KERNEL_DATA_CAVE = 0xC01300,
|
|
||||||
.FUN_PRINTF = 0x4A3270,
|
.FUN_PRINTF = 0x4A3270,
|
||||||
.FUN_HV_IOMMU_SET_BUFFERS = 0xB63FE0,
|
.FUN_HV_IOMMU_SET_BUFFERS = 0xB63FE0,
|
||||||
.FUN_HV_IOMM_WAIT_COMPLETION = 0xB63F20,
|
.FUN_HV_IOMM_WAIT_COMPLETION = 0xB63F20,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "prepare_resume.h"
|
#include "prepare_resume.h"
|
||||||
#include "../shellcode_kernel/shellcode_kernel.h"
|
#include "../shellcode_kernel/shellcode_kernel.h"
|
||||||
#include "../shellcode_kernel/shellcode_kernel_args.h"
|
#include "../shellcode_kernel/shellcode_kernel_args.h"
|
||||||
|
#include "config.h"
|
||||||
#include "iommu.h"
|
#include "iommu.h"
|
||||||
#include "offsets.h"
|
#include "offsets.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
@@ -14,21 +15,14 @@ int prepare_resume(void) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (env_offset.KERNEL_DATA_CAVE == 0) {
|
uint64_t args_va = prepare_sck_args();
|
||||||
printf("Error: missing data cave offset\n");
|
if (update_sck_args_ptr((uint64_t)shellcode_kernel_bin, args_va))
|
||||||
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))
|
|
||||||
return -1;
|
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_DEBUG_PATCH, 0xC3);
|
||||||
kwrite8(ktext + env_offset.KERNEL_CFI_CHECK, 0xC3);
|
kwrite8(ktext + env_offset.KERNEL_CFI_CHECK, 0xC3);
|
||||||
@@ -36,11 +30,11 @@ int prepare_resume(void) {
|
|||||||
return 0;
|
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
|
// Find the address 0x11AA11AA11AA11AA used as marker
|
||||||
int offset = -1;
|
int offset = -1;
|
||||||
for (int i = 0; i < 0x40; i++) {
|
for (uint64_t i = 0; i < 0x40; i++) {
|
||||||
if (*(uint64_t *)((uint64_t)sc + i) == 0x11AA11AA11AA11AA) {
|
if (*(uint64_t *)(shellcode + i) == 0x11AA11AA11AA11AA) {
|
||||||
offset = i;
|
offset = i;
|
||||||
break;
|
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");
|
notify("Could not find offset of args_ptr address - Aborting\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
kwrite64(dest_text + offset, dest_data);
|
*(uint64_t *)(shellcode + offset) = args;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +56,7 @@ void hook_call_near(uint64_t hook, uint64_t dst) {
|
|||||||
DEBUG_PRINT("Instruction patched\n");
|
DEBUG_PRINT("Instruction patched\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepare_sck_args(uint64_t dest_data) {
|
uint64_t prepare_sck_args(void) {
|
||||||
shellcode_kernel_args args;
|
shellcode_kernel_args args;
|
||||||
args.fw_version = fw;
|
args.fw_version = fw;
|
||||||
args.ktext = ktext;
|
args.ktext = ktext;
|
||||||
@@ -94,5 +88,9 @@ void prepare_sck_args(uint64_t dest_data) {
|
|||||||
|
|
||||||
args.linux_info_va = linux_i.linux_info;
|
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;
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <ps5/kernel.h>
|
#include <ps5/kernel.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/cpuset.h>
|
#include <sys/cpuset.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/proc.h>
|
#include <sys/proc.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@@ -284,3 +285,60 @@ enum kit_type get_kit_type(void) {
|
|||||||
notify("Retail console detected\n");
|
notify("Retail console detected\n");
|
||||||
return KIT_RETAIL;
|
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);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user