Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Build

on:
push:
pull_request:
workflow_dispatch:

jobs:
build:
runs-on: ubuntu-24.04

env:
LLVM_PREFIX: /usr/lib/llvm-18/bin

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Install build tools
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
clang-18 \
lld-18 \
llvm-18 \
make

- name: Show tool versions
run: |
"$LLVM_PREFIX/clang" --version
"$LLVM_PREFIX/ld.lld" --version
"$LLVM_PREFIX/llvm-objcopy" --version

- name: Build SDK
run: make -B

- name: Install SDK layout
run: sudo -E bash ./install.sh

- name: Build installed hello world example
run: make -C sample/hello_world -B
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
*.elf
*.o
build/*
devdocs/
.vscode/
*.map
*.bin
*.bin
7 changes: 6 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ CFLAGS := --target=x86_64-unknown-none-elf \
-Wall -Wextra \
-march=btver2 -mtune=btver2 \
-m64 -mcmodel=small \
-fPIC
-mno-red-zone \
-mno-mmx -mno-sse -mno-sse2 -mno-avx \
-mno-80387 -msoft-float \
-fPIC \
-fno-vectorize -fno-slp-vectorize \
$(EXTRA_CFLAGS)

CFILES := $(wildcard $(SDIR)/*.c)
SFILES := $(wildcard $(SDIR)/*.s)
Expand Down
22 changes: 18 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,20 +108,34 @@ int module_start(void* kproc_args)

## Using

Check the `sample` folder. To create a new project, you can copy the sample from the SDK installation directory to a new location.
Check the `sample` folder. To create a new project, you can use the `new_kld_project` helper installed by the SDK.

```
$ new_kld_project myproj
$ cd myproj
$ make
```

It copies the `hello_world` sample, removes old build files from the template, and creates a simple `src/main.c` using the project name. If the SDK is not installed in `/opt/ps5-kld-sdk`, set `PS5_KLD_SDK` before running it.

```
$ PS5_KLD_SDK=/path/to/ps5-kld-sdk new_kld_project myproj
```

You can still copy a sample manually if you want to start from a specific one:

```
$ mkdir myproj
$ cp /opt/ps5-kld-sdk/sample/hello_world/* myproj/
$ cp -R /opt/ps5-kld-sdk/sample/hello_world/* myproj/
```

The payloads are built with the `.bin` extension. You can send them to any kernel module loader, such as `kldload`, or embed them in your own loader.

Since the SDK includes freebsd-headers, you can use FreeBSD definitions in your project when needed, such as `<sys/cpuset.h>`. Depending on your IDE, you may want to add the following path for code completion:

- /opt/ps5-kld-sdk/include
- /oot/ps5-kld-sdk/include/freebsd-headers
- /opt/ps5-kld-sdk/include/freebsd-headers

## Porting

To add new offsets and function definitions, check the `include/ps5kld/offsets` directory and update the entries in `src/kernel.c`, specifically within the init_kernel function.
To add new offsets and function definitions, check the `include/ps5kld/offsets` directory and update the entries in `src/kernel.c`, specifically within the init_kernel function.
51 changes: 51 additions & 0 deletions include/ps5kld/debug.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#pragma once

#include <stdint.h>

#include <ps5kld/trap.h>

#define HW_BREAKPOINT_SLOTS 4
#define IDT_DB_VECTOR 1
#define EFLAGS_RF (1ULL << 16)

typedef enum hwbp_type
{
HWBP_EXECUTE = 0,
HWBP_WRITE = 1,
HWBP_IO = 2,
HWBP_READWRITE = 3,
} hwbp_type_t;

typedef enum hwbp_len
{
HWBP_LEN_1 = 1,
HWBP_LEN_2 = 2,
HWBP_LEN_4 = 4,
HWBP_LEN_8 = 8,
} hwbp_len_t;

typedef int (*hwbp_callback_t)(int slot, trap_frame_t *frame, void *arg);

typedef struct hwbp
{
uint64_t address;
hwbp_type_t type;
hwbp_len_t length;
hwbp_callback_t callback;
void *arg;
uint8_t enabled;
} hwbp_t;

int debug_init(void);
int hwbp_find_free(void);
int hwbp_set_local(int slot, uint64_t address, hwbp_type_t type,
hwbp_len_t length, hwbp_callback_t callback, void *arg);
int hwbp_set_all(int slot, uint64_t address, hwbp_type_t type,
hwbp_len_t length, hwbp_callback_t callback, void *arg);
int hwbp_clear_local(int slot);
int hwbp_clear_all_cpus(int slot);
void hwbp_apply_local(void);
void hwbp_disable_slot_local(int slot);
int hwbp_enable_slot_local(int slot);

void debug_handle_db(trap_frame_t *frame);
8 changes: 8 additions & 0 deletions include/ps5kld/device.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#pragma once

#include <ps5kld/kernel.h>

int device_available(void);
struct cdev *device_create(struct cdevsw *devsw, int unit, uid_t uid,
gid_t gid, int perms, const char *name);
void device_destroy(struct cdev *dev);
24 changes: 0 additions & 24 deletions include/ps5kld/dmap.h
Original file line number Diff line number Diff line change
@@ -1,30 +1,6 @@
#pragma once

#include <ps5kld/kernel.h>

#define PD_CLEAN_ADDR_MASK 0xffffffffff800
#define PDE_FIELD(pde, field) (*pde & field)

#define PAGE_PRESENT (1 << 0)

#define PHYSTODMAP(phys_addr) (get_dmap() + phys_addr)

typedef struct __vaddr_page
{
union
{
uint64_t vaddr;
struct
{
uint64_t offset: 12;
uint64_t pt_index: 9;
uint64_t pd_index: 9;
uint64_t pdpt_index: 9;
uint64_t pml4_index: 9;
uint64_t sign_ext: 16;
} levels;
};
} vaddr_page;

uint64_t get_dmap();
uint64_t virt2phys(uint64_t cr3, uint64_t vaddr);
40 changes: 40 additions & 0 deletions include/ps5kld/hook.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#pragma once

#include <stdint.h>

#include <ps5kld/debug.h>

typedef enum hook_kind
{
HOOK_NONE = 0,
HOOK_HWBP = 1,
} hook_kind_t;

typedef enum hook_type
{
ALWAYS_ENABLED = 0,
ONESHOT = 1,
} hook_type_t;

typedef struct hook
{
void *target;
void *replacement;
void *gateway;
hook_kind_t kind;
hook_type_t type;
int hwbp_slot;
uint8_t installed;
} hook_t;

int hook_install(hook_t *hook, void *target, void *replacement);
int hook_install_hwbp(hook_t *hook, void *target, void *replacement);
int hook_disable_current_cpu(hook_t *hook);
int hook_enable_current_cpu(hook_t *hook);
int hook_remove(hook_t *hook);

void hook_manager_init(void);
hook_t *hook_manager_add(void *target, void *replacement, hook_type_t type);
int hook_manager_remove(void *target);
hook_t *hook_manager_find(void *target);
int hook_manager_list(hook_t *hooks, size_t *len);
4 changes: 2 additions & 2 deletions include/ps5kld/intrin.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ DEFINE_DR_RW(7)
static inline __attribute__((always_inline)) uint64_t __readmsr(unsigned long __register) {
unsigned long __edx;
unsigned long __eax;
__asm__ volatile("wrmsr"
__asm__ volatile("rdmsr"
: "=d"(__edx), "=a"(__eax)
: "c"(__register));
return (((uint64_t)__edx) << 32) | (uint64_t)__eax;
Expand Down Expand Up @@ -126,4 +126,4 @@ static inline __attribute__((always_inline)) void __sidt(uint64_t* idtr) {
// static inline __attribute__((always_inline)) void intr_restore(uint64_t rflags)
// {
// write_rflags(rflags);
// }
// }
39 changes: 39 additions & 0 deletions include/ps5kld/ipi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#pragma once

#include <stdint.h>

#include <ps5kld/trap.h>

#define MAX_CPUS 16
#ifndef IPI_VECTOR
#define IPI_VECTOR 0xfe
#endif
#define APIC_ICR_LOW_INDEX (0x300 / sizeof(uint32_t))
#define APIC_ICR_HIGH_INDEX (0x310 / sizeof(uint32_t))
#define APIC_EOI_INDEX (0xb0 / sizeof(uint32_t))
#define APIC_ID_INDEX (0x20 / sizeof(uint32_t))
#define APIC_ID_SHIFT 24
#define APIC_DELIVERY_PENDING 0x1000
#define IPI_ICR (0x4000 | IPI_VECTOR)
#define MSR_APIC_BASE 0x1b
#define MSR_X2APIC_ID 0x802
#define MSR_X2APIC_EOI 0x80b
#define MSR_X2APIC_ICR 0x830
#ifndef APICBASE_X2APIC
#define APICBASE_X2APIC (1ULL << 10)
#endif
#ifndef APICBASE_ADDRESS
#define APICBASE_ADDRESS 0xfffff000ULL
#endif

typedef void (*ipi_callback_t)(int cpu, void *arg, trap_frame_t *frame);

int cpu_id(void);
int cpu_apic_id(int cpu);
int ipi_init(void);
int ipi_send_cpu(int cpu);
int ipi_run_on_cpu(int cpu, ipi_callback_t callback, void *arg);
int ipi_run_on_all(ipi_callback_t callback, void *arg);
int ipi_run_on_others(ipi_callback_t callback, void *arg);

void ipi_handle_interrupt(trap_frame_t *frame);
28 changes: 22 additions & 6 deletions include/ps5kld/kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,22 @@
#include <sys/param.h>
#include <sys/conf.h>
#include <sys/cpuset.h>
#include <sys/sysent.h>
#include <machine/specialreg.h>
#include <stdint.h>

#define M_ZERO 0
#define M_NODUMP 1
#define M_NOWAIT 2
#define M_WAITOK 3
#define M_USE_RESERVE 4
#include <ps5kld/machine/idt.h>

#define M_NOWAIT 0x0001
#define M_WAITOK 0x0002
#define M_ZERO 0x0100
#define M_NOVM 0x0200
#define M_USE_RESERVE 0x0400
#define M_NODUMP 0x0800

#ifndef PS5KLD_LOG
#define PS5KLD_LOG(...) kprintf(__VA_ARGS__)
#endif

struct flat_pmap {
uint64_t mtx_name_ptr;
Expand All @@ -30,13 +38,21 @@ typedef struct __kproc_args

uint64_t get_kernel_base();
int init_kernel(uint32_t fwver);
void copy_gate(idt_64 *dst, const idt_64 *src);


// Kernel functions
extern void(*kprintf)(char* fmt, ...);
extern uint64_t(*kmalloc)(size_t size, uint64_t *type, int flags);
extern struct cdev* (*kmake_dev)(struct cdevsw *cdevsw, int unit, uid_t uid,
gid_t gid, int perms, const char *fmt, ...);
extern void(*kdestroy_dev)(struct cdev *dev);

// Kernel variables
extern struct flat_pmap* kernel_pmap;
extern uint64_t* apic_ops;
extern uint64_t* KM_TEMP; // malloc_type
extern uint64_t* KM_TEMP; // malloc_type
extern int* cpu_apic_ids;
extern struct sysentvec* sysentvec;
extern struct sysent* sysent_table;
extern uint32_t kernel_fwver;
5 changes: 4 additions & 1 deletion include/ps5kld/machine/idt.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,7 @@ struct _idt_64

typedef struct _idt_64 idt_64;

#define UNPACK_HANDLER_ADDR(idt) ( ((uint64_t) idt->offset_high << 32) | (idt->offset_middle << 16) | idt->offset_low)
#define UNPACK_HANDLER_ADDR(idt) \
(((uint64_t)(idt)->offset_high << 32) | \
((uint64_t)(idt)->offset_middle << 16) | \
(uint64_t)(idt)->offset_low)
9 changes: 0 additions & 9 deletions include/ps5kld/offsets.h

This file was deleted.

6 changes: 4 additions & 2 deletions include/ps5kld/offsets/403.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
#define Xfast_syscall_403 0x294218
#define kprintf_offset_403 0x28da78
#define apic_ops_offset_403 OFFSET(0xFFFFFFFF81B44AC8)
#define cpu_apic_ids_offset_403 OFFSET(0xFFFFFFFF83BCC870)
#define kernel_pmap_offset_403 OFFSET(0xFFFFFFFF84067A78)
#define malloc_offset_403 OFFSET(0xFFFFFFFF80D66500)
#define malloc_MTEMP_offset_403 OFFSET(0xFFFFFFFF82156080)


#define make_dev_offset_403 OFFSET(0xFFFFFFFF80890C70)
#define destroy_dev_offset_403 OFFSET(0xFFFFFFFF808913F0 )
#define sysentvec_offset_403 OFFSET(0xFFFFFFFF81B21D30)
4 changes: 3 additions & 1 deletion include/ps5kld/offsets/500.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@
#define kernel_pmap_offset_500 OFFSET(0xFFFFFFFF841E8A88)
#define malloc_offset_500 OFFSET(0xFFFFFFFF80D9B210)
#define malloc_MTEMP_offset_500 OFFSET(0xFFFFFFFF822855A0)

#define make_dev_offset_500 OFFSET(0xFFFFFFFF808B9FC0)
#define destroy_dev_offset_500 OFFSET(0xFFFFFFFF808BA740)
#define sysentvec_offset_500 OFFSET(0xFFFFFFFF81C50D60)
Loading
Loading