diff --git a/crt/crt.c b/crt/crt.c index cba5739..d726661 100644 --- a/crt/crt.c +++ b/crt/crt.c @@ -11,10 +11,14 @@ #define ERR_CRT_UNKNOWN 0xDEAD0000 #define ERR_CRT_LIBKERNEL_INIT_FAIL 0xDEAD0001 #define ERR_CRT_MODULE_INIT_FAIL 0xDEAD0002 +#define ERR_CRT_SYSCALL_INIT_FAIL 0xDEAD0003 extern int payload_main(struct payload_args *args); +extern int syscall_init(struct payload_args *args); extern int libc_init(); extern int libkernel_init(); +extern int syscall_init(); + void __ps5sdk_crt_start(struct payload_args *args) { @@ -23,7 +27,12 @@ void __ps5sdk_crt_start(struct payload_args *args) // Dlsym must be initialized first to resolve everything else init_dlsym(args->dlsym); - // Kickstart libkernel and libc + // Kickstart syscall, libkernel and libc + if (syscall_init(args) != 0) { + rv = ERR_CRT_SYSCALL_INIT_FAIL; + goto out; + } + if (libkernel_init() != 0) { rv = ERR_CRT_LIBKERNEL_INIT_FAIL; goto out; diff --git a/crt/syscall.c b/crt/syscall.c new file mode 100644 index 0000000..adb37c1 --- /dev/null +++ b/crt/syscall.c @@ -0,0 +1,33 @@ +/***************************************************** + * PS5 SDK - Syscall + * Implements the syscall() function by setting up + * registers manually, then jumping to a syscall + * instruction in libkernel. + ****************************************************/ + +#include + +static __attribute__ ((used)) long ptr_syscall; + +asm(".intel_syntax noprefix\n" + ".global syscall\n" + ".type syscall @function\n" + "syscall:\n" + " mov rax, rdi\n" // sysno + " mov rdi, rsi\n" // arg1 + " mov rsi, rdx\n" // arg2 + " mov rdx, rcx\n" // arg3 + " mov r10, r8\n" // arg4 + " mov r8, r9\n" // arg5 + " mov r9, qword ptr [rsp + 8]\n" // arg6 + " jmp qword ptr [rip + ptr_syscall]\n" // syscall + " ret\n" + ); + +int syscall_init(const struct payload_args *args) { + if(args->dlsym(0x2001, "getpid", &ptr_syscall)) { + return -1; + } + ptr_syscall += 0xa; + return 0; +}