Files
ps5debug-NG/debugger/source/auth.c
T
OpenSourcereR-dev 9c649a44dc Initial public release: ps5debug-NG v1.2.2
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.
2026-05-14 13:44:35 +07:00

99 lines
2.5 KiB
C

// SPDX-License-Identifier: GPL-3.0-only
#include "protocol.h"
#include "sdk_shim.h"
#include "net.h"
#include "proc.h"
static uint32_t s_lfsr_s1;
static uint32_t s_lfsr_s2;
static uint32_t s_lfsr_s3;
static uint32_t s_lfsr_s4;
uint32_t g_proc_auth_state = 0x14000u;
uint32_t auth_lfsr_next(void) {
uint32_t s1 = s_lfsr_s1;
uint32_t s2 = s_lfsr_s2;
uint32_t s3 = s_lfsr_s3;
uint32_t s4 = s_lfsr_s4;
s1 = ((s1 << 18) & 0xFFF80000u) ^ ((s1 ^ (s1 << 6)) >> 13);
s2 = ((s2 << 2) & 0xFFFFFFE0u) ^ ((s2 ^ (s2 << 2)) >> 27);
s3 = ((s3 << 7) & 0xFFFFF800u) ^ ((s3 ^ (s3 << 13)) >> 21);
s4 = ((s4 << 13) & 0xFFF00000u) ^ ((s4 ^ (s4 << 3)) >> 12);
s_lfsr_s1 = s1;
s_lfsr_s2 = s2;
s_lfsr_s3 = s3;
s_lfsr_s4 = s4;
return s1 ^ s2 ^ s3 ^ s4;
}
void auth_lfsr_set_state(uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
s_lfsr_s1 = a;
s_lfsr_s2 = b;
s_lfsr_s3 = c;
s_lfsr_s4 = d;
}
void auth_keystream_fill(uint8_t *out, uint64_t length) {
(void)length;
auth_lfsr_set_state(200, 300, 400, 500);
for (int i = 0; i < 256; i++) {
out[i] = (uint8_t)auth_lfsr_next();
}
}
void proc_auth_xor_keystream(const uint8_t *in, uint8_t *out, uint16_t length) {
uint8_t keystream[256];
auth_keystream_fill(keystream, 0x100);
for (uint16_t i = 0; i < length; i++) {
out[i] = in[i] ^ keystream[(uint8_t)i];
}
}
static inline uint32_t bitswap32(uint32_t x) {
return ((x >> 1) & 0x55555555u) | ((x << 1) & 0xAAAAAAAAu);
}
int proc_auth_handle(int fd, struct cmd_packet *packet) {
struct cmd_proc_auth_packet *ap = (struct cmd_proc_auth_packet *)packet->data;
if (!ap || bitswap32(ap->magic) != CMD_PROC_AUTH_MAGIC_BSWAP) {
net_send_int32(fd, CMD_DATA_NULL);
return 1;
}
net_send_int32(fd, CMD_SUCCESS);
uint16_t chlen = 64;
uint8_t challenge[64];
uint8_t expected[64];
uint8_t response[64];
for (uint16_t i = 0; i < chlen; i++) {
uint32_t r = auth_lfsr_next();
challenge[i] = (uint8_t)(r + r / 255u);
}
proc_auth_xor_keystream(challenge, expected, chlen);
net_send_all(fd, &chlen, sizeof(chlen));
net_send_all(fd, challenge, chlen);
net_recv_all(fd, response, chlen, 1);
for (uint16_t i = 0; i < chlen; i++) {
if (response[i] != expected[i]) {
net_send_int32(fd, CMD_DATA_NULL);
return 1;
}
}
if (ap->flags & 1) g_proc_auth_state = 0x14001u;
if (ap->flags & 2) g_proc_auth_state = 0x14002u;
net_send_int32(fd, CMD_SUCCESS);
return 0;
}