mirror of
https://github.com/Pharaoh2k/ps5debug-NG.git
synced 2026-10-21 19:33:05 -05:00
PS5 debugger payload, inspired by Ctn's ps5debug 1.0b5 and wire-compatible with it. Runs the wire-protocol server inside SceShellCore via an umtx-loaded installer that injects the embedded debugger ELF. Features: process scan/RPC/ELF-inject, on-console scan, full debugger (breakpoints, watchpoints, single-step, regs/FP/DR access), kernel R/W, server-side Zydis disassembly, on-console Keystone assembler (0xBDAA0024), foreground-app metadata (0xBDDD0006), server-side RBP stack walk (CMD_PROC_READ_STACK), klog forwarder (TCP 3232), rest-mode survival and a lot more. Supports FW families 3.x / 4.0 / 4.x (incl. 4.51) / 5.x / 6.x / 7.x / 7.5x / 8.x via the kpatch routine in installer/source/main.c. GPL-3.0-only.
116 lines
3.9 KiB
C
116 lines
3.9 KiB
C
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
#include "sdk_shim.h"
|
|
#include "protocol.h"
|
|
#include "proc.h"
|
|
#include "kdbg.h"
|
|
|
|
extern int kernel_mprotect(pid_t pid, intptr_t addr, uint64_t len, int prot);
|
|
extern int proc_remote_alloc(uint32_t pid, uint64_t *out_addr, uint64_t length, uint64_t flags);
|
|
extern int proc_remote_free (uint32_t pid, uint64_t addr, uint64_t length);
|
|
extern int proc_remote_call (int pid, struct sys_proc_call_args *args);
|
|
extern long sys_proc_elf (unsigned long pid, unsigned long elf, unsigned long length);
|
|
extern long sys_proc_elf_rpc (unsigned long pid, unsigned long elf, unsigned long length, uint64_t *out_entry);
|
|
extern int sys_proc_vm_map (uint32_t pid, void **out_maps, int *out_count);
|
|
|
|
int sys_proc_cmd(uint64_t pid, uint64_t cmd, void *data) {
|
|
if (!data) return 1;
|
|
|
|
switch (cmd) {
|
|
|
|
case SYS_PROC_VM_MAP: {
|
|
struct sys_proc_vm_map_args *args = (struct sys_proc_vm_map_args *)data;
|
|
void *maps = NULL;
|
|
int count = 0;
|
|
|
|
int rc = sys_proc_vm_map((uint32_t)pid, &maps, &count);
|
|
if (rc != 0) {
|
|
sceKernelUsleep(10000);
|
|
for (int retries = 21; retries > 0; retries--) {
|
|
if (sys_proc_vm_map((uint32_t)pid, &maps, &count) == 0) { rc = 0; break; }
|
|
sceKernelUsleep(10000);
|
|
}
|
|
if (rc != 0) return 1;
|
|
}
|
|
|
|
if (!args->maps) {
|
|
|
|
args->num = (uint64_t)(count + 1);
|
|
if (maps) free(maps);
|
|
} else {
|
|
|
|
uint64_t to_copy = args->num < (uint64_t)count ? args->num : (uint64_t)count;
|
|
if (maps && to_copy > 0) {
|
|
memcpy(args->maps, maps,
|
|
(size_t)to_copy * sizeof(struct proc_vm_map_entry));
|
|
}
|
|
args->num = to_copy;
|
|
if (maps) free(maps);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
case SYS_PROC_ALLOC: {
|
|
struct sys_proc_alloc_args *args = (struct sys_proc_alloc_args *)data;
|
|
uint64_t out_addr = 0;
|
|
|
|
if (proc_remote_alloc((uint32_t)pid, &out_addr, args->length, 0x4000) != 0) return 1;
|
|
args->address = out_addr;
|
|
return 0;
|
|
}
|
|
|
|
case SYS_PROC_ALLOC_HINTED: {
|
|
struct sys_proc_alloc_args *args = (struct sys_proc_alloc_args *)data;
|
|
|
|
uint64_t out_addr = args->address;
|
|
if (proc_remote_alloc((uint32_t)pid, &out_addr, args->length, args->address) != 0) {
|
|
|
|
args->address = out_addr;
|
|
return 1;
|
|
}
|
|
args->address = out_addr;
|
|
return 0;
|
|
}
|
|
|
|
case SYS_PROC_FREE: {
|
|
struct sys_proc_free_args *args = (struct sys_proc_free_args *)data;
|
|
return proc_remote_free((uint32_t)pid, args->address, args->length);
|
|
}
|
|
|
|
case SYS_PROC_PROTECT: {
|
|
struct sys_proc_protect_args *args = (struct sys_proc_protect_args *)data;
|
|
return kernel_mprotect((pid_t)pid, (intptr_t)args->address,
|
|
args->length, (int)args->prot);
|
|
}
|
|
|
|
case SYS_PROC_CALL:
|
|
return proc_remote_call((int)pid, (struct sys_proc_call_args *)data);
|
|
|
|
case SYS_PROC_ELF: {
|
|
struct sys_proc_elf_args *args = (struct sys_proc_elf_args *)data;
|
|
|
|
long elf_rc = sys_proc_elf((unsigned long)pid,
|
|
(unsigned long)(uintptr_t)args->elf,
|
|
(unsigned long)args->length);
|
|
return elf_rc != 0 ? 1 : 0;
|
|
}
|
|
|
|
case SYS_PROC_ELF_RPC: {
|
|
struct sys_proc_elf_rpc_args *args = (struct sys_proc_elf_rpc_args *)data;
|
|
uint64_t entry = 0;
|
|
long elf_rc = sys_proc_elf_rpc((unsigned long)pid,
|
|
(unsigned long)(uintptr_t)args->elf,
|
|
(unsigned long)args->length,
|
|
&entry);
|
|
args->entry = entry;
|
|
return elf_rc != 0 ? 1 : 0;
|
|
}
|
|
|
|
case SYS_PROC_INSTALL:
|
|
case SYS_PROC_INFO:
|
|
case SYS_PROC_THRINFO:
|
|
default:
|
|
return 1;
|
|
}
|
|
}
|