From 8983095d0c336a560de64d45cdbe42b85e9bc9ae Mon Sep 17 00:00:00 2001 From: Roman Tarasov Date: Sun, 31 May 2026 14:22:36 +0300 Subject: [PATCH 1/9] build: rebuild kstuff when build config changes --- .gitignore | 19 +++++++------------ ps5-kstuff/Makefile | 19 ++++++++++++++++--- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index 7b8795b..02ed929 100644 --- a/.gitignore +++ b/.gitignore @@ -3,20 +3,9 @@ refs/* # Local backup files. *_old -# Build artifacts from lib/. -/lib/*.o -/lib/lib.a -/lib/lib-ps5.a -/lib/lib-elf.a -/lib/lib-elf-ps5.a + /lib/syscalls.asm /lib/syscalls-ps5.asm - -# Build artifacts from prosper0gdb/. -/prosper0gdb/*.o -/prosper0gdb/payload.elf -/prosper0gdb/payload.bin - # Build artifacts from ps5-kstuff-ldr/. /ps5-kstuff-ldr/kstuff.elf /ps5-kstuff-ldr/payload_bin.c @@ -33,3 +22,9 @@ refs/* /ps5-kstuff/uelf/uelf.bin /ps5-kstuff/debug-reader.bin /ps5-kstuff/debug-reader.elf +/ps5-kstuff/.build-config +logs/ +*.bin +*.elf +*.o +*.a diff --git a/ps5-kstuff/Makefile b/ps5-kstuff/Makefile index c0660ae..b1a297a 100644 --- a/ps5-kstuff/Makefile +++ b/ps5-kstuff/Makefile @@ -5,6 +5,7 @@ UELF_ARCH ?= -march=znver2 -mtune=znver2 KSTUFF_OBS ?= 0 ALL_TARGETS := payload.bin +BUILD_CONFIG := .build-config ifeq ($(KSTUFF_OBS),1) ifndef PS5_PAYLOAD_SDK @@ -16,7 +17,19 @@ endif all: $(ALL_TARGETS) clean: - rm -f payload.elf payload.bin debug-reader.elf debug-reader.bin freebsd-loader kelf kelf.o structs.h structs.inc uelf/uelf uelf/uelf.bin uelf/crt.o + rm -f payload.elf payload.bin debug-reader.elf debug-reader.bin freebsd-loader kelf kelf.o structs.h structs.inc uelf/uelf uelf/uelf.bin uelf/crt.o $(BUILD_CONFIG) + +.PHONY: FORCE +FORCE: + +$(BUILD_CONFIG): FORCE + @tmp="$@.tmp"; \ + printf 'KSTUFF_OBS=%s\n' "$(KSTUFF_OBS)" > "$$tmp"; \ + printf 'EXTRA_CFLAGS=%s\n' "$(EXTRA_CFLAGS)" >> "$$tmp"; \ + printf 'PAYLOAD_OPT=%s\n' "$(PAYLOAD_OPT)" >> "$$tmp"; \ + printf 'UELF_OPT=%s\n' "$(UELF_OPT)" >> "$$tmp"; \ + printf 'UELF_ARCH=%s\n' "$(UELF_ARCH)" >> "$$tmp"; \ + if test -f "$@" && cmp -s "$$tmp" "$@"; then rm -f "$$tmp"; else mv "$$tmp" "$@"; fi ../lib/lib-elf-ps5.a: cd ../lib; $(MAKE) @@ -27,7 +40,7 @@ clean: structs.inc: structs-ps5.inc cp structs-ps5.inc structs.inc -payload.elf: ../lib/lib-elf-ps5.a ../prosper0gdb/prosper0gdb.o main.c kelf uelf/uelf.bin +payload.elf: ../lib/lib-elf-ps5.a ../prosper0gdb/prosper0gdb.o main.c kelf uelf/uelf.bin $(BUILD_CONFIG) gcc $(PAYLOAD_OPT) -isystem ../freebsd-headers -nostdinc -nostdlib -fno-stack-protector -static ../lib/lib-elf-ps5.a ../prosper0gdb/prosper0gdb.o $(EXTRA_CFLAGS) -DKSTUFF_OBS=$(KSTUFF_OBS) main.c -DPS5KEK ../prosper0gdb/dbg.c -Wl,-gc-sections -o payload.elf -fPIE -ffreestanding -no-pie -Wl,-z,max-page-size=16384 -Wl,-z,common-page-size=16384 payloa%.bin: payloa%.elf @@ -46,7 +59,7 @@ structs.h: structs.inc uelf/crt.o: uelf/crt.asm yasm uelf/crt.asm -f elf64 -o uelf/crt.o -uelf/uelf: uelf/*.c uelf/*.h structs.h uelf/crt.o BearSSL/build/libbearssl.a isa-l_crypto/bin/isa-l_crypto.a +uelf/uelf: uelf/*.c uelf/*.h structs.h uelf/crt.o BearSSL/build/libbearssl.a isa-l_crypto/bin/isa-l_crypto.a $(BUILD_CONFIG) gcc -Wl,-Bsymbolic -Wl,-gc-sections -ffunction-sections -fdata-sections $(UELF_OPT) $(UELF_ARCH) -g -isystem ../freebsd-headers -isystem isa-l_crypto/include -nostdinc -nostdlib -mgeneral-regs-only -fno-stack-protector -fPIE -fPIC -shared -fvisibility=hidden -ffreestanding uelf/crt.o $(EXTRA_CFLAGS) -DKSTUFF_OBS=$(KSTUFF_OBS) uelf/*.c BearSSL/build/libbearssl.a isa-l_crypto/bin/isa-l_crypto.a -o uelf/uelf -Wl,-z,max-page-size=4096 uelf/uelf.bin: uelf/uelf From fc906b298b867431ae921eb97266c974bff8e8c1 Mon Sep 17 00:00:00 2001 From: Roman Tarasov Date: Sun, 31 May 2026 14:35:57 +0300 Subject: [PATCH 2/9] uelf: remove observability overhead from non-OBS builds --- ps5-kstuff/uelf/log.c | 3 +++ ps5-kstuff/uelf/log.h | 21 +++++++++++++++++++++ ps5-kstuff/uelf/shared_area.h | 17 ++++++++++++++--- ps5-kstuff/uelf/utils.h | 6 ++---- 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/ps5-kstuff/uelf/log.c b/ps5-kstuff/uelf/log.c index 2dca0b2..35dd6df 100644 --- a/ps5-kstuff/uelf/log.c +++ b/ps5-kstuff/uelf/log.c @@ -4,6 +4,7 @@ #include #include "utils.h" +#if KSTUFF_OBS #if KSTUFF_OBS static struct { @@ -365,3 +366,5 @@ int copy_shared_area_snapshot(uint64_t dst, uint64_t sz) return ENOSYS; } #endif + +#endif diff --git a/ps5-kstuff/uelf/log.h b/ps5-kstuff/uelf/log.h index 6e54b50..744b5c3 100644 --- a/ps5-kstuff/uelf/log.h +++ b/ps5-kstuff/uelf/log.h @@ -19,6 +19,7 @@ enum kstuff_syscall_tag KSTUFF_SYSCALL_MDBG_CALL, }; +#if KSTUFF_OBS void log_word(uint64_t word); void log_msg(const char* msg); int copy_shared_area_snapshot(uint64_t dst, uint64_t sz); @@ -28,3 +29,23 @@ void observe_syscall_armed(enum kstuff_syscall_tag tag); void observe_current_syscall_trap(void); void observe_current_syscall_emulated(void); void observe_current_syscall_finish(void); +#else +static inline void log_word(uint64_t word) { (void)word; } +static inline void log_msg(const char* msg) { (void)msg; } +static inline int copy_shared_area_snapshot(uint64_t dst, uint64_t sz) +{ + (void)dst; + (void)sz; + return -1; +} +static inline void observe_ioctl_com_total(uint64_t com) { (void)com; } +static inline void observe_ioctl_com_emulated(uint64_t com, uint32_t cmd) +{ + (void)com; + (void)cmd; +} +static inline void observe_syscall_armed(enum kstuff_syscall_tag tag) { (void)tag; } +static inline void observe_current_syscall_trap(void) {} +static inline void observe_current_syscall_emulated(void) {} +static inline void observe_current_syscall_finish(void) {} +#endif diff --git a/ps5-kstuff/uelf/shared_area.h b/ps5-kstuff/uelf/shared_area.h index 32bc701..a07afe5 100644 --- a/ps5-kstuff/uelf/shared_area.h +++ b/ps5-kstuff/uelf/shared_area.h @@ -7,13 +7,18 @@ #endif enum { - SHARED_AREA_SIZE = 8192, SHARED_FAKE_KEY_SLOTS = 63, SHARED_LOG_WORD_CAP = 16, SHARED_LOG_MSG_CAP = 488, SHARED_IOCTL_COM_TRACK_CAP = 128, }; +#if KSTUFF_OBS +enum { SHARED_AREA_SIZE = 8192 }; +#else +enum { SHARED_AREA_SIZE = 2048 }; +#endif + struct kstuff_metrics { uint64_t handle_entries; @@ -273,10 +278,12 @@ struct shared_area_layout uint64_t ready_mask; char pad[16]; uint8_t key_data[SHARED_FAKE_KEY_SLOTS][32]; +#if KSTUFF_OBS struct kstuff_metrics metrics; struct kstuff_word_log word_log; struct kstuff_ioctl_com_table ioctl_com_table; struct kstuff_msg_log msg_log; +#endif }; extern struct shared_area_layout shared_area; @@ -292,8 +299,8 @@ extern struct shared_area_layout shared_area; } while(0) #else #define METRIC_INC(field) do { } while(0) -#define METRIC_ADD(field, value) do { (void)(value); } while(0) -#define METRIC_MAX(field, value) do { (void)(value); } while(0) +#define METRIC_ADD(field, value) do { } while(0) +#define METRIC_MAX(field, value) do { } while(0) #endif _Static_assert(sizeof(struct kstuff_metrics) == 1544, "unexpected metrics size"); @@ -302,5 +309,9 @@ _Static_assert(sizeof(struct kstuff_ioctl_com_entry) == 24, "unexpected ioctl co _Static_assert(sizeof(struct kstuff_ioctl_com_table) == 3088, "unexpected ioctl com table size"); _Static_assert(sizeof(struct kstuff_msg_log) == 504, "unexpected message log size"); _Static_assert(sizeof(struct kstuff_snapshot) == 5416, "unexpected snapshot size"); +#if KSTUFF_OBS _Static_assert(sizeof(struct shared_area_layout) == 7448, "unexpected shared_area size"); +#else +_Static_assert(sizeof(struct shared_area_layout) == 2048, "unexpected non-OBS shared_area size"); +#endif _Static_assert(sizeof(struct shared_area_layout) <= SHARED_AREA_SIZE, "shared_area must fit in configured mapping"); diff --git a/ps5-kstuff/uelf/utils.h b/ps5-kstuff/uelf/utils.h index a6df577..147c428 100644 --- a/ps5-kstuff/uelf/utils.h +++ b/ps5-kstuff/uelf/utils.h @@ -48,10 +48,8 @@ static inline uint64_t uelf_rdtsc(void) METRIC_MAX(max_field, _metric_elapsed); \ } while(0) #else -#define METRIC_TIME_START(var) uint64_t var __attribute__((unused)) = 0 -#define METRIC_TIME(total_field, max_field, start_cycles) do { \ - (void)(start_cycles); \ -} while(0) +#define METRIC_TIME_START(var) enum { var = 0 } +#define METRIC_TIME(total_field, max_field, start_cycles) do { } while(0) #endif static inline int kpeek64_checked(uintptr_t kptr, uint64_t* value) From 9175b8e9a7617329174786329cb4fe7b97b18f84 Mon Sep 17 00:00:00 2001 From: Roman Tarasov Date: Sun, 31 May 2026 15:24:40 +0300 Subject: [PATCH 3/9] uelf: simplify OBS log build guards --- ps5-kstuff/uelf/log.c | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/ps5-kstuff/uelf/log.c b/ps5-kstuff/uelf/log.c index 35dd6df..08b0f32 100644 --- a/ps5-kstuff/uelf/log.c +++ b/ps5-kstuff/uelf/log.c @@ -4,7 +4,6 @@ #include #include "utils.h" -#if KSTUFF_OBS #if KSTUFF_OBS static struct { @@ -102,25 +101,19 @@ static void observe_syscall_metric(enum kstuff_syscall_tag tag, int kind) } #undef OBS_CASE } -#endif void log_word(uint64_t word) { -#if KSTUFF_OBS uint64_t seq = __atomic_fetch_add(&shared_area.word_log.next_seq, 1, __ATOMIC_RELAXED); struct kstuff_word_log_entry* entry = &shared_area.word_log.entries[seq % SHARED_LOG_WORD_CAP]; __atomic_store_n(&entry->seq, 0, __ATOMIC_RELAXED); entry->word = word; __atomic_store_n(&entry->seq, seq + 1, __ATOMIC_RELEASE); METRIC_INC(log_word_writes); -#else - (void)word; -#endif } void log_msg(const char* msg) { -#if KSTUFF_OBS if(!msg) return; size_t len = strlen(msg); @@ -144,14 +137,10 @@ void log_msg(const char* msg) spin_unlock_u64(&shared_area.msg_log.write_lock); METRIC_INC(log_msg_writes); METRIC_ADD(log_msg_bytes, len); -#else - (void)msg; -#endif } void observe_ioctl_com_emulated(uint64_t com, uint32_t cmd) { -#if KSTUFF_OBS spin_lock_u64(&shared_area.ioctl_com_table.write_lock); struct kstuff_ioctl_com_entry* entry = find_or_add_ioctl_com_entry_locked(com); if(entry) @@ -165,69 +154,50 @@ void observe_ioctl_com_emulated(uint64_t com, uint32_t cmd) entry->cmd6_hits++; } spin_unlock_u64(&shared_area.ioctl_com_table.write_lock); -#else - (void)com; - (void)cmd; -#endif } void observe_ioctl_com_total(uint64_t com) { -#if KSTUFF_OBS struct kstuff_ioctl_com_entry* entry = find_tracked_ioctl_com_entry(com); if(entry) __atomic_fetch_add(&entry->total_hits, 1, __ATOMIC_RELAXED); -#else - (void)com; -#endif } void observe_syscall_armed(enum kstuff_syscall_tag tag) { -#if KSTUFF_OBS s_current_syscall_state.tag = tag; s_current_syscall_state.trap_reported = 0; s_current_syscall_state.emu_reported = 0; observe_syscall_metric(tag, 0); -#else - (void)tag; -#endif } void observe_current_syscall_trap(void) { -#if KSTUFF_OBS if(s_current_syscall_state.tag != KSTUFF_SYSCALL_NONE && !s_current_syscall_state.trap_reported) { s_current_syscall_state.trap_reported = 1; observe_syscall_metric(s_current_syscall_state.tag, 1); } -#endif } void observe_current_syscall_emulated(void) { -#if KSTUFF_OBS if(s_current_syscall_state.tag != KSTUFF_SYSCALL_NONE && !s_current_syscall_state.emu_reported) { s_current_syscall_state.emu_reported = 1; observe_syscall_metric(s_current_syscall_state.tag, 2); } -#endif } void observe_current_syscall_finish(void) { -#if KSTUFF_OBS s_current_syscall_state.tag = KSTUFF_SYSCALL_NONE; s_current_syscall_state.trap_reported = 0; s_current_syscall_state.emu_reported = 0; -#endif } -#if KSTUFF_OBS static int virt2phys_untracked(uint64_t addr, uint64_t* phys, uint64_t* phys_limit) { uint64_t pml = cr3_phys; @@ -358,13 +328,5 @@ int copy_shared_area_snapshot(uint64_t dst, uint64_t sz) return EFAULT; return 0; } -#else -int copy_shared_area_snapshot(uint64_t dst, uint64_t sz) -{ - (void)dst; - (void)sz; - return ENOSYS; -} -#endif #endif From c0166970c1e14d84731bbbabedf37906ae833ff6 Mon Sep 17 00:00:00 2001 From: Roman Tarasov Date: Sun, 31 May 2026 15:01:20 +0300 Subject: [PATCH 4/9] uelf: split FSELF handled and emulated results --- ps5-kstuff/uelf/fself.c | 47 ++++++++++++++++++++++++++------------- ps5-kstuff/uelf/fself.h | 10 ++++++++- ps5-kstuff/uelf/mailbox.c | 6 +++-- ps5-kstuff/uelf/main.c | 6 +++-- 4 files changed, 48 insertions(+), 21 deletions(-) diff --git a/ps5-kstuff/uelf/fself.c b/ps5-kstuff/uelf/fself.c index 295ec97..bb3eb85 100644 --- a/ps5-kstuff/uelf/fself.c +++ b/ps5-kstuff/uelf/fself.c @@ -324,6 +324,7 @@ void handle_fself_trap(uint64_t* regs, uint32_t trapno) int try_handle_fself_mailbox(uint64_t* regs, uint64_t lr) { METRIC_TIME_START(start_cycles); + int emulated = 0; #define RETURN_FSELF_MAILBOX(value) do { METRIC_TIME(fself_mailbox_cycles_total, fself_mailbox_cycles_max, start_cycles); return (value); } while(0) /* * Telemetry shows the mailbox hot order is decryptSelfBlock, decryptMultipleSelfBlocks, @@ -353,6 +354,7 @@ int try_handle_fself_mailbox(uint64_t* regs, uint64_t lr) memcpy(DMEM+request[1], DMEM+request[2], (uint32_t)request[6]); regs[RAX] = 0; METRIC_INC(fself_mailbox_decrypt_self_block_emulated); + emulated = 1; } } else if(lr == (uint64_t)sceSblServiceMailbox_lr_decryptMultipleSelfBlocks) @@ -383,6 +385,7 @@ int try_handle_fself_mailbox(uint64_t* regs, uint64_t lr) copy_decrypted_self_blocks(DMEM, src, dst, request[5]); regs[RAX] = 0; METRIC_INC(fself_mailbox_decrypt_multiple_self_blocks_emulated); + emulated = 1; } } else if(lr == (uint64_t)sceSblServiceMailbox_lr_verifyHeader) @@ -397,14 +400,14 @@ int try_handle_fself_mailbox(uint64_t* regs, uint64_t lr) if(kpeek64_checked(self_context + 56, &self_header)) RETURN_FSELF_MAILBOX(0); if(!is_header_fself(self_header, size, 0, 0, 0, 0)) - RETURN_FSELF_MAILBOX(1); + RETURN_FSELF_MAILBOX(FSELF_HANDLE_HANDLED); if(copy_from_kernel(ctx_data, self_context, sizeof(ctx_data))) RETURN_FSELF_MAILBOX(0); if(ctx_data[7] != self_header) { self_header = ctx_data[7]; if(!is_header_fself(self_header, size, 0, 0, 0, 0)) - RETURN_FSELF_MAILBOX(1); + RETURN_FSELF_MAILBOX(FSELF_HANDLE_HANDLED); } remember_context_fself_info(self_context, self_header, size, ctx_data); char fself_header_backup[(48 + mini_syscore_header_size + 15) & -16]; @@ -434,6 +437,7 @@ int try_handle_fself_mailbox(uint64_t* regs, uint64_t lr) RETURN_FSELF_MAILBOX(0); } METRIC_INC(fself_mailbox_verify_header_emulated); + emulated = 1; } else if(lr == (uint64_t)sceSblServiceMailbox_lr_loadSelfSegment) { @@ -459,18 +463,20 @@ int try_handle_fself_mailbox(uint64_t* regs, uint64_t lr) RETURN_FSELF_MAILBOX(0); regs[RAX] = 0; METRIC_INC(fself_mailbox_load_self_segment_emulated); + emulated = 1; } } else RETURN_FSELF_MAILBOX(0); - RETURN_FSELF_MAILBOX(1); + RETURN_FSELF_MAILBOX(FSELF_HANDLE_HANDLED | (emulated ? FSELF_HANDLE_EMULATED : 0)); #undef RETURN_FSELF_MAILBOX } int try_handle_fself_trap(uint64_t* regs) { METRIC_TIME_START(start_cycles); + int emulated = 0; #define RETURN_FSELF_TRAP(value) do { METRIC_TIME(fself_trap_cycles_total, fself_trap_cycles_max, start_cycles); return (value); } while(0) /* * The hot trap order is watchpoint, epilogue, then SmIsLoadable2. @@ -481,24 +487,31 @@ int try_handle_fself_trap(uint64_t* regs) METRIC_INC(fself_trap_watchpoint); uint64_t frame[4]; if(copy_from_kernel(frame, regs[RSP], sizeof(frame))) - RETURN_FSELF_TRAP(1); + RETURN_FSELF_TRAP(FSELF_HANDLE_HANDLED); regs[(FWVER >= 0x800) ? RAX : R10] |= 0xffffull << 48; if(frame[3] == (uint64_t)loadSelfSegment_watchpoint_lr) { - if(!set_dbgregs_for_watchpoint(regs, dbgregs_for_loadSelfSegment, sizeof(frame))) - RETURN_FSELF_TRAP(1); + if(set_dbgregs_for_watchpoint(regs, dbgregs_for_loadSelfSegment, sizeof(frame))) + emulated = 1; + else + RETURN_FSELF_TRAP(FSELF_HANDLE_HANDLED); } else if(frame[3] == (uint64_t)decryptSelfBlock_watchpoint_lr) { - if(!set_dbgregs_for_watchpoint(regs, dbgregs_for_decryptSelfBlock, sizeof(frame))) - RETURN_FSELF_TRAP(1); + if(set_dbgregs_for_watchpoint(regs, dbgregs_for_decryptSelfBlock, sizeof(frame))) + emulated = 1; + else + RETURN_FSELF_TRAP(FSELF_HANDLE_HANDLED); } else if(frame[3] == (uint64_t)decryptMultipleSelfBlocks_watchpoint_lr) { - if(!set_dbgregs_for_watchpoint(regs, dbgregs_for_decryptMultipleSelfBlocks, sizeof(frame))) - RETURN_FSELF_TRAP(1); + if(set_dbgregs_for_watchpoint(regs, dbgregs_for_decryptMultipleSelfBlocks, sizeof(frame))) + emulated = 1; + else + RETURN_FSELF_TRAP(FSELF_HANDLE_HANDLED); } - METRIC_INC(fself_trap_watchpoint_emulated); + if(emulated) + METRIC_INC(fself_trap_watchpoint_emulated); } else if(regs[RIP] == (uint64_t)loadSelfSegment_epilogue || regs[RIP] == (uint64_t)decryptSelfBlock_epilogue @@ -506,8 +519,9 @@ int try_handle_fself_trap(uint64_t* regs) { METRIC_INC(fself_trap_epilogue); if(!unset_dbgregs_for_watchpoint(regs)) - RETURN_FSELF_TRAP(1); + RETURN_FSELF_TRAP(FSELF_HANDLE_HANDLED); METRIC_INC(fself_trap_epilogue_emulated); + emulated = 1; } else if(regs[RIP] == (uint64_t)sceSblAuthMgrSmIsLoadable2) { @@ -537,20 +551,21 @@ int try_handle_fself_trap(uint64_t* regs) p_authinfo = s_auth_info_for_exec; } if(copy_u64_from_kernel(&ret_addr, regs[RSP])) - RETURN_FSELF_TRAP(1); + RETURN_FSELF_TRAP(FSELF_HANDLE_HANDLED); if(copy_to_kernel(regs[R8], p_authinfo, 0x88)) - RETURN_FSELF_TRAP(1); + RETURN_FSELF_TRAP(FSELF_HANDLE_HANDLED); if(copy_u16_to_kernel(regs[RDI] + 62, 0xdeb7)) - RETURN_FSELF_TRAP(1); + RETURN_FSELF_TRAP(FSELF_HANDLE_HANDLED); regs[RSP] += 8; regs[RIP] = ret_addr; regs[RAX] = 0; METRIC_INC(fself_trap_is_loadable2_emulated); + emulated = 1; } } else RETURN_FSELF_TRAP(0); - RETURN_FSELF_TRAP(1); + RETURN_FSELF_TRAP(FSELF_HANDLE_HANDLED | (emulated ? FSELF_HANDLE_EMULATED : 0)); #undef RETURN_FSELF_TRAP } diff --git a/ps5-kstuff/uelf/fself.h b/ps5-kstuff/uelf/fself.h index 62090ca..961fe2a 100644 --- a/ps5-kstuff/uelf/fself.h +++ b/ps5-kstuff/uelf/fself.h @@ -10,5 +10,13 @@ void handle_fself_syscall(uint64_t* regs); void handle_fself_trap(uint64_t* regs, uint32_t trapno); + +#define FSELF_HANDLE_HANDLED 1 +#if KSTUFF_OBS +#define FSELF_HANDLE_EMULATED 2 +#else +#define FSELF_HANDLE_EMULATED 0 +#endif + int try_handle_fself_trap(uint64_t* regs); -int try_handle_fself_mailbox(uint64_t* regs, uint64_t lr); \ No newline at end of file +int try_handle_fself_mailbox(uint64_t* regs, uint64_t lr); diff --git a/ps5-kstuff/uelf/mailbox.c b/ps5-kstuff/uelf/mailbox.c index fb9afba..d58c499 100644 --- a/ps5-kstuff/uelf/mailbox.c +++ b/ps5-kstuff/uelf/mailbox.c @@ -14,11 +14,13 @@ int try_handle_mailbox_trap(uint64_t* regs) { METRIC_INC(mailbox_traps); uint64_t lr = kpeek64(regs[RSP]); - if(try_handle_fself_mailbox(regs, lr)) + int fself_result = try_handle_fself_mailbox(regs, lr); + if(fself_result & FSELF_HANDLE_HANDLED) { METRIC_INC(mailbox_fself); observe_current_syscall_trap(); - observe_current_syscall_emulated(); + if(fself_result & FSELF_HANDLE_EMULATED) + observe_current_syscall_emulated(); return 1; } if(try_handle_fpkg_mailbox(regs, lr)) diff --git a/ps5-kstuff/uelf/main.c b/ps5-kstuff/uelf/main.c index ac7fa75..0b491ac 100644 --- a/ps5-kstuff/uelf/main.c +++ b/ps5-kstuff/uelf/main.c @@ -300,11 +300,13 @@ static inline int handle_kernel_trap_fast(uint64_t* regs, uint64_t rip) } if(is_fself_trap_rip(rip)) { - if(try_handle_fself_trap(regs)) + int fself_result = try_handle_fself_trap(regs); + if(fself_result & FSELF_HANDLE_HANDLED) { METRIC_INC(fself_traps); observe_current_syscall_trap(); - observe_current_syscall_emulated(); + if(fself_result & FSELF_HANDLE_EMULATED) + observe_current_syscall_emulated(); return 1; } } From 32b4f8f7ca50f12f58a012a6f11f7a277aaaebcc Mon Sep 17 00:00:00 2001 From: Roman Tarasov Date: Sun, 31 May 2026 15:14:37 +0300 Subject: [PATCH 5/9] uelf: fix DBREGS restore state flag --- ps5-kstuff/uelf/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ps5-kstuff/uelf/utils.c b/ps5-kstuff/uelf/utils.c index fa55f48..07a8199 100644 --- a/ps5-kstuff/uelf/utils.c +++ b/ps5-kstuff/uelf/utils.c @@ -455,7 +455,7 @@ void handle_utils_trap(uint64_t* regs, uint32_t trapno) uint64_t stack_frame[12]; if(peek_stack_checked(regs, stack_frame, sizeof(stack_frame))) return; - if(restore_dbgregs_state_checked(stack_frame+5, stack_frame[4])) + if(restore_dbgregs_state_checked(stack_frame+5, stack_frame[3])) return; regs[RSP] += sizeof(stack_frame); regs[RIP] = stack_frame[11]; From 45f6dd22cd2c0cff93abdbd5f6c1778e3613746b Mon Sep 17 00:00:00 2001 From: Roman Tarasov Date: Sun, 31 May 2026 16:03:29 +0300 Subject: [PATCH 6/9] uelf: use fixed NPDRM interception path Drop the ioctl command allow-list and expected command mask prefilter from the NPDRM path. Keep ioctl-com tracking only for OBS builds and always arm the NPDRM mailbox breakpoint from the ioctl syscall path. Use the matched mailbox LR as the cmd6 guard in non-porting builds while reading the request command from the mailbox payload for the rest of the handler. --- ps5-kstuff/uelf/npdrm.c | 120 +++++----------------------------------- ps5-kstuff/uelf/npdrm.h | 4 ++ 2 files changed, 17 insertions(+), 107 deletions(-) diff --git a/ps5-kstuff/uelf/npdrm.c b/ps5-kstuff/uelf/npdrm.c index 83df39e..ebbce30 100644 --- a/ps5-kstuff/uelf/npdrm.c +++ b/ps5-kstuff/uelf/npdrm.c @@ -1,7 +1,6 @@ // https://github.com/PS5Dev/Byepervisor/blob/57204cbd7bd26ed4623634d52b0f60f40d630087/hen/src/fpkg.cpp#L82 #include -#include #include #include "utils.h" #include "npdrm.h" @@ -23,25 +22,21 @@ extern char sceSblServiceMailbox[]; static const uint8_t rif_debug_key[] = {0x96, 0xC2, 0x26, 0x8D, 0x69, 0x26, 0x1C, 0x8B, 0x1E, 0x3B, 0x6B, 0xFF, 0x2F, 0xE0, 0x4E, 0x12}; enum { AES128_EXPKEY_SIZE = 16 * 11 }; -enum { - NPDRM_EXPECT_CMD5 = 1u << 0, - NPDRM_EXPECT_CMD6 = 1u << 1, -}; +#if KSTUFF_OBS static struct { -#if KSTUFF_OBS uint64_t com; -#endif - uint8_t expected_cmd_mask; - uint8_t valid; + int valid; } s_current_ioctl_state; +#endif +#if KSTUFF_OBS void finish_npdrm_ioctl_state(void) { - s_current_ioctl_state.expected_cmd_mask = 0; s_current_ioctl_state.valid = 0; } +#endif static struct { @@ -113,26 +108,12 @@ int try_handle_npdrm_mailbox(uint64_t *regs, uint64_t lr) METRIC_INC(npdrm_reject_bad_lr); RETURN_NPDRM(0); } - cmd = (lr == (uint64_t)sceSblServiceMailbox_lr_npdrm_cmd_5) ? 5u : 6u; - if (s_current_ioctl_state.valid) - { - const uint8_t lr_cmd_mask = (cmd == 5u) ? NPDRM_EXPECT_CMD5 : NPDRM_EXPECT_CMD6; - if (!(s_current_ioctl_state.expected_cmd_mask & lr_cmd_mask)) - { - METRIC_INC(npdrm_reject_bad_cmd); - RETURN_NPDRM(1); - } - } if (copy_from_kernel(&request_hdr, regs[RDX], sizeof(request_hdr))) { METRIC_INC(npdrm_reject_copy_in_fail); RETURN_NPDRM(1); } - if (request_hdr.cmd != cmd) - { - METRIC_INC(npdrm_reject_bad_cmd); - RETURN_NPDRM(1); - } + cmd = request_hdr.cmd; #else if (copy_from_kernel(&request_hdr, regs[RDX], sizeof(request_hdr))) { @@ -211,7 +192,7 @@ int try_handle_npdrm_mailbox(uint64_t *regs, uint64_t lr) #ifdef NPDRM_PORTING if (cmd == 6) #else - if (cmd == 6) + if (lr == (uint64_t)sceSblServiceMailbox_lr_npdrm_cmd_6) #endif { uint8_t decrypted_secret[sizeof(rif->rifSecret)]; @@ -293,96 +274,21 @@ static const uint64_t dbgregs_for_ioctl[6] = { (uint64_t)sceSblServiceMailbox, 0, 0, 0, 0, 0x401}; -static uint8_t classify_npdrm_ioctl(uint64_t com) -{ - const uint32_t dir = (uint32_t)(com & IOC_DIRMASK); - const uint32_t len = IOCPARM_LEN(com); - const uint32_t group = IOCGROUP(com); - const uint32_t num = (uint32_t)(com & 0xff); - - /* - * Hot path from observed logs: - * IOC_INOUT + group 'N' (0x4e) - * with the useful commands clustered in len=0x20 and len=0x34. - * - * Keep the rest of the known-good commands in the rare exact tail below - * so coverage stays the same while the common case gets cheaper. - */ - if(__builtin_expect(dir == IOC_INOUT && group == 0x4e, 1)) - { - if(len == 0x20) - { - if(num == 0x0d || num == 0x0e) - return NPDRM_EXPECT_CMD5 | NPDRM_EXPECT_CMD6; - if(num == 0x16) - return NPDRM_EXPECT_CMD6; - } - else if(len == 0x34 && num == 0x18) - return NPDRM_EXPECT_CMD6; - } - - switch(com) - { - case 0x000000004004ae25ULL: - case 0x0000000040105305ULL: - case 0x0000000080048138ULL: - case 0x000000008008483eULL: - case 0x000000008010480fULL: - case 0x000000008018910bULL: - case 0x0000000080206216ULL: - case 0x0000000080208218ULL: - case 0x0000000080283208ULL: - case 0x0000000080308217ULL: - case 0x00000000c0044512ULL: - case 0x00000000c00c5a02ULL: - case 0x00000000c0108102ULL: - case 0x00000000c01c8f07ULL: - case 0x00000000c02066a5ULL: - case 0x00000000c0288907ULL: - case 0x00000000c0288908ULL: - case 0x00000000c028ab00ULL: - case 0x00000000c030ab00ULL: - case 0x00000000c0484851ULL: - return NPDRM_EXPECT_CMD5 | NPDRM_EXPECT_CMD6; - default: - return 0; - } -} - void handle_ioctl_syscall(uint64_t *regs) { +#if KSTUFF_OBS struct ioctl_args uap; - uint8_t expected_cmd_mask; + finish_npdrm_ioctl_state(); if(copy_from_kernel(&uap, regs[RSI], sizeof(uap))) { - finish_npdrm_ioctl_state(); -#if KSTUFF_OBS METRIC_INC(ioctl_prefilter_copy_in_fail_open); -#endif - start_syscall_with_dbgregs(regs, dbgregs_for_ioctl); - return; } - -#if KSTUFF_OBS - s_current_ioctl_state.com = (uint64_t)uap.com; -#endif - finish_npdrm_ioctl_state(); - - expected_cmd_mask = classify_npdrm_ioctl((uint64_t)uap.com); - if(!expected_cmd_mask) + else { -#if KSTUFF_OBS - METRIC_INC(ioctl_prefilter_skipped); -#endif - observe_current_syscall_finish(); - return; + s_current_ioctl_state.com = (uint64_t)uap.com; + s_current_ioctl_state.valid = 1; + observe_ioctl_com_total(s_current_ioctl_state.com); } - -#if KSTUFF_OBS - METRIC_INC(ioctl_prefilter_allowed); - observe_ioctl_com_total(s_current_ioctl_state.com); #endif - s_current_ioctl_state.expected_cmd_mask = expected_cmd_mask; - s_current_ioctl_state.valid = 1; start_syscall_with_dbgregs(regs, dbgregs_for_ioctl); } diff --git a/ps5-kstuff/uelf/npdrm.h b/ps5-kstuff/uelf/npdrm.h index 7f2da7a..5934a1e 100644 --- a/ps5-kstuff/uelf/npdrm.h +++ b/ps5-kstuff/uelf/npdrm.h @@ -84,4 +84,8 @@ struct RifCmd56MemoryLayout int try_handle_npdrm_mailbox(uint64_t *regs, uint64_t lr); void handle_ioctl_syscall(uint64_t *regs); +#if KSTUFF_OBS void finish_npdrm_ioctl_state(void); +#else +static inline void finish_npdrm_ioctl_state(void) {} +#endif From 2dacae828daa449ff573f92e33a903bb813943f8 Mon Sep 17 00:00:00 2001 From: Roman Tarasov Date: Sun, 31 May 2026 14:20:56 +0300 Subject: [PATCH 7/9] uelf: drop unused FSELF overlap coalesce guard --- ps5-kstuff/uelf/fself.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/ps5-kstuff/uelf/fself.c b/ps5-kstuff/uelf/fself.c index bb3eb85..9d77cb7 100644 --- a/ps5-kstuff/uelf/fself.c +++ b/ps5-kstuff/uelf/fself.c @@ -16,11 +16,6 @@ static uint64_t s_auth_info_for_exec_ps4[17] = {0x3100000000000001, 0x2000038000 enum { SELF_BLOCK_SIZE = 16384 }; -static int fself_block_ranges_overlap(uint64_t src, uint64_t dst, size_t size) -{ - return src < dst ? dst - src < size : src - dst < size; -} - static void copy_decrypted_self_blocks(char* dmem, const uint64_t* src, const uint64_t* dst, uint32_t count) { for(uint32_t i = 0; i < count;) @@ -42,11 +37,9 @@ static void copy_decrypted_self_blocks(char* dmem, const uint64_t* src, const ui continue; } - // Overlapping runs rely on per-block copy order. while(i + 1 < count && src[i + 1] == run_src + run_size - && dst[i + 1] == run_dst + run_size - && !fself_block_ranges_overlap(run_src, run_dst, run_size + SELF_BLOCK_SIZE)) + && dst[i + 1] == run_dst + run_size) { i++; run_size += SELF_BLOCK_SIZE; From 166f90f4c7cba67fd73ba2a431140a341f5b0e1d Mon Sep 17 00:00:00 2001 From: Roman Tarasov Date: Sun, 31 May 2026 14:45:44 +0300 Subject: [PATCH 8/9] uelf: remove unused XTS message coalescing --- ps5-kstuff/debug-reader.c | 1 - ps5-kstuff/uelf/fpkg.c | 47 ++++++++--------------------------- ps5-kstuff/uelf/shared_area.h | 7 +++--- 3 files changed, 14 insertions(+), 41 deletions(-) diff --git a/ps5-kstuff/debug-reader.c b/ps5-kstuff/debug-reader.c index a7e6a8c..8218780 100644 --- a/ps5-kstuff/debug-reader.c +++ b/ps5-kstuff/debug-reader.c @@ -259,7 +259,6 @@ static void print_metrics(const struct kstuff_metrics* metrics) PRINT_FIELD("req", metrics->xts_requests); PRINT_FIELD("sectors", metrics->xts_sectors); PRINT_FIELD("run_msg", metrics->xts_run_messages_total); - PRINT_FIELD("coalesced", metrics->xts_run_coalesced_messages); PRINT_FIELD("skipped", metrics->xts_run_skip_sectors); PRINT_FIELD("direct_runs", metrics->xts_full_direct_runs); PRINT_FIELD("direct_sectors", metrics->xts_full_direct_sectors); diff --git a/ps5-kstuff/uelf/fpkg.c b/ps5-kstuff/uelf/fpkg.c index 3206bf0..eb9d3f3 100644 --- a/ps5-kstuff/uelf/fpkg.c +++ b/ps5-kstuff/uelf/fpkg.c @@ -156,10 +156,10 @@ static struct crypto_message_result handle_hmac_message(uint64_t msg, const uint return result; } -static struct crypto_message_result handle_xts_message_run(uint64_t msg, const uint64_t first_msg_data[21], - int key_idx, - uint64_t bytes_cap, uint64_t* bytes_handled, - struct crypto_request_cache* cache) +static struct crypto_message_result handle_xts_message(uint64_t msg, const uint64_t msg_data[21], + int key_idx, + uint64_t bytes_cap, uint64_t* bytes_handled, + struct crypto_request_cache* cache) { struct crypto_message_result result = unhandled_crypto_message(msg); uint8_t key[32]; @@ -167,34 +167,11 @@ static struct crypto_message_result handle_xts_message_run(uint64_t msg, const u return result; METRIC_INC(xts_run_messages_total); - uint64_t src = first_msg_data[2]; - uint64_t dst = first_msg_data[3]; - uint64_t start_sector = first_msg_data[4]; - uint32_t total_sectors = (uint32_t)first_msg_data[1]; - int is_encrypt = (first_msg_data[0] & 0x800) >> 11; - uint64_t cursor = msg; - - while(result.next_msg) - { - uint64_t next_msg_data[21]; - if(read_crypto_message(result.next_msg, next_msg_data)) - break; - if(!is_xts_message(next_msg_data)) - break; - uint32_t next_sectors = (uint32_t)next_msg_data[1]; - if(HANDLE_TO_IDX(next_msg_data[5]) != key_idx - || (int)((next_msg_data[0] & 0x800) >> 11) != is_encrypt - || next_msg_data[2] != src + ((uint64_t)total_sectors << 12) - || next_msg_data[3] != dst + ((uint64_t)total_sectors << 12) - || next_msg_data[4] != start_sector + total_sectors - || total_sectors > UINT32_MAX - next_sectors) - break; - - total_sectors += next_sectors; - cursor = result.next_msg; - result.next_msg = kpeek64(cursor + 320); - result.total_messages++; - } + uint64_t src = msg_data[2]; + uint64_t dst = msg_data[3]; + uint64_t start_sector = msg_data[4]; + uint32_t total_sectors = (uint32_t)msg_data[1]; + int is_encrypt = (msg_data[0] & 0x800) >> 11; uint64_t run_bytes = (uint64_t)total_sectors << 12; uint64_t skip_bytes = 0; @@ -218,9 +195,7 @@ static struct crypto_message_result handle_xts_message_run(uint64_t msg, const u } } - result.emulated_messages = result.total_messages; - if(result.total_messages > 1) - METRIC_ADD(xts_run_coalesced_messages, result.total_messages - 1); + result.emulated_messages = 1; result.status = 0; return result; } @@ -277,7 +252,7 @@ static int handle_crypto_request(uint64_t* regs, uint64_t bytes_handled) struct crypto_message_result result; if(msg_info.kind == CRYPTO_MESSAGE_XTS) - result = handle_xts_message_run(msg, msg_data, msg_info.key_idx, bytes_handled, &new_bytes_handled, &s_crypto_request_cache); + result = handle_xts_message(msg, msg_data, msg_info.key_idx, bytes_handled, &new_bytes_handled, &s_crypto_request_cache); else if(msg_info.kind == CRYPTO_MESSAGE_HMAC) result = handle_hmac_message(msg, msg_data, msg_info.key_idx, bytes_handled, &new_bytes_handled, &s_crypto_request_cache); else diff --git a/ps5-kstuff/uelf/shared_area.h b/ps5-kstuff/uelf/shared_area.h index a07afe5..a9d1b6e 100644 --- a/ps5-kstuff/uelf/shared_area.h +++ b/ps5-kstuff/uelf/shared_area.h @@ -178,7 +178,6 @@ struct kstuff_metrics uint64_t xts_requests; uint64_t xts_sectors; uint64_t xts_run_messages_total; - uint64_t xts_run_coalesced_messages; uint64_t xts_run_skip_sectors; uint64_t xts_full_direct_runs; @@ -303,14 +302,14 @@ extern struct shared_area_layout shared_area; #define METRIC_MAX(field, value) do { } while(0) #endif -_Static_assert(sizeof(struct kstuff_metrics) == 1544, "unexpected metrics size"); +_Static_assert(sizeof(struct kstuff_metrics) == 1536, "unexpected metrics size"); _Static_assert(sizeof(struct kstuff_word_log) == 264, "unexpected word log size"); _Static_assert(sizeof(struct kstuff_ioctl_com_entry) == 24, "unexpected ioctl com entry size"); _Static_assert(sizeof(struct kstuff_ioctl_com_table) == 3088, "unexpected ioctl com table size"); _Static_assert(sizeof(struct kstuff_msg_log) == 504, "unexpected message log size"); -_Static_assert(sizeof(struct kstuff_snapshot) == 5416, "unexpected snapshot size"); +_Static_assert(sizeof(struct kstuff_snapshot) == 5408, "unexpected snapshot size"); #if KSTUFF_OBS -_Static_assert(sizeof(struct shared_area_layout) == 7448, "unexpected shared_area size"); +_Static_assert(sizeof(struct shared_area_layout) == 7440, "unexpected shared_area size"); #else _Static_assert(sizeof(struct shared_area_layout) == 2048, "unexpected non-OBS shared_area size"); #endif From 4c3340b2315a8ea52131e6bf3386905048e53aee Mon Sep 17 00:00:00 2001 From: Roman Tarasov Date: Sun, 31 May 2026 14:52:13 +0300 Subject: [PATCH 9/9] uelf: remove unused PFS crypto restart path --- ps5-kstuff/debug-reader.c | 3 -- ps5-kstuff/uelf/fpkg.c | 65 ++++++----------------------------- ps5-kstuff/uelf/shared_area.h | 9 ++--- 3 files changed, 13 insertions(+), 64 deletions(-) diff --git a/ps5-kstuff/debug-reader.c b/ps5-kstuff/debug-reader.c index 8218780..979a3da 100644 --- a/ps5-kstuff/debug-reader.c +++ b/ps5-kstuff/debug-reader.c @@ -247,7 +247,6 @@ static void print_metrics(const struct kstuff_metrics* metrics) PRINT_FIELD("emu", metrics->crypto_requests_emulated); PRINT_FIELD("fallback", metrics->crypto_requests_fallback); PRINT_FIELD("fail", metrics->crypto_requests_failed); - PRINT_FIELD("restart", metrics->crypto_requests_restarted); PRINT_FIELD("msg", metrics->crypto_messages_total); PRINT_FIELD("xts_msg", metrics->crypto_messages_xts); PRINT_FIELD("hmac_msg", metrics->crypto_messages_hmac); @@ -259,7 +258,6 @@ static void print_metrics(const struct kstuff_metrics* metrics) PRINT_FIELD("req", metrics->xts_requests); PRINT_FIELD("sectors", metrics->xts_sectors); PRINT_FIELD("run_msg", metrics->xts_run_messages_total); - PRINT_FIELD("skipped", metrics->xts_run_skip_sectors); PRINT_FIELD("direct_runs", metrics->xts_full_direct_runs); PRINT_FIELD("direct_sectors", metrics->xts_full_direct_sectors); PRINT_FIELD("fallback", metrics->xts_full_fallback_sectors); @@ -290,7 +288,6 @@ static void print_metrics(const struct kstuff_metrics* metrics) PRINT_FIELD("hmac_shape", metrics->fpkg_reject_hmac_bad_shape); PRINT_FIELD("other", metrics->fpkg_reject_other_message); PRINT_FIELD("no_emu", metrics->fpkg_request_no_emulation); - PRINT_FIELD("partial", metrics->fpkg_request_partial_emulation); PRINT_FIELD("fpu_fail", metrics->fpkg_request_fpu_enter_fail); tee_putc('\n'); diff --git a/ps5-kstuff/uelf/fpkg.c b/ps5-kstuff/uelf/fpkg.c index eb9d3f3..b10550d 100644 --- a/ps5-kstuff/uelf/fpkg.c +++ b/ps5-kstuff/uelf/fpkg.c @@ -128,8 +128,7 @@ static struct crypto_message_info inspect_crypto_message(const uint64_t msg_data } static struct crypto_message_result handle_hmac_message(uint64_t msg, const uint64_t msg_data[21], - int key_idx, uint64_t bytes_cap, - uint64_t* bytes_handled, + int key_idx, struct crypto_request_cache* cache) { struct crypto_message_result result = unhandled_crypto_message(msg); @@ -138,8 +137,7 @@ static struct crypto_message_result handle_hmac_message(uint64_t msg, const uint return result; uint8_t hash[32] = {0}; - *bytes_handled += msg_data[1]; - if(bytes_cap < *bytes_handled && pfs_hmac_virtual_fpu_held(cache, hash, key_idx, key, msg_data[2], msg_data[1])) + if(pfs_hmac_virtual_fpu_held(cache, hash, key_idx, key, msg_data[2], msg_data[1])) { result.emulated_messages = 1; result.status = -1; @@ -158,7 +156,6 @@ static struct crypto_message_result handle_hmac_message(uint64_t msg, const uint static struct crypto_message_result handle_xts_message(uint64_t msg, const uint64_t msg_data[21], int key_idx, - uint64_t bytes_cap, uint64_t* bytes_handled, struct crypto_request_cache* cache) { struct crypto_message_result result = unhandled_crypto_message(msg); @@ -173,26 +170,11 @@ static struct crypto_message_result handle_xts_message(uint64_t msg, const uint6 uint32_t total_sectors = (uint32_t)msg_data[1]; int is_encrypt = (msg_data[0] & 0x800) >> 11; - uint64_t run_bytes = (uint64_t)total_sectors << 12; - uint64_t skip_bytes = 0; - if(bytes_cap > *bytes_handled) - skip_bytes = bytes_cap - *bytes_handled; - if(skip_bytes >= run_bytes) - skip_bytes = run_bytes; - uint32_t skip_sectors = (uint32_t)(skip_bytes >> 12); - *bytes_handled += run_bytes; - METRIC_ADD(xts_run_skip_sectors, skip_sectors); - - if(skip_sectors < total_sectors) + if(pfs_xts_virtual_fpu_held(cache, dst, src, key_idx, key, start_sector, total_sectors, is_encrypt)) { - if(pfs_xts_virtual_fpu_held(cache, dst + ((uint64_t)skip_sectors << 12), - src + ((uint64_t)skip_sectors << 12), key_idx, key, - start_sector + skip_sectors, total_sectors - skip_sectors, is_encrypt)) - { - result.emulated_messages = result.total_messages; - result.status = -1; - return result; - } + result.emulated_messages = 1; + result.status = -1; + return result; } result.emulated_messages = 1; @@ -209,7 +191,7 @@ static inline uint64_t rdtsc(void) } */ -static int handle_crypto_request(uint64_t* regs, uint64_t bytes_handled) +static int handle_crypto_request(uint64_t* regs) { METRIC_TIME_START(start_cycles); // uint64_t start_time = rdtsc(); @@ -218,7 +200,6 @@ static int handle_crypto_request(uint64_t* regs, uint64_t bytes_handled) int total_status = 0; int handled = 0; int fpu_entered = 0; - uint64_t new_bytes_handled = 0; METRIC_INC(crypto_requests_total); uint64_t start = (FWVER >= 0x800) ? regs[RBX] : regs[R14]; @@ -252,30 +233,13 @@ static int handle_crypto_request(uint64_t* regs, uint64_t bytes_handled) struct crypto_message_result result; if(msg_info.kind == CRYPTO_MESSAGE_XTS) - result = handle_xts_message(msg, msg_data, msg_info.key_idx, bytes_handled, &new_bytes_handled, &s_crypto_request_cache); + result = handle_xts_message(msg, msg_data, msg_info.key_idx, &s_crypto_request_cache); else if(msg_info.kind == CRYPTO_MESSAGE_HMAC) - result = handle_hmac_message(msg, msg_data, msg_info.key_idx, bytes_handled, &new_bytes_handled, &s_crypto_request_cache); + result = handle_hmac_message(msg, msg_data, msg_info.key_idx, &s_crypto_request_cache); else result = unhandled_crypto_message(msg); int status = result.status; - if (status == EINTR) // partial decrypt, need to restart the syscall - { - METRIC_INC(crypto_requests_restarted); - uint64_t frame[6] = { - MKTRAP(TRAP_FPKG, 2), 0, 0, 0, 0, - new_bytes_handled, - }; - if(push_stack_checked(regs, frame, sizeof(frame))) - { - total_status = -1; - break; - } - regs[RIP] = (uint64_t)doreti_iret; - handled = 1; - goto exit; - } - total += result.total_messages; if (status != ENOSYS) @@ -294,7 +258,6 @@ static int handle_crypto_request(uint64_t* regs, uint64_t bytes_handled) { // not all requests successfully emulated // we can't run only part of the request, so just report failure - METRIC_INC(fpkg_request_partial_emulation); total_status = -1; } @@ -325,7 +288,7 @@ int try_handle_fpkg_trap(uint64_t* regs) { if(regs[RIP] == (uint64_t)sceSblServiceCryptAsync_deref_singleton) { - if(handle_crypto_request(regs, 0)) + if(handle_crypto_request(regs)) observe_current_syscall_emulated(); else { @@ -444,14 +407,6 @@ void handle_fpkg_trap(uint64_t* regs, uint32_t trapno) regs[RIP] = frame[11]; regs[RAX] = 0; } - else if(trapno == 2) - { - uint64_t frame[6]; - if(pop_stack_checked(regs, frame, sizeof(frame))) - return; - regs[RIP] = (uint64_t)sceSblServiceCryptAsync_deref_singleton; - handle_crypto_request(regs, frame[5]); - } } static const uint64_t dbgregs_for_nmount[6] = { diff --git a/ps5-kstuff/uelf/shared_area.h b/ps5-kstuff/uelf/shared_area.h index a9d1b6e..0c78048 100644 --- a/ps5-kstuff/uelf/shared_area.h +++ b/ps5-kstuff/uelf/shared_area.h @@ -167,7 +167,6 @@ struct kstuff_metrics uint64_t crypto_requests_emulated; uint64_t crypto_requests_fallback; uint64_t crypto_requests_failed; - uint64_t crypto_requests_restarted; uint64_t crypto_messages_total; uint64_t crypto_messages_xts; uint64_t crypto_messages_hmac; @@ -178,7 +177,6 @@ struct kstuff_metrics uint64_t xts_requests; uint64_t xts_sectors; uint64_t xts_run_messages_total; - uint64_t xts_run_skip_sectors; uint64_t xts_full_direct_runs; uint64_t xts_full_direct_sectors; @@ -217,7 +215,6 @@ struct kstuff_metrics uint64_t fpkg_reject_hmac_bad_shape; uint64_t fpkg_reject_other_message; uint64_t fpkg_request_no_emulation; - uint64_t fpkg_request_partial_emulation; uint64_t fpkg_request_fpu_enter_fail; uint64_t shared_area_snapshots; @@ -302,14 +299,14 @@ extern struct shared_area_layout shared_area; #define METRIC_MAX(field, value) do { } while(0) #endif -_Static_assert(sizeof(struct kstuff_metrics) == 1536, "unexpected metrics size"); +_Static_assert(sizeof(struct kstuff_metrics) == 1512, "unexpected metrics size"); _Static_assert(sizeof(struct kstuff_word_log) == 264, "unexpected word log size"); _Static_assert(sizeof(struct kstuff_ioctl_com_entry) == 24, "unexpected ioctl com entry size"); _Static_assert(sizeof(struct kstuff_ioctl_com_table) == 3088, "unexpected ioctl com table size"); _Static_assert(sizeof(struct kstuff_msg_log) == 504, "unexpected message log size"); -_Static_assert(sizeof(struct kstuff_snapshot) == 5408, "unexpected snapshot size"); +_Static_assert(sizeof(struct kstuff_snapshot) == 5384, "unexpected snapshot size"); #if KSTUFF_OBS -_Static_assert(sizeof(struct shared_area_layout) == 7440, "unexpected shared_area size"); +_Static_assert(sizeof(struct shared_area_layout) == 7416, "unexpected shared_area size"); #else _Static_assert(sizeof(struct shared_area_layout) == 2048, "unexpected non-OBS shared_area size"); #endif