1 Commits
Author SHA1 Message Date
Mateico 01436f0a6b some tidy up 2026-05-13 09:37:44 +02:00
58 changed files with 3270 additions and 4022 deletions
+1 -2
View File
@@ -1,7 +1,6 @@
bin/
shellcode_0607/shellcode_0607.h
shellcode_kernel/shellcode_kernel.h
shellcode_hv/shellcode_hv.h
shellcode_hypervisor/shellcode_hypervisor.h
*.elf
*.bin
*.o
+37 -42
View File
@@ -1,42 +1,37 @@
.PHONY: all clean
ifndef PS5_PAYLOAD_SDK
PS5_PAYLOAD_SDK = /opt/ps5-payload-sdk/
endif
include $(PS5_PAYLOAD_SDK)/toolchain/prospero.mk
BIN := bin/ps5-linux-loader.elf
SRC := $(wildcard source/*.c)
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_0607_H) $(SC_HV_H) $(SC_K_H) $(BIN)
$(SC_0607_H):
$(MAKE) -C shellcode_0607
$(SC_HV_H):
$(MAKE) -C shellcode_hv
$(SC_K_H):
$(MAKE) -C shellcode_kernel
$(OBJS): %.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
$(BIN): $(OBJS)
@mkdir -p $(dir $@)
$(CC) $(OBJS) $(LDFLAGS) -o $@
clean:
rm -f $(BIN) $(OBJS)
$(MAKE) -C shellcode_0607 clean
$(MAKE) -C shellcode_hv clean
$(MAKE) -C shellcode_kernel clean
.PHONY: all clean
ifndef PS5_PAYLOAD_SDK
PS5_PAYLOAD_SDK = /opt/ps5-payload-sdk/
endif
include $(PS5_PAYLOAD_SDK)/toolchain/prospero.mk
BIN := bin/ps5-linux-loader.elf
SRC := $(wildcard source/*.c)
OBJS := $(SRC:.c=.o)
CFLAGS := -std=c23 -Wall -Iinclude -Ishellcode_hypervisor -Ishellcode_kernel
LDFLAGS :=
SC_HV_H := shellcode_hypervisor/shellcode_hypervisor.h
SC_K_H := shellcode_kernel/shellcode_kernel.h
all: $(SC_HV_H) $(SC_K_H) $(BIN)
$(SC_HV_H):
$(MAKE) -C shellcode_hypervisor
$(SC_K_H):
$(MAKE) -C shellcode_kernel
$(OBJS): %.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
$(BIN): $(OBJS)
@mkdir -p $(dir $@)
$(CC) $(OBJS) $(LDFLAGS) -o $@
clean:
rm -f $(BIN) $(OBJS)
$(MAKE) -C shellcode_hypervisor clean
$(MAKE) -C shellcode_kernel clean
+58 -71
View File
@@ -1,39 +1,28 @@
# 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.
Features:
- HDMI 4K60 video and audio output
- M.2 SSD as dedicated Linux partition
- All USB ports usable for peripherals
- BD drive usable via custom ahci driver
- Internal Bluetooth usable via custom xhci driver
- Ethernet port usable via custom gbe driver
**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.
![Alt Text](logo.webp)
## PS5 firmware
*ps5-linux* is only supported on PS5 Phat and Slim on the following firmwares:
*ps5-linux* is currently only supported on PS5 Phat on 3.xx and 4.xx firmwares.
- **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
- **5.00**, **5.02**, **5.10**, **5.50** with M.2 support
- **6.00**, **6.02**, **6.50** with M.2 support
- **7.20**, **7.40**, **7.61** 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.
If you are on firmwares in-between or 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
To run *ps5-linux*, you need some required and optional hardwares:
- **Required**: USB drive with minimum 64GB (ideally external SSD) to install and run Linux.
- **Required**: USB Ethernet/WLAN adapter for internet access.
- **Required**: USB keyboard/mouse (dongles supported too).
- *Optional*: USB WLAN adapter for WLAN internet access.
- *Optional*: M.2 SSD compatible on PS5 (see [official guide](https://www.playstation.com/en-us/support/hardware/ps5-install-m2-ssd)) to run Linux from SSD.
- *Optional*: Bluetooth dongle to connect with PS5 DualSense controller.
@@ -55,17 +44,7 @@ If you reset your PS5 settings or reinstall the FW, you need to reapply these se
### 1. Get a Linux image
#### Pre-built images
You can download them from [ps5-linux-image](https://github.com/ps5-linux/ps5-linux-image/releases/tag/latest). Recommended is `ps5-ubuntu2604.img.xz`. Unpack the `.xz` file.
#### Build your own image
If you use Windows, run this in PowerShell or CMD as administrator to install WSL
```bash
wsl --install
```
#### Linux/macOS:
Install docker:
@@ -76,6 +55,38 @@ sudo service docker start
sudo usermod -aG docker $USER
```
Restart the terminal.
```bash
git clone https://github.com/ps5-linux/ps5-linux-image
cd ps5-linux-image
chmod +x ./build_image.sh
./build_image.sh --distro ubuntu2604
```
#### Windows (WSL2):
If WSL2 is not installed yet, run this in PowerShell or CMD as administrator, then restart:
```bash
wsl --install
```
Then open WSL and set up Docker:
```bash
sudo apt update
sudo apt install docker.io -y
sudo service docker start
sudo usermod -aG docker $USER
```
Restart WSL from PowerShell/CMD:
```bash
wsl --shutdown
```
Then clone and build:
```bash
@@ -111,29 +122,16 @@ 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
### 4. Run the jailbreak exploit
#### Firmware 3.00-5.50
1. Clone via: `git clone https://github.com/idlesauce/umtx2`
1. Clone https://github.com/idlesauce/umtx2
2. Configure fakedns via `dns.conf` to point `manuals.playstation.net` to your PCs IP address
3. Run fake dns: `sudo python fakedns.py -c dns.conf`
4. In a different terminal, run HTTPS server: `sudo python host.py`
3. Run fake dns: `python fakedns.py -c dns.conf`
4. Run HTTPS server: `python host.py`
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-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`
### 5. Send the payload
If you're on ARM64 Linux, first install the x86-64 cross-compilation tools before:
```bash
sudo apt install gcc-x86-64-linux-gnu binutils-x86-64-linux-gnu
```
#### 5. Send the payload
Either download [ps5-linux-loader.elf](https://github.com/ps5-linux/ps5-linux-loader/releases/), or install [ps5-payload-sdk](https://github.com/ps5-payload-dev/sdk) and compile it yourself:
```bash
@@ -142,18 +140,23 @@ cd ps5-linux-loader
make
```
Send the payload with your `$PS5IP` (shown on the page):
If you're on ARM64 Linux, then additionall install the x86-64 cross-compilation tools before:
```bash
socat -t 99999999 - TCP:$PS5IP:9021 < ps5-linux-loader.elf
sudo apt install gcc-x86-64-linux-gnu binutils-x86-64-linux-gnu
```
If all is successful, the payload will automatically go into rest mode. Wait until the orange LED stops blinking and becomes static. Only then, press the power button again to boot your PS5 into Linux. If the boot is successful, **the LED should turn white**. If it boots back into PS5 OS, then it's because you pressed the power button too early. Or, you did not enable rest mode features as described above. If it freezes instead of going into rest mode, then it is likely because you have etahen/kstuff enabled, which is incompatible. Disable them.
Find your PS5 IP at `Settings → Network → View Connection Status`.
```bash
socat -t 99999999 - TCP:192.168.178.127:9021 < ps5-linux-loader.elf
```
If all is successful, the payload will automatically go into rest mode. Wait until the orange LED stops blinking and becomes static. Only then, press the power button again to boot your PS5 into Linux. If the boot is successful, **the LED should turn white**. If it boots back into PS5 OS, then it's because you pressed the power button too early. Or, you did not enable rest mode features as described above.
If the LED is white, but you still have a blackscreen then:
- Try removing `video=DP-1:1920x1080@60` line in cmdline.txt.
- Try setting HDCP on or off (try both).
- Try different monitors or capture cards, ideally with different resolutions. Currently, some monitors have issues.
- Try setting `amdgpu.force_1080p=1` in `cmdline.txt` in the FAT32 partition of the USB drive.
@@ -199,14 +202,6 @@ Then, there are certain settings and commands we recommend doing:
make
```
7. If you have a Marvell WLAN chip (`lspci -nn` shows `40:00.7 Ethernet controller [0200]: Marvell Technology Group Ltd. Device [1b4b:2b56] (rev 02)`), then you can install the WLAN driver:
```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).
@@ -254,16 +249,8 @@ sudo ./ps5_control --boost on
Always turn on fan when your turn on boost, as this is what the official PS5 OS does.
## Updating ps5-linux
For any future ps5-linux updates, you can download the `.deb` or `.pkg.tar.zst` on your PS5 from [ps5-linux-patches](https://github.com/ps5-linux/ps5-linux-patches/releases) and install them like normal packages.
## FAQ
- Q: Will higher >=8.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.
- Q: Can I dual-boot Linux and PS5 OS?
- A: No, this is a soft-mod. You need to re-run the exploit in order to boot into Linux.
- Q: Can I put Linux into standby and resume?
@@ -271,13 +258,14 @@ For any future ps5-linux updates, you can download the `.deb` or `.pkg.tar.zst`
- Q: Can I continue using my PS5 if I install Linux?
- A: Yes, the internal SSD is not modified
- Q: Can I use the PS5's NIC/WLAN module in Linux?
- A: WLAN is only supported for Marvell chipsets at the moment. Ethernet is supported on all models.
- A: In theory yes, but someone needs to write or adapt drivers to use them.
- Q: Will higher >=6.50 firmwares be supported?
- A: No.
- Q: Does the DualSense controller work?
- A: Yes, via internal Bluetooth as well as Bluetooth dongle.
- A: Via a Bluetooth dongle. Built-in Bluetooth is not yet supported.
- Q: What resolutions and refresh rates are supported?
- A: 1080p, 1440p and 2160p at 60Hz are broadly supported. 1440p@120Hz has been the only confirmed working on the DELL S3225QC yet. 120Hz or 30Hz may be added in the future.
- Q: After reboot, I get a "Repairing" screen and "Your PS5 wasn't turned off properly." screen. Is that normal?
- A: Yes, and it's harmless.
## Tips and tricks
@@ -313,9 +301,8 @@ Join our [Discord server](https://discord.gg/PeMGVB7BAm) to celebrate Linux on P
- [theflow](https://github.com/TheOfficialFloW): [ps5-linux-loader](https://github.com/ps5-linux/ps5-linux-loader), [ps5-linux-patches](https://github.com/ps5-linux/ps5-linux-patches), [ps5-linux-tools](https://github.com/ps5-linux/ps5-linux-tools)
- [c0w](https://github.com/c0w-ar): [ps5-linux-loader](https://github.com/ps5-linux/ps5-linux-loader)
- [resulknad](https://github.com/resulknad): [ps5-linux-image](https://github.com/ps5-linux/ps5-linux-image)
- [rmuxnet](https://github.com/rmuxnet): [ps5 ethernet driver](https://github.com/ps5-linux/ps5-linux-patches/commit/643e214d7bd37f292045fc0dbb821e421f7a3e47)
- [fail0verflow](https://github.com/fail0verflow): [prosperous](https://github.com/fail0verflow/prosperous)
- [flatz](https://github.com/flatz): [HV exploit](https://gist.github.com/flatz/620ddda6d64acca6d1c990dc3080ac0e)
- [flatz](github.com/flatz): [HV exploit](https://gist.github.com/flatz/620ddda6d64acca6d1c990dc3080ac0e)
- [cragson](https://github.com/cragson): [HV expoit implementation](https://github.com/cragson/ps5-hen)
- [john-tornblom](https://github.com/john-tornblom): [PS5 SDK](https://github.com/ps5-payload-dev/sdk)
- [echostretch](https://github.com/echostretch): Offsets and testing
+34 -38
View File
@@ -1,38 +1,34 @@
#ifndef CONFIG_H
#define CONFIG_H
#define PAGE_SIZE 0x4000ULL
// This is used to allocate resources for HV shellcode and Linux boot
#define cave 0x100000000ULL
#define cave_hv_paging cave
#define cave_hv_code \
cave_hv_paging + 0x3000ULL // Leave space for 3 pages but we only use 2 for
// 1GB 1:1 mapping
#define cave_linux_files cave_hv_code + 0x2000ULL
#define cave_linux_info cave_linux_files
#define cave_bzImage cave_linux_info + PAGE_SIZE
// #define cave_initrd // Allocated dynamically after bzImage
#define hv_base_rsp (cave + 0x10000000ULL)
#define hv_stack_size 0x1000ULL
// This is used as transitional storage from ProsperoOS to Kernel shellcode
#define kernel_cave 0xFFFF800000000000
#define kernel_cave_shellcode kernel_cave
#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
// #define kernel_cave_initrd // Allocated dynamically after bzImage
// Linux boot config
#define VRAM_SIZE (512ULL * 1024 * 1024)
#define CMD_LINE \
"root=/dev/sda2 rw rootwait console=ttyTitania0 console=tty0 " \
"video=DP-1:1920x1080@60 mitigations=off idle=halt pci=pcie_bus_perf"
#define DEBUG 0 // Toggle to 0 to disable logs
#endif
#ifndef CONFIG_H
#define CONFIG_H
#define PAGE_SIZE 0x4000ULL
// This is used to allocate resources for HV shellcode and Linux boot
#define cave 0x100000000ULL
#define cave_hv_paging cave
#define cave_hv_code \
cave_hv_paging + 0x3000ULL // Leave space for 3 pages but we only use 2 for
// 1GB 1:1 mapping
#define cave_linux_files cave_hv_code + 0x2000ULL
#define cave_linux_info cave_linux_files
#define cave_bzImage cave_linux_info + PAGE_SIZE
// #define cave_initrd // Allocated dynamically after bzImage
#define hv_base_rsp (cave + 0x10000000ULL)
#define hv_stack_size 0x1000ULL
// This is used as transitional storage from ProsperoOS to Kernel shellcode
#define kernel_cave_files 0xFFFF800000000000
#define kernel_cave_linux_info kernel_cave_files
#define kernel_cave_bzImage kernel_cave_linux_info + PAGE_SIZE
// #define kernel_cave_initrd // Allocated dynamically after bzImage
// Linux boot config
#define VRAM_SIZE (512ULL * 1024 * 1024)
#define CMD_LINE \
"root=/dev/sda2 rw rootwait console=ttyTitania0 console=tty0 " \
"video=DP-1:1920x1080@60 mitigations=off idle=halt pci=pcie_bus_perf"
#define DEBUG 0 // Toggle to 0 to disable logs
#endif
+70 -70
View File
@@ -1,70 +1,70 @@
/*** Source: ps5-hen by cragson ***/
#ifndef GPU_H
#define GPU_H
#include <stdint.h>
#define GPU_PDE_VALID_BIT 0
#define GPU_PDE_IS_PTE_BIT 54
#define GPU_PDE_TF_BIT 56
#define GPU_PDE_BLOCK_FRAG_BIT 59
#define GPU_PDE_ADDR_MASK 0x0000FFFFFFFFFFC0ULL
#define PROT_GPU_READ 0x10
#define PROT_GPU_WRITE 0x20
#define MAP_NO_COALESCE 0x00400000
#define GPU_SUBMIT_IOCTL 0xC0108102
#define PM4_TYPE3 3
#define PM4_SHADER_COMPUTE 1
#define PM4_OPCODE_DMA_DATA 0x50
#define PM4_OPCODE_INDIRECT_BUF 0x3F
struct gpu_kernel_offsets {
uint64_t proc_vmspace; // proc->p_vmspace offset
uint64_t vmspace_vm_vmid; // vmspace->vm_vmid offset
uint64_t data_base_gvmspace; // offset from kernel data base to gvmspace array
uint64_t sizeof_gvmspace; // size of each gvmspace entry
uint64_t gvmspace_page_dir_va; // gvmspace->page_dir_va offset (GPU PDB2)
uint64_t gvmspace_size; // gvmspace->size offset
uint64_t gvmspace_start_va; // gvmspace->start_va offset
};
struct gpu_ctx {
int fd; // /dev/gc file descriptor
int initialized; // 1 if gpu_init() succeeded
uint64_t victim_va; // CPU VA of victim buffer (GPU PTE remapped)
uint64_t transfer_va; // CPU VA of transfer/staging buffer
uint64_t cmd_va; // CPU VA of PM4 command buffer
uint64_t victim_real_pa; // original physical address of victim buffer
uint64_t victim_ptbe_va; // kernel VA of the GPU PTE for victim buffer
uint64_t cleared_ptbe; // GPU PTE with physical address cleared (template)
uint64_t page_size; // GPU page size for victim allocation (should be 2MB)
uint64_t dmem_size; // allocation size (2MB)
};
void gpu_set_offsets(struct gpu_kernel_offsets *offsets);
int gpu_init(void);
int gpu_init_internal(void);
int gpu_test(void);
int gpu_read_phys(uint64_t phys_addr, void *out_buf, uint32_t size);
uint8_t gpu_read_phys1(uint64_t phys_addr);
uint32_t gpu_read_phys4(uint64_t phys_addr);
uint64_t gpu_read_phys8(uint64_t phys_addr);
int gpu_write_phys(uint64_t phys_addr, const void *in_buf, uint32_t size);
void gpu_write_phys4(uint64_t phys_addr, uint32_t value);
void gpu_write_phys8(uint64_t phys_addr, uint64_t value);
void gpu_cleanup(void);
struct gpu_ctx *gpu_get_ctx(void);
#endif
/*** Source: ps5-hen by cragson ***/
#ifndef GPU_H
#define GPU_H
#include <stdint.h>
#define GPU_PDE_VALID_BIT 0
#define GPU_PDE_IS_PTE_BIT 54
#define GPU_PDE_TF_BIT 56
#define GPU_PDE_BLOCK_FRAG_BIT 59
#define GPU_PDE_ADDR_MASK 0x0000FFFFFFFFFFC0ULL
#define PROT_GPU_READ 0x10
#define PROT_GPU_WRITE 0x20
#define MAP_NO_COALESCE 0x00400000
#define GPU_SUBMIT_IOCTL 0xC0108102
#define PM4_TYPE3 3
#define PM4_SHADER_COMPUTE 1
#define PM4_OPCODE_DMA_DATA 0x50
#define PM4_OPCODE_INDIRECT_BUF 0x3F
struct gpu_kernel_offsets {
uint64_t proc_vmspace; // proc->p_vmspace offset
uint64_t vmspace_vm_vmid; // vmspace->vm_vmid offset
uint64_t data_base_gvmspace; // offset from kernel data base to gvmspace array
uint64_t sizeof_gvmspace; // size of each gvmspace entry
uint64_t gvmspace_page_dir_va; // gvmspace->page_dir_va offset (GPU PDB2)
uint64_t gvmspace_size; // gvmspace->size offset
uint64_t gvmspace_start_va; // gvmspace->start_va offset
};
struct gpu_ctx {
int fd; // /dev/gc file descriptor
int initialized; // 1 if gpu_init() succeeded
uint64_t victim_va; // CPU VA of victim buffer (GPU PTE remapped)
uint64_t transfer_va; // CPU VA of transfer/staging buffer
uint64_t cmd_va; // CPU VA of PM4 command buffer
uint64_t victim_real_pa; // original physical address of victim buffer
uint64_t victim_ptbe_va; // kernel VA of the GPU PTE for victim buffer
uint64_t cleared_ptbe; // GPU PTE with physical address cleared (template)
uint64_t page_size; // GPU page size for victim allocation (should be 2MB)
uint64_t dmem_size; // allocation size (2MB)
};
void gpu_set_offsets(struct gpu_kernel_offsets *offsets);
int gpu_init(void);
int gpu_init_internal(void);
int gpu_test(void);
int gpu_read_phys(uint64_t phys_addr, void *out_buf, uint32_t size);
uint8_t gpu_read_phys1(uint64_t phys_addr);
uint32_t gpu_read_phys4(uint64_t phys_addr);
uint64_t gpu_read_phys8(uint64_t phys_addr);
int gpu_write_phys(uint64_t phys_addr, const void *in_buf, uint32_t size);
void gpu_write_phys4(uint64_t phys_addr, uint32_t value);
void gpu_write_phys8(uint64_t phys_addr, uint64_t value);
void gpu_cleanup(void);
struct gpu_ctx *gpu_get_ctx(void);
#endif
+19
View File
@@ -0,0 +1,19 @@
#ifndef HV_DEFEAT_H
#define HV_DEFEAT_H
#include "iommu.h"
#include <stdint.h>
int hv_defeat(void);
int stage1_tmr_relax(void);
int stage2_find_vmcbs(void);
uint64_t get_vmcb(int core);
int iommu_selftest(void);
int stage3_patch_vmcbs(void);
int stage4_force_vmcb_reload(void);
int stage5_remove_xotext(void);
int stage6_kernel_pmap_invalidate_all(void);
int stage7_install_kexec(void);
int kexec(uint64_t fptr);
#endif
-11
View File
@@ -1,11 +0,0 @@
#ifndef HV_DEFEAT_0304_H
#define HV_DEFEAT_0304_H
#include <stddef.h>
int hv_defeat_0304(void *shellcode_kernel, size_t shellcode_kernel_len);
int stage1_tmr_relax(void);
int stage2_patch_vmcbs(void);
int stage3_force_vmcb_reload(void);
#endif
-8
View File
@@ -1,8 +0,0 @@
#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
-8
View File
@@ -1,8 +0,0 @@
#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
+46 -46
View File
@@ -1,46 +1,46 @@
/*** Source: ps5-hen by cragson ***/
#ifndef IOMMU_H
#define IOMMU_H
#include <stdint.h>
// Command buffer MMIO offsets
#define IOMMU_MMIO_CB_HEAD 0xa000
#define IOMMU_MMIO_CB_TAIL 0xa008
// Queue constants
#define IOMMU_CB_SIZE 0x2000
#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
typedef struct _iommu_ctx {
uint64_t cb2_base; // kernel VA of command buffer 2 (hv terminology)
uint64_t cb3_base; // kernel VA of command buffer 3 (hv terminology)
uint64_t eb_base; // kernel VA of event buffer
uint64_t mmio_va; // DMAP VA of IOMMU MMIO base
} iommu_ctx;
extern iommu_ctx iommu_store;
extern iommu_ctx *iommu;
int iommu_init(void);
// Submit a single 16-byte command and wait for completion
void iommu_submit_cmd(const void *cmd);
// Write 8 bytes to a physical address using IOMMU completion wait store
void iommu_write8_pa(uint64_t pa, uint64_t val);
// Write 4 bytes to a physical address
void iommu_write4_pa(uint64_t pa, uint32_t val);
// Write arbitrary length to a physical address in 8-byte chunks
void iommu_write_pa(uint64_t pa, const void *data, uint32_t len);
#endif
/*** Source: ps5-hen by cragson ***/
#ifndef IOMMU_H
#define IOMMU_H
#include <stdint.h>
// Command buffer MMIO offsets
#define IOMMU_MMIO_CB_HEAD 0xa000
#define IOMMU_MMIO_CB_TAIL 0xa008
// Queue constants
#define IOMMU_CB_SIZE 0x2000
#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
typedef struct _iommu_ctx {
uint64_t cb2_base; // kernel VA of command buffer 2 (hv terminology)
uint64_t cb3_base; // kernel VA of command buffer 3 (hv terminology)
uint64_t eb_base; // kernel VA of event buffer
uint64_t mmio_va; // DMAP VA of IOMMU MMIO base
} iommu_ctx;
extern iommu_ctx iommu_store;
extern iommu_ctx *iommu;
int iommu_init(void);
// Submit a single 16-byte command and wait for completion
void iommu_submit_cmd(const void *cmd);
// Write 8 bytes to a physical address using IOMMU completion wait store
void iommu_write8_pa(uint64_t pa, uint64_t val);
// Write 4 bytes to a physical address
void iommu_write4_pa(uint64_t pa, uint32_t val);
// Write arbitrary length to a physical address in 8-byte chunks
void iommu_write_pa(uint64_t pa, const void *data, uint32_t len);
#endif
+15 -11
View File
@@ -1,11 +1,15 @@
#ifndef LOADER_H
#define LOADER_H
#include "utils.h"
void install_page(uintptr_t pml4, vm_offset_t va, vm_paddr_t pa, int bits);
void pte_store(uintptr_t ptep, uint64_t pte);
int read_file(const char *path, void *buf, size_t bufsize);
void trim_newline(char *s);
int fetch_linux(struct linux_info *info);
#endif
#ifndef LOADER_H
#define LOADER_H
#include "utils.h"
#include <stdint.h>
uint64_t alloc_page(void);
void install_page(uintptr_t pml4, vm_offset_t va, vm_paddr_t pa,
int bits);
void pte_store(uintptr_t ptep, uint64_t pte);
int read_file(const char *path, void *buf, size_t bufsize);
void trim_newline(char *s);
int fetch_linux(struct linux_info *info);
#endif
-8
View File
@@ -1,8 +0,0 @@
#ifndef MAIN_H
#define MAIN_H
int main(void);
int setup_env(void);
int prepare_resume(void);
#endif
+52 -75
View File
@@ -1,75 +1,52 @@
#ifndef OFFSETS_H
#define OFFSETS_H
#include <stdint.h>
typedef struct _offset_list {
/* Loader utils */
uint64_t IOMMU_SOFTC;
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_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;
uint64_t KERNEL_CODE_CAVE;
uint64_t FUN_PRINTF;
uint64_t FUN_HV_IOMMU_SET_BUFFERS;
uint64_t FUN_HV_IOMM_WAIT_COMPLETION;
uint64_t FUN_SMP_RENDEZVOUS;
uint64_t FUN_SMP_NO_RENDEVOUS_BARRIER;
/* Shellcode HV */
uint64_t HV_CODE_CAVE_PA;
uint64_t HV_HANDLE_VMEXIT_PA;
/* Patches on Kernel */
uint64_t KERNEL_UART_OVERRIDE;
uint64_t KERNEL_CFI_CHECK;
/* Internal functions to prepare boot */
uint64_t G_VBIOS;
uint64_t FUN_TRANSMITTER_CONTROL;
uint64_t FUN_MP3_INITIALIZE;
uint64_t FUN_MP3_INVOKE;
/* Wifi FW */
uint64_t PS5_WIFI_FW_OFFSET;
uint64_t PS5_WIFI_FW_SIZE;
} offset_list;
extern offset_list off_0300;
extern offset_list off_0310;
extern offset_list off_0320;
extern offset_list off_0321;
extern offset_list off_0400;
extern offset_list off_0402;
extern offset_list off_0403;
extern offset_list off_0450;
extern offset_list off_0451;
extern offset_list off_0500;
extern offset_list off_0502;
extern offset_list off_0510;
extern offset_list off_0550;
extern offset_list off_0600;
extern offset_list off_0602;
extern offset_list off_0650;
extern offset_list off_0720;
extern offset_list off_0740;
extern offset_list off_0761;
#endif
#ifndef OFFSETS_H
#define OFFSETS_H
#include <stdint.h>
typedef struct _offset_list {
uint64_t PMAP_STORE;
uint64_t HV_VCPU; // Needed for 1.xx and 2.xx
uint64_t HV_VCPU_CPUID; // Needed for 1.xx and 2.xx
uint64_t HV_VCPU_ARRAY_OFF; // Needed for 1.xx and 2.xx
uint64_t HV_VCPU_STRIDE; // Needed for 1.xx and 2.xx
uint64_t HV_VCPU_VMCB_PTR; // Needed for 1.xx and 2.xx
uint64_t KERNEL_CODE_CAVE;
uint64_t KERNEL_DATA_CAVE;
uint64_t IOMMU_SOFTC;
uint64_t VMSPACE_VM_VMID;
uint64_t VMSPACE_VM_PMAP;
uint64_t PMAP_PM_PML4;
uint64_t PMAP_PM_CR3;
uint64_t DATA_BASE_GVMSPACE;
uint64_t HOOK_ACPI_WAKEUP_MACHDEP;
uint64_t FUN_PRINTF;
uint64_t FUN_VA_TO_PA;
uint64_t FUN_HV_IOMMU_SET_BUFFERS;
uint64_t FUN_HV_IOMM_WAIT_COMPLETION;
uint64_t FUN_SMP_RENDEZVOUS;
uint64_t FUN_SMP_NO_RENDEVOUS_BARRIER;
uint64_t HV_HANDLE_VMEXIT_PA;
uint64_t HV_CODE_CAVE_PA;
uint64_t HV_UART_OVERRIDE_PA;
uint64_t G_VBIOS;
uint64_t FUN_TRANSMITTER_CONTROL;
uint64_t FUN_MP3_INITIALIZE;
uint64_t FUN_MP3_INVOKE;
uint64_t KERNEL_UART_OVERRIDE;
uint64_t KERNEL_DEBUG_PATCH;
uint64_t KERNEL_CFI_CHECK;
uint64_t PS5_WIFI_FW_OFFSET;
uint64_t PS5_WIFI_FW_SIZE;
} offset_list;
extern offset_list off_0300;
extern offset_list off_0310;
extern offset_list off_0320;
extern offset_list off_0321;
extern offset_list off_0400;
extern offset_list off_0402;
extern offset_list off_0403;
extern offset_list off_0450;
extern offset_list off_0451;
#endif
+12 -12
View File
@@ -1,12 +1,12 @@
#ifndef PREPARE_RESUME_H
#define PREPARE_RESUME_H
#include "utils.h"
extern struct linux_info linux_i;
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);
#endif
#ifndef PREPARE_RESUME_H
#define PREPARE_RESUME_H
#include "utils.h"
extern struct linux_info linux_i;
int prepare_resume(void);
int update_sck_data_ptr (void* sc, uint64_t dest_text, uint64_t dest_data);
void hook_call_near(uint64_t hook, uint64_t dst);
void prepare_sck_args(uint64_t dest_data);
#endif
+19 -19
View File
@@ -1,19 +1,19 @@
#ifndef TMR_H
#define TMR_H
#include <stdint.h>
#define ECAM_B0D18F2 dmap + (0xF0000000ULL + 0x18ULL * 0x8000 + 2 * 0x1000)
#define TMR_INDEX_OFF 0x80
#define TMR_DATA_OFF 0x84
#define TMR_BASE(n) ((n) * 0x10 + 0x00)
#define TMR_LIMIT(n) ((n) * 0x10 + 0x04)
#define TMR_CONFIG(n) ((n) * 0x10 + 0x08)
#define TMR_REQUESTORS(n) ((n) * 0x10 + 0x0C)
#define TMR_CFG_PERMISSIVE 0x3F07
uint32_t tmr_read(uint32_t addr);
void tmr_write(uint32_t addr, uint32_t val);
#endif
#ifndef TMR_H
#define TMR_H
#include <stdint.h>
#define ECAM_B0D18F2 dmap + (0xF0000000ULL + 0x18ULL * 0x8000 + 2 * 0x1000)
#define TMR_INDEX_OFF 0x80
#define TMR_DATA_OFF 0x84
#define TMR_BASE(n) ((n) * 0x10 + 0x00)
#define TMR_LIMIT(n) ((n) * 0x10 + 0x04)
#define TMR_CONFIG(n) ((n) * 0x10 + 0x08)
#define TMR_REQUESTORS(n) ((n) * 0x10 + 0x0C)
#define TMR_CFG_PERMISSIVE 0x3F07
uint32_t tmr_read(uint32_t addr);
void tmr_write(uint32_t addr, uint32_t val);
#endif
+185 -175
View File
@@ -1,175 +1,185 @@
#ifndef UTILS_H
#define UTILS_H
#include "linux.h"
#include "offsets.h"
#include <ps5/kernel.h>
#include <stdarg.h>
#include <string.h>
int sceKernelGetCurrentCpu();
int sceKernelSendNotificationRequest(int, void *, size_t, int);
int sceKernelOpenEventFlag(void *, const char *);
int sceKernelNotifySystemSuspendStart(void);
int sceKernelSetEventFlag(void *, int);
int sceKernelCloseEventFlag(void *);
typedef struct _sysent {
uint32_t n_arg;
uint32_t pad;
uint64_t sy_call;
uint64_t sy_auevent;
uint64_t sy_systrace_args;
uint32_t sy_entry;
uint32_t sy_return;
uint32_t sy_flags;
uint32_t sy_thrcnt;
} sysent;
typedef struct __flat_pmap {
uint64_t mtx_name_ptr;
uint64_t mtx_flags;
uint64_t mtx_data;
uint64_t mtx_lock;
uint64_t pm_pml4;
uint64_t pm_cr3;
} flat_pmap;
/** These vars are global for the payload to simplify things */
extern offset_list env_offset; // Defined on utils.c
extern uint64_t ktext; // Defined on utils.c
extern uint64_t kdata; // Defined on utils.c
extern uint64_t dmap; // Defined on utils.c
extern uint64_t cr3; // Defined on utils.c
extern uint32_t fw; // Defined on utils.c
extern uint64_t vmcb_pa[16]; // Defined on hv_defeat.c
extern struct linux_info linux_i; // Declared on main.c
int setup_env(void);
static inline void kwrite_large(uint64_t ka, void *src, uint64_t len) {
uint32_t CHUNK = 0x1000;
uint64_t written = 0;
while (written < len) {
uint32_t n = (len - written > CHUNK) ? CHUNK : (uint32_t)(len - written);
kernel_copyin(src + written, ka + written, n);
written += n;
}
}
static inline void kwrite(uint64_t ka, void *src, uint64_t len) {
kernel_copyin(src, ka, len);
}
static inline void kwrite64(uint64_t dst, uint64_t val) {
kernel_copyin(&val, dst, 8);
}
static inline void kwrite32(uint64_t dst, uint32_t val) {
kernel_copyin(&val, dst, 4);
}
static inline void kwrite8(uint64_t dst, uint8_t val) {
kernel_copyin(&val, dst, 1);
}
static inline void kread(uint64_t ka, void *dst, uint64_t len) {
kernel_copyout(ka, dst, len);
}
static inline uint64_t kread64(uint64_t src) {
uint64_t val;
kernel_copyout(src, &val, 8);
return val;
}
static inline uint32_t kread32(uint64_t src) {
uint32_t val;
kernel_copyout(src, &val, 4);
return val;
}
static inline uint8_t kread8(uint64_t src) {
uint8_t val;
kernel_copyout(src, &val, 1);
return val;
}
int set_offsets(void);
int init_global_vars(void);
uint64_t get_offset_va(uint64_t offset);
// Defines for Page management
#define ALIGN_UP(size, align) (((size) + (align) - 1) & ~((align) - 1))
#define INKERNEL(va) (va & 0xFFFF000000000000)
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))
#define pmap_pml4e_index(va) ((va >> 39) & 0x1FF)
#define pmap_pdpe_index(va) ((va >> 30) & 0x1FF)
#define pmap_pde_index(va) ((va >> 21) & 0x1FF)
#define pmap_pte_index(va) ((va >> 12) & 0x1FF)
uint64_t vtophys_user(uint64_t va);
uint64_t vtophys(uint64_t va);
uint64_t vtophys_custom(uint64_t va, uint64_t cr3_custom);
uint64_t pa_to_dmap(uint64_t pa);
void page_chain_set_rw(uint64_t va);
uint64_t page_remove_global(uint64_t va);
uint64_t getpmap(uint64_t proc_ptr);
uint64_t get_pml4(uint64_t pmap);
int pin_to_core(int n);
int pin_to_first_available_core(void);
void unpin(void);
void notify(const char *fmt, ...);
void notify_internal(uint8_t *msg);
void enter_rest_mode(void);
#if DEBUG
#define DEBUG_PRINT(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#define DEBUG_PRINT(fmt, ...)
#endif
bool if_exists(const char *path);
bool sceKernelIsTestKit(void);
bool sceKernelIsDevKit(void);
enum kit_type { KIT_RETAIL, KIT_TESTKIT, KIT_DEVKIT };
enum kit_type get_kit_type(void);
#define MINI_SYSCORE_PID 1
uint64_t alloc_page(void);
void pte_store(uintptr_t ptep, uint64_t pte);
void install_page(uintptr_t pml4, vm_offset_t va, vm_paddr_t pa, int bits);
void install_page_syscore(vm_offset_t va, vm_paddr_t pa, int bits);
#endif
#ifndef UTILS_H
#define UTILS_H
#include "offsets.h"
#include <ps5/kernel.h>
#include <stdarg.h>
#include <stdint.h>
#include <string.h>
int sceKernelGetCurrentCpu();
int sceKernelSendNotificationRequest(int, void *, size_t, int);
int sceKernelOpenEventFlag(void*, const char *);
int sceKernelNotifySystemSuspendStart(void);
int sceKernelSetEventFlag(void *, int);
int sceKernelCloseEventFlag(void*);
typedef struct _sysent {
uint32_t n_arg;
uint32_t pad;
uint64_t sy_call;
uint64_t sy_auevent;
uint64_t sy_systrace_args;
uint32_t sy_entry;
uint32_t sy_return;
uint32_t sy_flags;
uint32_t sy_thrcnt;
} sysent;
typedef struct __flat_pmap {
uint64_t mtx_name_ptr;
uint64_t mtx_flags;
uint64_t mtx_data;
uint64_t mtx_lock;
uint64_t pm_pml4;
uint64_t pm_cr3;
} flat_pmap;
struct linux_info {
uintptr_t bzimage;
size_t bzimage_size;
uintptr_t initrd;
size_t initrd_size;
size_t vram_size;
char cmdline[2048];
int kit_type;
uintptr_t linux_info; // PA of linux_info
};
/** These vars are global for the payload to simplify things */
extern offset_list env_offset; // Defined on utils.c
extern uint64_t ktext; // Defined on utils.c
extern uint64_t kdata; // Defined on utils.c
extern uint64_t dmap; // Defined on utils.c
extern uint64_t cr3; // Defined on utils.c
extern uint32_t fw; // Defined on utils.c
extern uint64_t vmcb_pa[16]; // Defined on hv_defeat.c
extern struct linux_info linux_i; // Declared on main.c
int setup_env(void);
static inline void kwrite_large(uint64_t ka, void* src, uint64_t len) {
uint32_t CHUNK = 0x1000;
uint64_t written = 0;
while (written < len) {
uint32_t n = (len - written > CHUNK) ? CHUNK : (uint32_t)(len - written);
kernel_copyin(src + written, ka + written, n);
written += n;
}
}
static inline void kwrite(uint64_t ka, void *src, uint64_t len) {
kernel_copyin(src, ka, len);
}
static inline void kwrite64(uint64_t dst, uint64_t val) {
kernel_copyin(&val, dst, 8);
}
static inline void kwrite32(uint64_t dst, uint32_t val) {
kernel_copyin(&val, dst, 4);
}
static inline void kwrite8(uint64_t dst, uint8_t val) {
kernel_copyin(&val, dst, 1);
}
static inline void kread(uint64_t ka, void *dst, uint64_t len) {
kernel_copyout(ka, dst, len);
}
static inline uint64_t kread64(uint64_t src) {
uint64_t val;
kernel_copyout(src, &val, 8);
return val;
}
static inline uint32_t kread32(uint64_t src) {
uint32_t val;
kernel_copyout(src, &val, 4);
return val;
}
static inline uint8_t kread8(uint64_t src) {
uint8_t val;
kernel_copyout(src, &val, 1);
return val;
}
int set_offsets(void);
int init_global_vars(void);
uint64_t get_offset_va(uint64_t offset);
// Defines for Page management
#define ALIGN_UP(size, align) (((size) + (align) - 1) & ~((align) - 1))
#define INKERNEL(va) (va & 0xFFFF000000000000)
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))
#define pmap_pml4e_index(va) ((va >> 39) & 0x1FF)
#define pmap_pdpe_index(va) ((va >> 30) & 0x1FF)
#define pmap_pde_index(va) ((va >> 21) & 0x1FF)
#define pmap_pte_index(va) ((va >> 12) & 0x1FF)
uint64_t va_to_pa_user(uint64_t va);
uint64_t va_to_pa_kernel(uint64_t va);
uint64_t va_to_pa_custom(uint64_t va, uint64_t cr3_custom);
uint64_t pa_to_dmap(uint64_t pa);
void page_chain_set_rw(uint64_t va);
uint64_t page_remove_global(uint64_t va);
uint64_t getpmap(uint64_t proc_ptr);
uint64_t get_pml4(uint64_t pmap);
int pin_to_core(int n);
int pin_to_first_available_core(void);
void unpin(void);
void notify(const char *fmt, ...);
void notify_internal(uint8_t *msg);
void enter_rest_mode(void);
#if DEBUG
#define DEBUG_PRINT(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#define DEBUG_PRINT(fmt, ...)
#endif
bool if_exists(const char* path);
bool sceKernelIsTestKit(void);
bool sceKernelIsDevKit(void);
enum kit_type {
KIT_RETAIL,
KIT_TESTKIT,
KIT_DEVKIT
};
enum kit_type get_kit_type(void);
#endif
-34
View File
@@ -1,34 +0,0 @@
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)
-71
View File
@@ -1,71 +0,0 @@
#include "utils.h"
// 7.xx offsets
#define HV_REENTER_HYPERCORE_07xx 0x0000000062806380ULL
#define HV_STACK_TABLE_07xx 0x000000006282E120ULL
#define HV_PML4_07xx 0x000000006282E1A0ULL
#define HV_ENTRY_07xx 0x000000006282E1B8ULL
#define HV_MAIN_07xx 0x0000000000000E20
#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_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) {
volatile int fw_version = 0x11AA11AA; // To be updated by loader
uint64_t 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++) {
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 *)(fw_version == 0x0650 ? HV_STACK_TABLE_0650
: HV_STACK_TABLE_07xx))[0] +
0x1000);
// Reenter hypercore.
void (*hv_reenter_hypercore)(void) =
(void *)(fw_version == 0x0650 ? HV_REENTER_HYPERCORE_0650
: HV_REENTER_HYPERCORE_07xx);
hv_reenter_hypercore();
while (1)
;
}
-35
View File
@@ -1,35 +0,0 @@
#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
View File
@@ -1,37 +0,0 @@
#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

Some files were not shown because too many files have changed in this diff Show More