From 691e50f35953674cdeebe1306a01c7b7442cdc12 Mon Sep 17 00:00:00 2001 From: Ouroboros <47540491+Ouroboroshen@users.noreply.github.com> Date: Mon, 19 Oct 2026 08:37:57 -0300 Subject: [PATCH] 13.20 and 13.00 support (#49) * add 13.20 support * add 13.00 support * Update README.md update readme to reflect new 13.00, 13.20 and 13.60 support. --- .gitignore | 1 + Makefile | 14 ++++- README.md | 5 +- include/offsets.h | 2 + shellcode_kernel/boot_linux.c | 28 +++++++++ shellcode_kernel/linker.ld | 1 + shellcode_kernel/main.c | 9 ++- shellcode_kernel_13xx/Makefile | 42 +++++++++++++ source/hv_defeat_13xx.c | 47 ++++++++------ source/khook.c | 28 ++++++--- source/main.c | 2 +- source/offsets.c | 112 +++++++++++++++++++++++++++++++++ source/prepare_resume.c | 29 +++++++-- source/utils.c | 6 ++ 14 files changed, 289 insertions(+), 37 deletions(-) create mode 100644 shellcode_kernel_13xx/Makefile diff --git a/.gitignore b/.gitignore index ef61b4d..422fa80 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ bin/ shellcode_0607/shellcode_0607.h shellcode_kernel/shellcode_kernel.h +shellcode_kernel_13xx/shellcode_kernel_13xx.h shellcode_hv/shellcode_hv.h *.elf *.bin diff --git a/Makefile b/Makefile index 4da90e2..9b45ee0 100644 --- a/Makefile +++ b/Makefile @@ -16,8 +16,9 @@ LDFLAGS := SC_0607_H := shellcode_0607/shellcode_0607.h SC_HV_H := shellcode_hv/shellcode_hv.h SC_K_H := shellcode_kernel/shellcode_kernel.h +SC_K_13XX_H := shellcode_kernel_13xx/shellcode_kernel_13xx.h -all: $(SC_0607_H) $(SC_HV_H) $(SC_K_H) $(BIN) +all: $(SC_0607_H) $(SC_HV_H) $(SC_K_H) $(SC_K_13XX_H) $(BIN) $(SC_0607_H): $(MAKE) -C shellcode_0607 @@ -28,9 +29,19 @@ $(SC_HV_H): $(SC_K_H): $(MAKE) -C shellcode_kernel +$(SC_K_13XX_H): $(SC_HV_H) shellcode_kernel/main.c \ + shellcode_kernel/boot_linux.c shellcode_kernel/utils.c \ + shellcode_kernel/main.h shellcode_kernel/boot_linux.h \ + shellcode_kernel/utils.h shellcode_kernel/shellcode_kernel_args.h \ + shellcode_kernel/linker.ld include/config.h include/linux.h \ + shellcode_kernel_13xx/Makefile + $(MAKE) -C shellcode_kernel_13xx + $(OBJS): %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< +source/prepare_resume.o: $(SC_K_13XX_H) + $(BIN): $(OBJS) @mkdir -p $(dir $@) $(CC) $(OBJS) $(LDFLAGS) -o $@ @@ -40,3 +51,4 @@ clean: $(MAKE) -C shellcode_0607 clean $(MAKE) -C shellcode_hv clean $(MAKE) -C shellcode_kernel clean + $(MAKE) -C shellcode_kernel_13xx clean diff --git a/README.md b/README.md index cd6a3a3..c27b446 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # ps5-linux -**ps5-linux** leverages patched HV vulnerabilities to transform your **PS5 Phat and Slim** console running **3.00-7.61 firmwares** into a highly capable Linux PC, unlocking its full hardware potential for desktop use. Powered by 8 CPU cores (16 threads) at **3.5 GHz** and a GPU at **2.23 GHz**, it provides enough performance to run Steam games and various emulators with impressive fluidity. +**ps5-linux** leverages patched HV vulnerabilities to transform your **PS5 Phat and Slim** console running **3.00-13.60 firmwares** into a highly capable Linux PC, unlocking its full hardware potential for desktop use. Powered by 8 CPU cores (16 threads) at **3.5 GHz** and a GPU at **2.23 GHz**, it provides enough performance to run Steam games and various emulators with impressive fluidity. Features: @@ -23,6 +23,7 @@ Features: - **5.00**, **5.02**, **5.10**, **5.50** with M.2 support - **6.00**, **6.02**, **6.50** with M.2 support - **7.00**, **7.01**, **7.20**, **7.40**, **7.60**, **7.61** with M.2 support +- **13.00**, **13.20**, **13.60** with M.2 support Support for 1.xx and 2.xx firmwares may be added in the future, but we will not prioritize this effort. @@ -261,7 +262,7 @@ For any future ps5-linux updates, you can download the `.deb` or `.pkg.tar.zst` ## FAQ -- Q: Will higher >=8.00 firmwares be supported? +- Q: Will higher >=14.00 firmwares be supported? - A: No. - Q: Why can I not use M.2 on 3.xx? - A: Because the PS5 fails to boot with it attached. diff --git a/include/offsets.h b/include/offsets.h index 921b754..8583d1f 100644 --- a/include/offsets.h +++ b/include/offsets.h @@ -99,6 +99,8 @@ extern offset_list off_0720; extern offset_list off_0740; extern offset_list off_0760; extern offset_list off_0761; +extern offset_list off_1300; +extern offset_list off_1320; extern offset_list off_1360; #endif diff --git a/shellcode_kernel/boot_linux.c b/shellcode_kernel/boot_linux.c index 862e346..b3f6440 100644 --- a/shellcode_kernel/boot_linux.c +++ b/shellcode_kernel/boot_linux.c @@ -60,12 +60,25 @@ struct dig_transmitter_control_parameters_v1_6 { static struct linux_info info; +#if defined(FW_13XX_PORT) +static int *mp3_req, *mp3_rsp; +#else static int mp3_req[1281], mp3_rsp[1282]; +#endif static inline void stac(void) { __asm__ volatile("stac" : : : "cc"); } static inline void clac(void) { __asm__ volatile("clac" : : : "cc"); } +#if defined(FW_13XX_PORT) +static uint64_t read_tsc(void) { + uint32_t lo, hi; + __asm__ volatile("rdtsc" : "=a"(lo), "=d"(hi)); + return ((uint64_t)hi << 32) | lo; +} + +#endif + static inline uint64_t vmmcall(uint64_t nr, uint64_t a0, uint64_t a1, uint64_t a2) { uint64_t ret; @@ -169,6 +182,11 @@ void patch_hv(void) { } void boot_linux(void) { +#if defined(FW_13XX_PORT) + mp3_rsp = (int *)(args.linux_info_va + 0x1000); + mp3_req = (int *)(args.linux_info_va + 0x2420); +#endif + patch_hv(); // Common bootloader code @@ -179,6 +197,12 @@ void boot_linux(void) { // Enable DP phys link. dp_enable_link_phy(4, 30); +#if defined(FW_13XX_PORT) + uint64_t start = read_tsc(); + while (read_tsc() - start < 0x14DC937FULL) + __asm__ volatile("pause"); +#endif + // Initialize hdcp in mp3. mp3_initialize(0); mp3_set_hdcp_packet(0, 1); @@ -187,6 +211,7 @@ void boot_linux(void) { // Copy bzImage and initrd into contiguous memory. memcpy(&info, (void *)args.linux_info_va, sizeof(struct linux_info)); +#if !defined(FW_13XX_PORT) info.n_tmrs = 0; if (args.fw_version >= 0x0500 && args.fw_version < 0x0800) { SceSblHvShm *shm = (SceSblHvShm *)PHYS_TO_DMAP(get_hv_shm()); @@ -200,6 +225,9 @@ void boot_linux(void) { } } } +#else + info.n_tmrs = 0; +#endif uintptr_t bzimage = info.bzimage; uintptr_t initrd = info.initrd; diff --git a/shellcode_kernel/linker.ld b/shellcode_kernel/linker.ld index 611bd59..ae200bd 100644 --- a/shellcode_kernel/linker.ld +++ b/shellcode_kernel/linker.ld @@ -15,4 +15,5 @@ SECTIONS *(.bss) *(.bss.*) } + ASSERT(SIZEOF(.shell_code) <= (DEFINED(SHELLCODE_LIMIT) ? SHELLCODE_LIMIT : 0x100000), "shellcode exceeds kernel code cave") } diff --git a/shellcode_kernel/main.c b/shellcode_kernel/main.c index 2f922e1..ac91135 100644 --- a/shellcode_kernel/main.c +++ b/shellcode_kernel/main.c @@ -1,6 +1,8 @@ #include "main.h" #include "boot_linux.h" +#if !defined(FW_13XX_PORT) #include "hv_defeat_0304.h" +#endif #include "utils.h" #include @@ -22,8 +24,12 @@ __attribute__((section(".entry_point"))) uint32_t main(uint64_t add1, return -1; } +#if defined(FW_13XX_PORT) + if (args_ptr->fw_version < 0x1300 || args_ptr->fw_version >= 0x1400) + return -1; + activate_uart(args_ptr); +#else activate_uart(args_ptr); - if ((0x0300 <= args_ptr->fw_version) && (args_ptr->fw_version < 0x0500)) { if (hv_defeat_0304(args_ptr)) return -1; @@ -33,6 +39,7 @@ __attribute__((section(".entry_point"))) uint32_t main(uint64_t add1, } else { return 0; } +#endif // Now we can R/W on .text init_global_pointers(args_ptr); diff --git a/shellcode_kernel_13xx/Makefile b/shellcode_kernel_13xx/Makefile new file mode 100644 index 0000000..8a85679 --- /dev/null +++ b/shellcode_kernel_13xx/Makefile @@ -0,0 +1,42 @@ +ifeq ($(shell uname -m),aarch64) +CC = x86_64-linux-gnu-gcc +LD = x86_64-linux-gnu-ld +OBJCOPY = x86_64-linux-gnu-objcopy +else +CC = gcc +LD = ld +OBJCOPY = objcopy +endif +CFLAGS = -Os -fno-stack-protector -ffreestanding -nostdlib \ + -fcf-protection=none -mno-sse -mno-sse2 -m64 -ffunction-sections \ + -fdata-sections -DFW_13XX_PORT=1 +LDFLAGS = -T ../shellcode_kernel/linker.ld \ + -Wl,--gc-sections,--defsym,SHELLCODE_LIMIT=0x3910 +TARGET = shellcode_kernel_13xx.elf +TEXT_BIN = shellcode_kernel_13xx.bin +dump = shellcode_kernel_13xx.h + +SRC = main.c boot_linux.c utils.c +OBJ = $(SRC:.c=.o) +HEADERS = ../shellcode_kernel/main.h ../shellcode_kernel/boot_linux.h \ + ../shellcode_kernel/utils.h ../shellcode_kernel/shellcode_kernel_args.h \ + ../include/config.h ../include/linux.h ../shellcode_hv/shellcode_hv.h + +all: $(dump) + +$(TARGET): $(OBJ) + $(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) -o $(TARGET) + +$(OBJ): %.o: ../shellcode_kernel/%.c $(HEADERS) + $(CC) $(CFLAGS) -c $< -o $@ + +$(TEXT_BIN): $(TARGET) + $(OBJCOPY) -O binary -j .shell_code $(TARGET) $(TEXT_BIN) + +clean: + rm -f $(OBJ) $(TARGET) $(TEXT_BIN) $(dump) + +$(dump): $(TEXT_BIN) + xxd -i $(TEXT_BIN) > $(dump) + +.PHONY: all clean diff --git a/source/hv_defeat_13xx.c b/source/hv_defeat_13xx.c index 6f2094a..5cb510d 100644 --- a/source/hv_defeat_13xx.c +++ b/source/hv_defeat_13xx.c @@ -9,9 +9,9 @@ #include #define KH_POP_RSP_1360 0x291C42 -#define CARRIER_PA_1360 0x3FFFF000 -#define HV_HEAP_OFFSET_1360 0x83028 -#define HV_PCPUS_OFFSET_1360 0x82A60 +#define CARRIER_PA 0x3FFFF000 +#define HV_HEAP_POINTER_OFFSET 0x83028 +#define HV_PCPUS_POINTER_OFFSET 0x82A60 static int kernel_read(uint64_t address, void *buffer, size_t length) { return kernel_copyout((intptr_t)address, buffer, length); @@ -32,7 +32,8 @@ uint64_t kgadget(kgadget_t gadget) { offset = env_offset.GAD_IRETQ; break; case KERNEL_GADGET_POP_RAX: - offset = env_offset.GAD_RET_TRAMP - 1; + offset = fw == 0x1360 ? env_offset.GAD_RET_TRAMP - 1 + : env_offset.GAD_POP_RAX_RET; break; case KERNEL_GADGET_POP_RCX: offset = env_offset.GAD_POP_RCX_RET; @@ -50,7 +51,7 @@ uint64_t kgadget(kgadget_t gadget) { offset = env_offset.GAD_POP_R8_RET; break; case KERNEL_GADGET_POP_RSP: - offset = KH_POP_RSP_1360; + offset = fw == 0x1360 ? KH_POP_RSP_1360 : env_offset.GAD_POP_RSP_RET; break; case KERNEL_GADGET_STORE_RCX_R8: offset = env_offset.GAD_STORE_RCX_R8_RET; @@ -92,10 +93,13 @@ uint64_t kgadget(kgadget_t gadget) { return 0; } - return ktext + offset; + return offset ? ktext + offset : 0; } static int offsets_present(void) { + if (fw != 0x1300 && fw != 0x1320 && fw != 0x1360) + return 0; + const uint64_t required[] = { env_offset.ACPIGBL_FACS, env_offset.IDT, @@ -324,7 +328,6 @@ static int pin_to_core_reborn(int core) { cpusetid_t cpuset_id; uint64_t cpuset_affinity[2] = {0xFFFF, 0}; uint64_t affinity[2]; - if (core < 0 || core >= 16) return -1; if (cpuset(&cpuset_id)) @@ -342,8 +345,10 @@ static int install_startup_hook(uint64_t hv_base) { kh_chain_t chain; uint8_t chain_buffer[0x800]; uint64_t data_cave = ktext + env_offset.DATA_CAVE; - uint64_t carrier = dmap + CARRIER_PA_1360; + uint64_t carrier = dmap + CARRIER_PA; uint64_t oracle; + uint64_t heap_pointer_slot = hv_base + HV_HEAP_POINTER_OFFSET; + uint64_t pcpus_pointer_slot = hv_base + HV_PCPUS_POINTER_OFFSET; int result; if (kernel_write(data_cave + 0x1000, stock_shellcode_ap_1360, @@ -371,10 +376,8 @@ static int install_startup_hook(uint64_t hv_base) { kh_chain_store(&chain, carrier + 0xF08, dmap); kh_chain_store(&chain, carrier + 0xF10, oracle); kh_chain_store(&chain, carrier + 0xF18, hv_base); - kh_chain_store(&chain, carrier + 0xF20, - hv_base + HV_HEAP_OFFSET_1360); - kh_chain_store(&chain, carrier + 0xF28, - hv_base + HV_PCPUS_OFFSET_1360); + kh_chain_store(&chain, carrier + 0xF20, heap_pointer_slot); + kh_chain_store(&chain, carrier + 0xF28, pcpus_pointer_slot); kh_chain_store(&chain, carrier + 0xF30, 1); if (chain.err || clear_execute_disable(carrier)) @@ -396,33 +399,37 @@ int hv_defeat_13xx(void *shellcode_kernel, size_t shellcode_kernel_len) { uint64_t waking_vector; int result; - if (fw != 0x1360 || !shellcode_kernel || !shellcode_kernel_len || - !offsets_present()) { - notify("13.60 offsets incomplete\n"); + if ((fw != 0x1300 && fw != 0x1320 && fw != 0x1360) || !shellcode_kernel || + !shellcode_kernel_len || !offsets_present()) { + if (fw == 0x1360) + notify("13.60 offsets incomplete\n"); return -1; } if (check_nvs_signature()) { - notify("13.60 firmware signature check failed\n"); + if (fw == 0x1360) + notify("13.60 firmware signature check failed\n"); return -1; } hv_base = derive_h(); if (!hv_base) { - notify("13.60 hypervisor base was not found\n"); + if (fw == 0x1360) + notify("13.60 hypervisor base was not found\n"); return -1; } kernel_set_ucred_authid(getpid(), 0x4800000000000007ULL); result = pin_to_core_reborn(0); if (result) { - notify("13.60 core pin failed (%d)\n", result); + if (fw == 0x1360) + notify("13.60 core pin failed (%d)\n", result); return -1; } - result = install_startup_hook(hv_base); if (result) { - notify("13.60 startup hook failed (%d)\n", result); + if (fw == 0x1360) + notify("13.60 startup hook failed (%d)\n", result); return -1; } diff --git a/source/khook.c b/source/khook.c index 477cc90..36ad05d 100644 --- a/source/khook.c +++ b/source/khook.c @@ -69,16 +69,31 @@ int kh_chain_q(kh_chain_t *chain, uint64_t raw) int kh_chain_g(kh_chain_t *chain, kgadget_t gadget) { - return kh_chain_q(chain, kgadget(gadget)); + uint64_t address = kgadget(gadget); + if (!address) { + if (chain) + chain->err = 1; + return -1; + } + return kh_chain_q(chain, address); } int kh_chain_store(kh_chain_t *chain, uint64_t kaddr, uint64_t val) { - kh_chain_g(chain, KERNEL_GADGET_POP_RCX); - kh_chain_q(chain, kaddr); - kh_chain_g(chain, KERNEL_GADGET_POP_R8); - kh_chain_q(chain, val); - kh_chain_g(chain, KERNEL_GADGET_STORE_RCX_R8); + if (kgadget(KERNEL_GADGET_POP_R8) && + kgadget(KERNEL_GADGET_STORE_RCX_R8)) { + kh_chain_g(chain, KERNEL_GADGET_POP_RCX); + kh_chain_q(chain, kaddr); + kh_chain_g(chain, KERNEL_GADGET_POP_R8); + kh_chain_q(chain, val); + kh_chain_g(chain, KERNEL_GADGET_STORE_RCX_R8); + } else { + kh_chain_g(chain, KERNEL_GADGET_POP_RCX); + kh_chain_q(chain, kaddr); + kh_chain_g(chain, KERNEL_GADGET_POP_RAX); + kh_chain_q(chain, val); + kh_chain_g(chain, KERNEL_GADGET_ST_RCX_RAX); + } return chain && !chain->err ? 0 : -1; } @@ -132,7 +147,6 @@ int kh_init(khook_t *kh, kh_read_fn rd, kh_write_fn wr, uint64_t kernel_base, ui kh->kernel_base = kernel_base; kh->scratch_base = scratch_base; kh->ist_index = ist_index; - return 0; } diff --git a/source/main.c b/source/main.c index 720081a..268a3c0 100644 --- a/source/main.c +++ b/source/main.c @@ -35,7 +35,7 @@ int main(void) { } else if ((0x0650 <= fw) && (fw < 0x0800)) { if (hv_defeat_0607(shellcode_kernel, shellcode_kernel_len)) goto err; - } else if (fw == 0x1360) { + } else if (fw == 0x1300 || fw == 0x1320 || fw == 0x1360) { if (hv_defeat_13xx(shellcode_kernel, shellcode_kernel_len)) goto err; } else { diff --git a/source/offsets.c b/source/offsets.c index 48f17e2..952c78b 100644 --- a/source/offsets.c +++ b/source/offsets.c @@ -766,6 +766,118 @@ offset_list off_0761 = { .PS5_WIFI_FW_SIZE = 497636, }; +offset_list off_1300 = { + .IOMMU_SOFTC = 0x3532CF0, + .VMSPACE_VM_VMID = 0x1EC, + .VMSPACE_VM_PMAP = 0x1D8, + .DATA_BASE_GVMSPACE = 0x2ED6570, + .ACPIGBL_FACS = 0x39B5390, + .IDT = 0x3B90300, + .COMMON_TSS = 0x3B92FE0, + .FUN_MEMCPY = 0x259070, + .GAD_ADD_RSP_28_POP_RBP_RET = 0x9DAC44, + .GAD_IRETQ = 0x257AFD, + .GAD_POP_RAX_RET = 0x291231, + .GAD_POP_RDI_RET = 0x31A4A3, + .GAD_POP_RSI_RET = 0x2A46ED, + .GAD_POP_RDX_RET = 0x2A0D3B, + .GAD_POP_RCX_RET = 0x291842, + .GAD_POP_RSP_RET = 0x291BD2, + .GAD_WRMSR_RET = 0x254FF4, + .HOOK_ACPI_WAKEUP_MACHDEP = 0x3909B0, + .KERNEL_CODE_CAVE = 0xCAC6F0, + .FUN_PRINTF = 0x4ABB00, + .FUN_HV_IOMMU_SET_BUFFERS = 0xC09D30, + .FUN_HV_IOMM_WAIT_COMPLETION = 0xC09C70, + .FUN_SMP_RENDEZVOUS = 0xAF92E0, + .FUN_SMP_NO_RENDEVOUS_BARRIER = 0xAF90A0, + .HV_CODE_CAVE_PA = 0x62806F00, + .HV_HANDLE_VMEXIT_PA = 0x62847375, + .KERNEL_UART_OVERRIDE = 0x21E9378, + .KERNEL_CFI_CHECK = 0x44E550, + .G_VBIOS = 0x3DB39F0, + .FUN_TRANSMITTER_CONTROL = 0xC01CD0, + .FUN_MP3_INITIALIZE = 0xA0BAC0, + .FUN_MP3_INVOKE = 0xA0A6C0, + .PS5_WIFI_FW_OFFSET = 0x1505170, + .PS5_WIFI_FW_SIZE = 0x7A248, + .HV_MP_STARTUP_CALL = 0xC0A110, + .MP_STARTUP_INIT_VECTOR = 0x269238, + .DATA_CAVE = 0x2D29000, + .GAD_PIVOT_ADD_RSP28_RET = 0x2520FE, + .GAD_POP_R8_RET = 0xB820BD, + .GAD_STORE_RCX_R8_RET = 0x472B09, + .GAD_STORE_RDI8_RCX_RET = 0x325D8F, + .GAD_OR_RCX_EAX_RET = 0x802E40, + .GAD_SET_DR7_RET = 0x9FF536, + .GAD_STORE_RCX_RDX_RET = 0x8247D5, + .GAD_STORE_RCX_RAX_RET = 0x2BB04F, + .GAD_MOV_RAX_RSI_RET = 0x8DB9F4, + .GAD_MOV_RAX_RDI_RET = 0xBE007A, + .GAD_REP_MOVSB_RET = 0x25CFE7, + .GAD_CLD_RET = 0x2883B0, + .GAD_RET_TRAMP = 0x291232, + .GAD_DBREG_RESUME = 0x252998, + .NVS_SIGNATURE = 0x1A06D40, + .HV_EFI_MAP_ROOT = 0x3DC9070, +}; + +offset_list off_1320 = { + .IOMMU_SOFTC = 0x3532CF0, + .VMSPACE_VM_VMID = 0x1EC, + .VMSPACE_VM_PMAP = 0x1D8, + .DATA_BASE_GVMSPACE = 0x2ED6570, + .ACPIGBL_FACS = 0x39B5390, + .IDT = 0x3B90300, + .COMMON_TSS = 0x3B92FE0, + .FUN_MEMCPY = 0x259070, + .GAD_ADD_RSP_28_POP_RBP_RET = 0x9DAF54, + .GAD_IRETQ = 0x257AFD, + .GAD_POP_RAX_RET = 0x291231, + .GAD_POP_RDI_RET = 0x3CBFAD, + .GAD_POP_RSI_RET = 0x632731, + .GAD_POP_RDX_RET = 0x2A0D3B, + .GAD_POP_RCX_RET = 0x291842, + .GAD_POP_RSP_RET = 0x291BD2, + .GAD_WRMSR_RET = 0x254FF4, + .GAD_MOV_QWORD_PTR_RDI_RSI_POP_RBP_RET = 0x3D34DA, + .KERNEL_CODE_CAVE = 0xCAC6F0, + .FUN_PRINTF = 0x25D4B0, + .FUN_HV_IOMMU_SET_BUFFERS = 0xC09F30, + .FUN_HV_IOMM_WAIT_COMPLETION = 0xC09E70, + .FUN_SMP_RENDEZVOUS = 0xAF94E0, + .FUN_SMP_NO_RENDEVOUS_BARRIER = 0x2642A8, + .HV_CODE_CAVE_PA = 0x62806F00, + .HV_HANDLE_VMEXIT_PA = 0x62847375, + .KERNEL_UART_OVERRIDE = 0x21E9378, + .KERNEL_CFI_CHECK = 0x44E5D0, + .G_VBIOS = 0x3DB39F0, + .FUN_TRANSMITTER_CONTROL = 0xC01ED0, + .FUN_MP3_INITIALIZE = 0xA0BDD0, + .FUN_MP3_INVOKE = 0xA0A9D0, + .PS5_WIFI_FW_OFFSET = 0x1505170, + .PS5_WIFI_FW_SIZE = 0x7A248, + .HV_MP_STARTUP_CALL = 0xC0A310, + .MP_STARTUP_INIT_VECTOR = 0x26A798, + .DATA_CAVE = 0x2D29000, + .GAD_PIVOT_ADD_RSP28_RET = 0x2520FE, + .GAD_POP_R8_RET = 0xB822BD, + .GAD_STORE_RCX_R8_RET = 0x472B89, + .GAD_STORE_RDI8_RCX_RET = 0x325D8F, + .GAD_OR_RCX_EAX_RET = 0x803150, + .GAD_SET_DR7_RET = 0x9FF846, + .GAD_STORE_RCX_RDX_RET = 0x824AE5, + .GAD_STORE_RCX_RAX_RET = 0x2BB04F, + .GAD_MOV_RAX_RSI_RET = 0x8DBD04, + .GAD_MOV_RAX_RDI_RET = 0xBE027A, + .GAD_REP_MOVSB_RET = 0x25CFE7, + .GAD_CLD_RET = 0x304D17, + .GAD_RET_TRAMP = 0x291232, + .GAD_DBREG_RESUME = 0x252998, + .NVS_SIGNATURE = 0x1A06DF0, + .HV_EFI_MAP_ROOT = 0x3DC9070, +}; + offset_list off_1360 = { .IOMMU_SOFTC = 0x3543A70, .VMSPACE_VM_VMID = 0x1EC, diff --git a/source/prepare_resume.c b/source/prepare_resume.c index d5a019a..2e465a3 100644 --- a/source/prepare_resume.c +++ b/source/prepare_resume.c @@ -6,9 +6,11 @@ #include "offsets.h" #include "shellcode_1360.h" #include "utils.h" +#include "../shellcode_kernel_13xx/shellcode_kernel_13xx.h" #include #include #include +#include static int apply_1360_dma_e820_map(void *buffer, size_t length) { static const struct { @@ -101,11 +103,17 @@ int prepare_resume(void **shellcode_kernel, size_t *shellcode_kernel_len) { const uint8_t *shellcode_src = shellcode_kernel_bin; size_t shellcode_len = shellcode_kernel_bin_len; - if (fw == 0x1360) { + if (fw == 0x1300 || fw == 0x1320) { + shellcode_src = shellcode_kernel_13xx_bin; + shellcode_len = shellcode_kernel_13xx_bin_len; + } else if (fw == 0x1360) { shellcode_src = stock_shellcode_kernel_1360; shellcode_len = stock_shellcode_kernel_1360_len; } + if ((fw == 0x1300 || fw == 0x1320) && shellcode_len > 0x3910) + return -1; + *shellcode_kernel = mmap(NULL, ALIGN_UP(shellcode_len, PAGE_SIZE), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); @@ -120,7 +128,8 @@ int prepare_resume(void **shellcode_kernel, size_t *shellcode_kernel_len) { } uint64_t args_va = prepare_sck_args(); - if (update_sck_args_ptr((uint64_t)*shellcode_kernel, args_va)) + if (!args_va || + update_sck_args_ptr((uint64_t)*shellcode_kernel, args_va)) return -1; // Install shellcode_kernel in kernel space. @@ -161,13 +170,15 @@ int update_sck_args_ptr(uint64_t shellcode, uint64_t args) { uint64_t prepare_sck_args(void) { shellcode_kernel_args args; + memset(&args, 0, sizeof(args)); args.fw_version = fw; args.ktext = ktext; args.kdata = kdata; args.dmap_base = dmap; args.fun_printf = ktext + env_offset.FUN_PRINTF; - args.fun_hv_iommu_set_buffers = ktext + env_offset.FUN_HV_IOMMU_SET_BUFFERS; + args.fun_hv_iommu_set_buffers = + ktext + env_offset.FUN_HV_IOMMU_SET_BUFFERS; args.fun_hv_iommu_wait_completion = ktext + env_offset.FUN_HV_IOMM_WAIT_COMPLETION; args.fun_smp_rendezvous = ktext + env_offset.FUN_SMP_RENDEZVOUS; @@ -188,8 +199,16 @@ uint64_t prepare_sck_args(void) { args.linux_info_va = linux_i.linux_info; - uint64_t args_cave = pa_to_dmap(alloc_page()); - kernel_copyin(&args, args_cave, sizeof(args)); + uint64_t args_pa = alloc_page(); + if (!args_pa) + return 0; + + uint64_t args_cave = pa_to_dmap(args_pa); + shellcode_kernel_args readback = {0}; + if (kernel_copyin(&args, args_cave, sizeof(args)) || + kernel_copyout((intptr_t)args_cave, &readback, sizeof(readback)) || + memcmp(&args, &readback, sizeof(args))) + return 0; return args_cave; } diff --git a/source/utils.c b/source/utils.c index d11a6fc..4a247d9 100644 --- a/source/utils.c +++ b/source/utils.c @@ -97,6 +97,12 @@ int set_offsets(void) { case 0x0761: env_offset = off_0761; break; + case 0x1300: + env_offset = off_1300; + break; + case 0x1320: + env_offset = off_1320; + break; case 0x1360: env_offset = off_1360; break;