ps5-kstuff: add nmount & sceSblServiceCrypt hooks

This can be used to decrypt the inner PFS using custom-derived keys. Key derivation using the "ypkg" key is also implemented.

External libraries used: BearSSL for RSA & SHA256HMAC, libtomcrypt for AES/XTS.
This commit is contained in:
Sergey Lisov committed 2023-10-02 00:54:53 +03:00
1 parent 74f7752b61
commit 04fa6028eb
21 files changed
+813 -18

No files matched your search

+6
View File
@@ -16,3 +16,9 @@
[submodule "linux/ps4-kexec-900"]
path = linux/ps4-kexec-900
url = https://github.com/sleirsgoevy/ps4-kexec
[submodule "ps5-kstuff/BearSSL"]
path = ps5-kstuff/BearSSL
url = https://www.bearssl.org/git/BearSSL
[submodule "ps5-kstuff/libtomcrypt"]
path = ps5-kstuff/libtomcrypt
url = https://github.com/libtom/libtomcrypt
Submodule ps5-kstuff/BearSSL added at 79c060eea3.
+8 -2
View File
@@ -32,5 +32,11 @@ 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
gcc -Wl,-Bsymbolic -Wl,-gc-sections -ffunction-sections -fdata-sections -O0 -g -isystem ../freebsd-headers -nostdinc -nostdlib -mgeneral-regs-only -fno-stack-protector -fPIE -fPIC -shared -ffreestanding -fno-builtin uelf/crt.o uelf/*.c -o uelf/uelf
uelf/uelf: uelf/*.c uelf/*.h structs.h uelf/crt.o BearSSL/build/libbearssl.a libtomcrypt/libtomcrypt.a
gcc -Wl,-Bsymbolic -Wl,-gc-sections -ffunction-sections -fdata-sections -O0 -g -isystem ../freebsd-headers -nostdinc -nostdlib -mgeneral-regs-only -fno-stack-protector -fPIE -fPIC -shared -fvisibility=hidden -ffreestanding uelf/crt.o uelf/*.c -L BearSSL/build -lbearssl -L libtomcrypt -ltomcrypt -o uelf/uelf
BearSSL/build/libbearssl.a: build_bearssl.sh overrides.h
bash build_bearssl.sh
libtomcrypt/libtomcrypt.a: build_libtomcrypt.sh overrides.h
bash build_libtomcrypt.sh
+2
View File
@@ -0,0 +1,2 @@
cd BearSSL
for i in clean "lib -j$(nproc)"; do make CC='gcc -nostdlib -nostdinc -isystem /proc/'$$'/cwd/../../freebsd-headers -isystem /nix/store/b7hvml0m3qmqraz1022fwvyyg6fc1vdy-gcc-12.2.0/lib/gcc/x86_64-unknown-linux-gnu/12.2.0/include -O0 -g -ffreestanding -mgeneral-regs-only -ffunction-sections -fdata-sections -fvisibility=hidden -include /proc/'$$'/cwd/../overrides.h' $i; done
+2
View File
@@ -0,0 +1,2 @@
cd libtomcrypt
for i in clean -j$(nproc); do make CC='gcc -nostdlib -nostdinc -isystem /proc/'$$'/cwd/../../freebsd-headers -isystem /nix/store/b7hvml0m3qmqraz1022fwvyyg6fc1vdy-gcc-12.2.0/lib/gcc/x86_64-unknown-linux-gnu/12.2.0/include -O0 -g -ffreestanding -mgeneral-regs-only -ffunction-sections -fdata-sections -fPIE -fPIC -fvisibility=hidden -include /proc/'$$'/cwd/../overrides.h' $i; done
+351 -9
View File
@@ -202,11 +202,14 @@ extern char uek_end[];
asm(".section .text\nkekcall:\nmov 8(%rsp), %rax\njmp *p_kekcall(%rip)");
int kekcall(uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint64_t e, uint64_t f, uint64_t nr);
uint64_t kekcall(uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint64_t e, uint64_t f, uint64_t nr);
#define KEKCALL_GETPPID 0x000000027
#define KEKCALL_READ_DR 0x100000027
#define KEKCALL_WRITE_DR 0x200000027
#define KEKCALL_GETPPID 0x000000027
#define KEKCALL_READ_DR 0x100000027
#define KEKCALL_WRITE_DR 0x200000027
#define KEKCALL_RDMSR 0x300000027
#define KEKCALL_REMOTE_SYSCALL 0x500000027
#define KEKCALL_CHECK 0xffffffff00000027
void* p_kekcall;
void* dlsym(void*, const char*);
@@ -276,7 +279,6 @@ void build_uelf_cr3(uint64_t uelf_cr3, void* uelf_base[2])
int main(void* ds, int a, int b, uintptr_t c, uintptr_t d)
{
r0gdb_init(ds, a, b, c, d);
dbg_enter();
uint64_t percpu_ist4[NCPUS];
for(int cpu = 0; cpu < NCPUS; cpu++)
copyout(&percpu_ist4[cpu], TSS(cpu)+28+4*8, 8);
@@ -286,6 +288,7 @@ int main(void* ds, int a, int b, uintptr_t c, uintptr_t d)
uint64_t int13_handler;
copyout(&int13_handler, IDT+16*13, 2);
copyout((char*)&int13_handler + 2, IDT+16*13+6, 6);
dbg_enter();
gdb_remote_syscall("write", 3, 0, (uintptr_t)1, (uintptr_t)"allocating kernel memory... ", (uintptr_t)28);
for(int i = 0; i < 0x300; i += 2)
r0gdb_kmalloc(0x100);
@@ -296,11 +299,16 @@ int main(void* ds, int a, int b, uintptr_t c, uintptr_t d)
mem_blocks[i+1] = (mem_blocks[i] ? mem_blocks[i] + (1<<23) : 0);
}
gdb_remote_syscall("write", 3, 0, (uintptr_t)1, (uintptr_t)"done\n", (uintptr_t)5);
uint64_t shared_area = (uint64_t)kmalloc(8192);
shared_area = ((shared_area - 1) | 4095) + 1;
kmemzero((void*)shared_area, 4096);
shared_area = virt2phys(shared_area) + (1ull << 39);
volatile int zero = 0; //hack to force runtime calculation of string pointers
const char* symbols[] = {
"add_rsp_iret"+zero,
"copyin"+zero,
"copyout"+zero,
"crypt_message_resolve"+zero,
"decryptSelfBlock_epilogue"+zero,
"decryptSelfBlock_watchpoint"+zero,
"decryptSelfBlock_watchpoint_lr"+zero,
@@ -336,11 +344,13 @@ int main(void* ds, int a, int b, uintptr_t c, uintptr_t d)
"rdmsr_end"+zero,
"rdmsr_start"+zero,
"rep_movsb_pop_rbp_ret"+zero,
"sceSblServiceCryptAsync_deref_singleton"+zero,
"sceSblServiceIsLoadable2"+zero,
"sceSblServiceMailbox"+zero,
"sceSblServiceMailbox_lr_decryptSelfBlock"+zero,
"sceSblServiceMailbox_lr_loadSelfSegment"+zero,
"sceSblServiceMailbox_lr_verifyHeader"+zero,
"shared_area"+zero,
"soo_ioctl"+zero,
"syscall_after"+zero,
"syscall_before"+zero,
@@ -357,6 +367,7 @@ int main(void* ds, int a, int b, uintptr_t c, uintptr_t d)
kdata_base - 0x9cf853, // add_rsp_iret
kdata_base - 0x9908e0, // copyin
kdata_base - 0x990990, // copyout
kdata_base - 0x479d60, // crypt_message_resolve
kdata_base - 0x8a52c3, // decryptSelfBlock_epilogue
kdata_base - 0x2cc88e, // decryptSelfBlock_watchpoint
kdata_base - 0x8a538a, // decryptSelfBlock_watchpoint_lr
@@ -392,11 +403,13 @@ int main(void* ds, int a, int b, uintptr_t c, uintptr_t d)
kdata_base - 0x9d6cf9, // rdmsr_end
kdata_base - 0x9d6d02, // rdmsr_start
kdata_base - 0x990a55, // rep_movsb_pop_rbp_ret
kdata_base - 0x8ed902, // sceSblServiceCryptAsync_deref_singleton
kdata_base - 0x8a5c40, // sceSblServiceIsLoadable2
kdata_base - 0x6824c0, // sceSblServiceMailbox
kdata_base - 0x8a5014, // sceSblServiceMailbox_lr_decryptSelfBlock
kdata_base - 0x8a5541, // sceSblServiceMailbox_lr_loadSelfSegment
kdata_base - 0x8a58bc, // sceSblServiceMailbox_lr_verifyHeader
shared_area, // shared_area
kdata_base - 0x96eb98, // soo_ioctl
kdata_base - 0x8022ee, // syscall_after
kdata_base - 0x802311, // syscall_before
@@ -424,6 +437,7 @@ int main(void* ds, int a, int b, uintptr_t c, uintptr_t d)
uint64_t uelf_bases[NCPUS];
uint64_t kelf_bases[NCPUS];
uint64_t kelf_entries[NCPUS];
uint64_t uelf_cr3s[NCPUS];
for(int cpu = 0; cpu < NCPUS; cpu++)
{
char buf[] = "loading on cpu ..\n";
@@ -451,6 +465,7 @@ int main(void* ds, int a, int b, uintptr_t c, uintptr_t d)
char* uelf = load_kelf(uek, symbols, values, uelf_base, &uelf_entry, 0x400000);
uintptr_t uelf_cr3 = (uintptr_t)kmalloc(24576);
uelf_cr3 = ((uelf_cr3 + 4095) | 4095) - 4095;
uelf_cr3s[cpu] = uelf_cr3;
values[uelf_cr3_idx] = virt2phys(uelf_cr3);
values[uelf_entry_idx] = (uintptr_t)uelf_entry - (uintptr_t)uelf_base[0] + 0x400000;
void* entry = 0;
@@ -480,16 +495,343 @@ int main(void* ds, int a, int b, uintptr_t c, uintptr_t d)
kmemcpy((char*)(IDT+16*2), (char*)&iret, 2);
kmemcpy((char*)(IDT+16*2+6), (char*)&iret+2, 6);
//kmemzero((char*)(IDT+16*1), 16);
gdb_remote_syscall("write", 3, 0, (uintptr_t)1, (uintptr_t)"done\npatching sysentvec... ", (uintptr_t)27);
copyin(kdata_base + 0xd11bb8 + 14, &(const uint16_t[1]){0xdeb7}, 2);
copyin(kdata_base + 0xd11d30 + 14, &(const uint16_t[1]){0xdeb7}, 2);
gdb_remote_syscall("write", 3, 0, (uintptr_t)1, (uintptr_t)"done\napplying kdata patches... ", (uintptr_t)31);
copyin(kdata_base + 0xd11bb8 + 14, &(const uint16_t[1]){0xdeb7}, 2); //native sysentvec
copyin(kdata_base + 0xd11d30 + 14, &(const uint16_t[1]){0xdeb7}, 2); //ps4 sysentvec
copyin(kdata_base + 0x2e31830 + 11*8 + 2*8 + 6, &(const uint16_t[1]){0xdeb7}, 2); //crypt xts
copyin(kdata_base + 0x2e31830 + 11*8 + 9*8 + 6, &(const uint16_t[1]){0xdeb7}, 2); //crypt xts
gdb_remote_syscall("write", 3, 0, (uintptr_t)1, (uintptr_t)"done\n", (uintptr_t)5);
p_kekcall = (char*)dlsym((void*)0x2001, "getpid") + 7;
//restore the gdb_stub's SIGTRAP handler
struct sigaction sa;
sigaction(SIGBUS, 0, &sa);
sigaction(SIGTRAP, &sa, 0);
copyin(IDT+16*179+5, "\x89", 1);
sigaction(SIGPIPE, &sa, 0);
copyin(IDT+16*9+5, "\x8e", 1);
copyin(IDT+16*179+5, "\x8e", 1);
asm volatile("ud2");
return 0;
}
/*
TEMPORARY CODE
This should either go to some separate place ("utils.c" in r0gdb perhaps), or be removed completely.
*/
#define sysctl __sysctl
#include <sys/syscall.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/thr.h>
#include <sys/sysctl.h>
#include <machine/sysarch.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdarg.h>
#define SYS_mdbg_call 573
#define SYS_dynlib_dlsym 591
#define SYS_dynlib_get_info_ex 608
void inject_payload(int pid)
{
if(kekcall(0, 0, 0, 0, 0, 0, KEKCALL_CHECK))
return;
static int sock = -1;
if(sock < 0)
{
sock = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in sin = {
.sin_family = AF_INET,
.sin_addr = {.s_addr = 0},
.sin_port = __builtin_bswap16(9020),
};
bind(sock, (void*)&sin, sizeof(sin));
listen(sock, 1);
}
int sock2 = accept(sock, 0, 0);
char* buf = mmap(0, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
size_t sz = 0;
size_t cap = 16384;
for(;;)
{
if(sz == cap)
{
cap *= 2;
char* buf2 = mmap(0, cap, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
for(size_t i = 0; i < sz; i++)
buf2[i] = buf[i];
munmap(buf, sz);
buf = buf2;
}
ssize_t chk = read(sock2, buf+sz, cap-sz);
if(chk <= 0)
break;
sz += chk;
}
static const char shellcode[] = {
0x55, //push rbp
0x48, 0x8b, 0xfc, //mov rdi, rsp
0x31, 0xf6, //xor esi, esi
0x48, 0xba, 0, 0, 0, 0, 0, 0, 0, 0, //movabs rdx, ...
0x48, 0xb9, 0, 0, 0, 0, 0, 0, 0, 0, //movabs rcx, ...
0x48, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, //movabs rax, ...
0xff, 0xd0, //call rax
0x31, 0xff, //xor edi, edi
0xb8, SYS_thr_exit&255, SYS_thr_exit>>8, 0, 0,
0xff, 0x25, 0, 0, 0, 0, //jmp qword [rip]
0, 0, 0, 0, 0, 0, 0, 0,
};
if(cap - sz < sizeof(shellcode))
{
cap *= 2;
char* buf2 = mmap(0, cap, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
for(size_t i = 0; i < sz; i++)
buf2[i] = buf[i];
munmap(buf, sz);
buf = buf2;
}
size_t shellcode_offset = sz;
for(size_t i = 0; i < sizeof(shellcode); i++)
buf[sz++] = shellcode[i];
uint64_t target_pointer = kekcall(pid, SYS_mmap, (uint64_t)(const uint64_t[6]){0, sz, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0}, 0, 0, 0, KEKCALL_REMOTE_SYSCALL);
if(target_pointer + 1 <= 4096)
asm volatile("ud2");
uint64_t target_stack = kekcall(pid, SYS_mmap, (uint64_t)(const uint64_t[6]){0, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0}, 0, 0, 0, KEKCALL_REMOTE_SYSCALL);
if(target_stack + 1 <= 4096)
asm volatile("ud2");
if(kekcall(pid, SYS_mprotect, (uint64_t)(const uint64_t[6]){target_pointer, sz, PROT_READ|PROT_WRITE|PROT_EXEC}, 0, 0, 0, KEKCALL_REMOTE_SYSCALL))
asm volatile("ud2");
*(uint64_t*)(buf+shellcode_offset+8) = target_pointer;
kekcall(pid, SYS_dynlib_dlsym, (uint64_t)(const uint64_t[6]){0x2001, (uint64_t)"sceKernelDlsym", (uint64_t)(buf+shellcode_offset+18)}, 0, 0, 0, KEKCALL_REMOTE_SYSCALL);
if(!*(uint64_t*)(buf+shellcode_offset+18))
asm volatile("ud2");
kekcall(pid, SYS_dynlib_dlsym, (uint64_t)(const uint64_t[6]){0x2001, (uint64_t)"pthread_create", (uint64_t)(buf+shellcode_offset+28)}, 0, 0, 0, KEKCALL_REMOTE_SYSCALL);
if(!*(uint64_t*)(buf+shellcode_offset+28))
asm volatile("ud2");
kekcall(pid, SYS_dynlib_dlsym, (uint64_t)(const uint64_t[6]){0x2001, (uint64_t)"getpid", (uint64_t)(buf+shellcode_offset+51)}, 0, 0, 0, KEKCALL_REMOTE_SYSCALL);
if(!*(uint64_t*)(buf+shellcode_offset+51))
asm volatile("ud2");
*(uint64_t*)(buf+shellcode_offset+51) += 7;
{
uint64_t arg1[4] = {1, 0x13};
uint64_t arg2[8] = {pid, target_pointer, (uint64_t)buf, sz};
uint64_t arg3[4] = {0};
if(kekcall((uint64_t)arg1, (uint64_t)arg2, (uint64_t)arg3, 0, 0, 0, SYS_mdbg_call))
asm volatile("ud2");
}
{
uint64_t arg1[4] = {1, 0x13};
uint64_t arg2[8] = {pid, target_stack+16, (uint64_t)&target_stack, 8};
uint64_t arg3[4] = {0};
if(kekcall((uint64_t)arg1, (uint64_t)arg2, (uint64_t)arg3, 0, 0, 0, SYS_mdbg_call))
asm volatile("ud2");
}
{
uint64_t arg1[4] = {1, 0x13};
uint64_t arg2[8] = {pid, target_stack+0x1a8, (uint64_t)&target_stack, 8};
uint64_t arg3[4] = {0};
if(kekcall((uint64_t)arg1, (uint64_t)arg2, (uint64_t)arg3, 0, 0, 0, SYS_mdbg_call))
asm volatile("ud2");
}
munmap(buf, sz);
{
struct thr_param param = {0};
long x, y;
param.start_func = (void*)(target_pointer+shellcode_offset);
param.stack_base = (void*)target_stack;
param.stack_size = 65536;
param.tls_size = 1;
param.arg = 0;
if(kekcall(pid, SYS_sysarch, (uint64_t)(const uint64_t[6]){AMD64_GET_FSBASE, (uint64_t)&param.tls_base}, 0, 0, 0, KEKCALL_REMOTE_SYSCALL))
asm volatile("ud2");
if(kekcall(pid, SYS_thr_new, (uint64_t)(const uint64_t[6]){(uint64_t)&param, sizeof(param)}, 0, 0, 0, KEKCALL_REMOTE_SYSCALL))
asm volatile("ud2");
}
}
void* klog_server(void* arg)
{
int sock = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in sin = {
.sin_family = AF_INET,
.sin_addr = { .s_addr = 0 },
.sin_port = 0x0e27, //9998
};
bind(sock, (void*)&sin, sizeof(sin));
listen(sock, 1);
new_conn:
int sock2 = accept(sock, NULL, NULL);
char buf[512];
int fd1 = open("/dev/klog", O_RDONLY);
for(;;)
{
ssize_t chk = read(fd1, buf, sizeof(buf));
if(chk < 0)
break;
char* p = buf;
while(chk > 0)
{
ssize_t chk1 = write(sock2, p, chk);
if(chk1 <= 0)
{
close(sock2);
goto new_conn;
}
chk -= chk1;
p += chk1;
}
}
}
int find_proc(const char* name)
{
char buf[1097] = {0};
for(int pid = 1; pid < 1024; pid++)
{
size_t sz = 1096;
int key[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
sysctl(key, 4, buf, &sz, 0, 0);
const char* a = buf + 447;
const char* b = name;
while(*a && *a++ == *b++);
if(!*a && !*b)
return pid;
}
return -1;
}
static int64_t do_remote_syscall(int pid, int sysc, ...)
{
static uint64_t args_p = 0;
if(!args_p)
args_p = r0gdb_kmalloc(48);
uint64_t args[6];
va_list l;
va_start(l, sysc);
for(int i = 0; i < 6; i++)
args[i] = va_arg(l, uint64_t);
va_end(l);
uint64_t proc;
uint64_t target = 0;
copyout(&proc, kdata_base+0x27edcb8, 8);
while(proc)
{
uint32_t pid1;
copyout(&pid1, proc+0xbc, 4);
if(pid1 == pid)
{
target = proc;
break;
}
copyout(&proc, proc, 8);
}
if(!target)
asm volatile("ud2");
uint64_t target_thread;
copyout(&target_thread, target+16, 8);
copyin(args_p, args, 48);
uint64_t syscall_fn;
copyout(&syscall_fn, kdata_base+0x1709c0+48*sysc+8, 8);
int err = r0gdb_kfncall(syscall_fn, target_thread, args_p);
if(err)
return -err;
int64_t ans;
copyout(&ans, target_thread+0x408, 8);
return ans;
}
struct module_segment
{
uint64_t addr;
uint32_t size;
uint32_t flags;
};
struct module_info_ex
{
size_t st_size;
char name[256];
int id;
uint32_t tls_index;
uint64_t tls_init_addr;
uint32_t tls_init_size;
uint32_t tls_size;
uint32_t tls_offset;
uint32_t tls_align;
uint64_t init_proc_addr;
uint64_t fini_proc_addr;
uint64_t reserved1;
uint64_t reserved2;
uint64_t eh_frame_hdr_addr;
uint64_t eh_frame_addr;
uint32_t eh_frame_hdr_size;
uint32_t eh_frame_size;
struct module_segment segments[4];
uint32_t segment_count;
uint32_t ref_count;
};
static uint64_t shellcore_args_base;
static void temp_patch_shellcore(int do_lk)
{
int pid = find_proc("SceShellCore");
struct module_info_ex mod_info;
mod_info.st_size = sizeof(mod_info);
do_remote_syscall(pid, SYS_dynlib_get_info_ex, 0, 0, &mod_info);
uint64_t shellcore_base = mod_info.eh_frame_hdr_addr - 0x13c0000;
mod_info.st_size = sizeof(mod_info);
do_remote_syscall(pid, SYS_dynlib_get_info_ex, 0x2001, 0, &mod_info);
uint64_t libkernel_base = mod_info.eh_frame_hdr_addr - 0x44000;
shellcore_args_base = do_remote_syscall(pid, SYS_mmap, 0, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
struct
{
uint64_t addr;
void* data;
size_t sz;
} patches[] = {
{shellcore_base+0x974fe0, "\x31\xc0\xc3", 3},
{shellcore_base+0x974bb0, "\x31\xc0\xc3", 3},
{shellcore_base+0x5307f9, "\xeb\x04", 2},
{shellcore_base+0x26f35c, "\xeb\x04", 2},
{shellcore_base+0x54e1f0, "\xeb", 1},
{shellcore_base+0x536e1d, "\x90\xe9", 2},
{libkernel_base+0x18f0, "\x48\xb8\xef\xbe\xad\xde\xef\xbe\xad\xde\x48\x89\x38\x48\x89\x70\x08\x48\x89\x50\x10\xeb\xfe", do_lk ? 23 : 0},
{libkernel_base+0x18f2, &shellcore_args_base, do_lk ? 8 : 0},
};
for(int i = 0; i < sizeof(patches) / sizeof(*patches); i++)
{
uint64_t arg1[4] = {1, 0x13};
uint64_t arg2[8] = {pid, patches[i].addr, (uint64_t)patches[i].data, patches[i].sz};
uint64_t arg3[4] = {0};
mdbg_call_20(arg1, arg2, arg3);
}
}
static void* get_nmount_args(void)
{
int pid = find_proc("SceShellCore");
uint64_t args[3];
#define READ(dst, src, sz) (mdbg_call_20((uint64_t[4]){1, 0x12}, (uint64_t[8]){pid, (src), (uint64_t)(dst), (sz)}, (uint64_t[4]){}))
READ(args, shellcore_args_base, 24);
uint64_t* ptrs = malloc(sizeof(*ptrs) * args[1] * 2);
READ(ptrs, args[0], sizeof(*ptrs) * args[1] * 2);
for(int i = 0; i < args[1]; i++)
{
uint64_t ptr = ptrs[2*i];
uint64_t sz = ptrs[2*i+1];
char* buf = malloc(sz+1);
READ(buf, ptr, sz);
buf[sz] = 0;
ptrs[2*i] = (uint64_t)buf;
}
#undef READ
return ptrs;
}
int my_nmount(void* a, int b, int c)
{
return kekcall((uintptr_t)a, b, c, 0, 0, 0, SYS_nmount);
}
+15
View File
@@ -0,0 +1,15 @@
/* disable use of POSIX functions */
#undef __linux__
#undef __unix__
/* disable XMM intrinsics */
#undef __x86_64__
/* for BearSSL */
#define BR_64 1
#define BR_INT128 1
/* for libtomcrypt */
#define ARGTYPE 3
#define TAB_SIZE 1
#define LTC_NO_TEST 1
+1
View File
@@ -25,6 +25,7 @@
%define p_pid 0xbc
%define pcb_fsbase 0x40
%define pcb_gsbase 0x48
%define pcb_flags 0x100
+28
View File
@@ -3,6 +3,8 @@ use64
global yield
global memcpy
global memset
global memmove
global cr3_phys
global trap_frame
global wrmsr_args
@@ -25,6 +27,32 @@ mov rcx, rdx
rep movsb
ret
memset:
movzx eax, sil
mov rsi, rdi
mov rcx, rdx
rep stosb
mov rax, rsi
ret
memmove:
mov rax, rdi
sub rax, rsi
cmp rax, rdx
jae memcpy
test rax, rax
je .mov_rax_rdi_ret
lea rdi, [rdi+rdx-1]
lea rsi, [rsi+rdx-1]
mov rcx, rdx
std
rep movsb
cld
inc rdi
.mov_rax_rdi_ret:
mov rax, rdi
ret
; rdi = trap_frame
; rsi = cr3 of caller
; rdx = our cr3 (currently unused)
+44
View File
@@ -0,0 +1,44 @@
#include "fakekeys.h"
#include <stdint.h>
#include <string.h>
extern struct
{
uint64_t bitmask;
char pad[24];
char key_data[63][32];
} shared_area;
int register_fake_key(const char key_data[32])
{
uint64_t mask, mask1;
mask = __atomic_load_n(&shared_area.bitmask, __ATOMIC_ACQUIRE);
do
{
mask1 = (mask | (mask + 1)) & ((1ull << 63) - 1);
if(mask1 == mask)
return -1;
}
while(!__atomic_compare_exchange_n(&shared_area.bitmask, &mask, mask1, 1, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE));
int key_idx = 63 - __builtin_clzll(mask ^ mask1);
memcpy(shared_area.key_data[key_idx], key_data, 32);
return key_idx;
}
void unregister_fake_key(int key_id)
{
uint64_t mask, mask1;
mask = __atomic_load_n(&shared_area.bitmask, __ATOMIC_ACQUIRE);
do
mask1 = mask & ~(1ull << key_id);
while(!__atomic_compare_exchange_n(&shared_area.bitmask, &mask, mask1, 1, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE));
}
int get_fake_key(int key_id, char key_data[32])
{
uint64_t mask = __atomic_load_n(&shared_area.bitmask, __ATOMIC_ACQUIRE);
if(!(mask & (1ull << key_id)))
return 0;
memcpy(key_data, shared_area.key_data[key_id], 32);
return 1;
}
+5
View File
@@ -0,0 +1,5 @@
#pragma once
int register_fake_key(const char key_data[32]);
void unregister_fake_key(int key_id);
int get_fake_key(int key_id, char key_data[32]);
+188
View File
@@ -0,0 +1,188 @@
#include <string.h>
#include "fpkg.h"
#include "utils.h"
#include "traps.h"
#include "log.h"
#include "pfs_crypto.h"
#include "fakekeys.h"
extern char sceSblServiceMailbox[];
extern char sceSblServiceCryptAsync_deref_singleton[];
extern char crypt_message_resolve[];
extern char doreti_iret[];
extern char kdata_base[];
#define IDX_TO_HANDLE(x) (0x13374100 | ((uint8_t)((x)+1)))
#define HANDLE_TO_IDX(x) ((((x) & 0xffffff00) == 0x13374100 ? ((int)(uint8_t)(x)) : (int)0) - 1)
static void crypto_request_emulated(uint64_t* regs, uint64_t msg, uint32_t status)
{
uint64_t frame[7] = {
(uint64_t)doreti_iret,
MKTRAP(TRAP_FPKG, 1), 0, 0, 0, 0,
0
};
push_stack(regs, frame, sizeof(frame));
regs[RIP] = (uint64_t)crypt_message_resolve;
regs[RDI] = msg;
regs[RSI] = status;
}
static int handle_crypto_request(uint64_t* regs)
{
uint64_t dbgregs[6] = {0};
read_dbgregs(dbgregs);
//if(dbgregs[0] == 0x1337)
{
//uint64_t req = regs[R13];
uint64_t msg = regs[R14];
/*if(msg != kpeek64(req))
{
log_word(0xdead0008dead0008);
log_word(req);
log_word(msg);
return 0;
}*/
uint64_t msg_data[32];
copy_from_kernel(msg_data, msg, sizeof(msg_data));
if((msg_data[0] & 0x7fffffff) == 0x9132000) // SHA256HMAC with key handle
{
int idx = HANDLE_TO_IDX(msg_data[20]);
//log_word(0xfee10006dead0000|(uint16_t)idx);
if(idx < 0)
return 0;
uint8_t key[32];
if(!get_fake_key(idx, key))
return 0;
if(msg_data[3] != msg_data[1] * 8)
return 0;
//log_word(0xdead0006dead0007);
uint8_t hash[32] = {0};
if(pfs_hmac_virtual(hash, key, msg_data[2], msg_data[1]))
{
crypto_request_emulated(regs, msg, -1);
return 1;
}
/*for(int i = 0; i < 4; i++)
log_word(*(uint64_t*)(hash+8*i));*/
copy_to_kernel(msg+32, hash, 32);
crypto_request_emulated(regs, msg, 0);
return 1;
/*for(int i = 0; i < 16; i++)
{
uint8_t tmp = key[i];
key[i] = key[31-i];
key[31-i] = tmp;
}
kpoke64(msg, msg_data[0] & ~(1ull << 20));
copy_to_kernel(msg+160, key, 32);
for(int i = 32; i < 256; i += 8)
kpoke64(msg+i, 0x100000001);*/
}
else if((msg_data[0] & 0x7ffff7ff) == 0x2108000) // AES-XTS decrypt/encrypt with key handle
{
int idx = HANDLE_TO_IDX(msg_data[5]);
//log_word(0xfee10006dead0100|(uint16_t)idx);
if(idx < 0)
return 0;
uint8_t key[32];
if(!get_fake_key(idx, key))
return 0;
if(pfs_xts_virtual(msg_data[3], msg_data[2], key, msg_data[4], msg_data[1], (msg_data[0] & 0x800) >> 11))
crypto_request_emulated(regs, msg, -1);
else
crypto_request_emulated(regs, msg, 0);
return 1;
/*kpoke64(msg, msg_data[0] & ~(1ull << 20));
copy_to_kernel(msg+40, key, 32);*/
}
/*log_word(0xdead0006dead0006);
log_word(msg);
for(int i = 0; i < 32; i++)
log_word(msg_data[i]);
log_word(0xdead0006ffffffff);*/
}
return 0;
}
int try_handle_fpkg_trap(uint64_t* regs)
{
if(regs[RIP] == (uint64_t)kdata_base - 0x94a7f5)
{
uint64_t req[8];
copy_from_kernel(req, regs[RDX], 64);
uint64_t p_eekpfs = 0;
memcpy(&p_eekpfs, DMEM+req[2]+32, 8);
uint8_t eekpfs[256] = {0};
memcpy(eekpfs, DMEM+p_eekpfs, 256);
uint8_t crypt_seed[16];
memcpy(crypt_seed, DMEM+req[3]+0x370, 16);
uint8_t ek[32] = {}, sk[32] = {};
if(pfs_derive_fake_keys(eekpfs, crypt_seed, ek, sk))
{
/*log_word(0xdead0004dead0001);
{
uint64_t* q = ek;
for(int i = 0; i < 4; i++)
log_word(q[i]);
}
{
uint64_t* q = sk;
for(int i = 0; i < 4; i++)
log_word(q[i]);
}*/
int key1 = register_fake_key(ek);
if(key1 >= 0)
{
int key2 = register_fake_key(sk);
if(key2 >= 0)
{
regs[RIP] += 5;
regs[RAX] = 0;
uint32_t fake_resp[4] = {0, 0, IDX_TO_HANDLE(key1), IDX_TO_HANDLE(key2)};
copy_to_kernel(regs[RDX], fake_resp, sizeof(fake_resp));
}
}
}
}
else if(regs[RIP] == (uint64_t)sceSblServiceCryptAsync_deref_singleton)
{
if(!handle_crypto_request(regs))
{
regs[RAX] |= -1ull << 48;
regs[RBX] |= -1ull << 48;
}
}
/*else if(regs[RIP] == (uint64_t)kdata_base - 0x94a7a0)
{
log_word(0xdead0004dead0005);
log_word(regs[R13]);
log_word(regs[R14]);
}*/
else
return 0;
return 1;
}
void handle_fpkg_trap(uint64_t* regs, uint32_t trapno)
{
if(trapno == 1)
{
uint64_t frame[12];
pop_stack(regs, frame, sizeof(frame));
regs[RBX] = frame[7];
regs[R14] = frame[8];
regs[R15] = frame[9];
regs[RBP] = frame[10];
regs[RIP] = frame[11];
regs[RAX] = 0;
}
}
static const uint64_t dbgregs_for_nmount[6] = {0x1337, (uint64_t)kdata_base - 0x94a7f5, 0, 0, 0, 0x404};
void handle_fpkg_syscall(uint64_t* regs)
{
start_syscall_with_dbgregs(regs, dbgregs_for_nmount);
}
+7
View File
@@ -0,0 +1,7 @@
#pragma once
#include <sys/types.h>
#include <sys/syscall.h>
void handle_fpkg_syscall(uint64_t* regs);
void handle_fpkg_trap(uint64_t* regs, uint32_t trapno);
int try_handle_fpkg_trap(uint64_t* regs);
+25 -5
View File
@@ -1,5 +1,7 @@
#include <errno.h>
#include <sys/sysent.h>
#include <sys/syscall.h>
#include <machine/sysarch.h>
#include <string.h>
#include "kekcall.h"
#include "traps.h"
@@ -105,17 +107,35 @@ void handle_kekcall_trap(uint64_t* regs, uint32_t trap)
regs[RDI] = kpeek64(proc+16);
uint64_t stack_frame_2[14] = {(uint64_t)doreti_iret, MKTRAP(TRAP_KEKCALL, 3), [6] = stack_frame[13], regs[RDI]};
memcpy(stack_frame_2+8, stack_frame+7, 48);
if(sysc_no == SYS_sysarch && (uint32_t)stack_frame[7] == AMD64_GET_FSBASE)
{
stack_frame_2[1] = MKTRAP(TRAP_KEKCALL, 4);
stack_frame_2[8] = kpeek64(kpeek64(regs[RDI]+td_pcb)+pcb_fsbase);
kpoke64(stack_frame[13]+td_retval, 0);
}
else
kpoke64(regs[RDI]+td_retval, 0);
push_stack(regs, stack_frame_2, sizeof(stack_frame_2));
regs[RAX] = (uint64_t)&sysents[sysc_no];
regs[RIP] = kpeek64((uint64_t)&sysents[sysc_no].sy_call);
regs[RSI] = regs[RSP] + 64;
handle_syscall(regs, 0);
if(sysc_no == SYS_sysarch && (uint32_t)stack_frame[7] == AMD64_GET_FSBASE)
{
regs[RIP] = (uint64_t)copyout;
regs[RDI] = regs[RSP] + 64;
regs[RSI] = stack_frame[8];
regs[RDX] = 8;
}
else
{
regs[RIP] = kpeek64((uint64_t)&sysents[sysc_no].sy_call);
regs[RSI] = regs[RSP] + 64;
handle_syscall(regs, 0);
}
}
else if(trap == 3)
else if(trap == 3 || trap == 4)
{
uint64_t stack_frame[14];
pop_stack(regs, stack_frame, sizeof(stack_frame));
if(!(uint32_t)regs[RAX])
if(trap == 3 && !(uint32_t)regs[RAX])
kpoke64(stack_frame[5]+td_retval, kpeek64(stack_frame[6]+td_retval));
regs[RIP] = stack_frame[13];
}
+6
View File
@@ -11,6 +11,7 @@
#include "traps.h"
#include "kekcall.h"
#include "fself.h"
#include "fpkg.h"
#include "syscall_fixes.h"
int have_error_code;
@@ -55,6 +56,8 @@ void handle_syscall(uint64_t* regs, int allow_kekcall)
|| IS(get_sdk_compiled_version)
|| IS_PPR(get_ppr_sdk_compiled_version))
handle_fself_syscall(regs);
else if(IS(nmount))
handle_fpkg_syscall(regs);
else if(IS(mprotect)
|| IS_PPR(mdbg_call))
handle_syscall_fix(regs);
@@ -138,6 +141,7 @@ from_userspace:
case TRAP_KEKCALL: handle_kekcall_trap(regs, TRAP_IDX(lr)); break;
#ifndef FREEBSD
case TRAP_FSELF: handle_fself_trap(regs, TRAP_IDX(lr)); break;
case TRAP_FPKG: handle_fpkg_trap(regs, TRAP_IDX(lr)); break;
#endif
}
}
@@ -146,6 +150,8 @@ from_userspace:
return;
else if(handle_fself_parasites(regs))
return;
else if(try_handle_fpkg_trap(regs))
return;
else if(try_handle_syscall_fix_trap(regs))
return;
#endif
+105
View File
@@ -0,0 +1,105 @@
#include <stdint.h>
#include <stddef.h>
#include "pfs_crypto.h"
#include "utils.h"
#include "../BearSSL/inc/bearssl.h"
#include "../libtomcrypt/src/headers/tomcrypt.h"
static const uint8_t ypkg_n[256] = {0xc6, 0xcf, 0x71, 0xe7, 0xe5, 0x9a, 0xf0, 0xd1, 0x2a, 0x2c, 0x45, 0x8b, 0xf9, 0x2a, 0xe, 0xc1, 0x43, 0x5, 0x8b, 0xc3, 0x71, 0x17, 0x80, 0x1d, 0xcd, 0x49, 0x7d, 0xde, 0x35, 0x9d, 0x25, 0x9b, 0xa0, 0xd7, 0xa0, 0xf2, 0x7d, 0x6c, 0x8, 0x7e, 0xaa, 0x55, 0x2, 0x68, 0x2b, 0x23, 0xc6, 0x44, 0xb8, 0x44, 0x18, 0xeb, 0x56, 0xcf, 0x16, 0xa2, 0x48, 0x3, 0xc9, 0xe7, 0x4f, 0x87, 0xeb, 0x3d, 0x30, 0xc3, 0x15, 0x88, 0xbf, 0x20, 0xe7, 0x9d, 0xff, 0x77, 0xc, 0xde, 0x1d, 0x24, 0x1e, 0x63, 0xa9, 0x4f, 0x8a, 0xbf, 0x5b, 0xbe, 0x60, 0x19, 0x68, 0x33, 0x3b, 0xfc, 0xed, 0x9f, 0x47, 0x4e, 0x5f, 0xf8, 0xea, 0xcb, 0x3d, 0x0, 0xbd, 0x67, 0x1, 0xf9, 0x2c, 0x6d, 0xc6, 0xac, 0x13, 0x64, 0xe7, 0x67, 0x14, 0xf3, 0xdc, 0x52, 0x69, 0x6a, 0xb9, 0x83, 0x2c, 0x42, 0x30, 0x13, 0x1b, 0xb2, 0xd8, 0xa5, 0x2, 0xd, 0x79, 0xed, 0x96, 0xb1, 0xd, 0xf8, 0xcc, 0xc, 0xdf, 0x81, 0x95, 0x4f, 0x3, 0x58, 0x9, 0x57, 0xe, 0x80, 0x69, 0x2e, 0xfe, 0xff, 0x52, 0x77, 0xea, 0x75, 0x28, 0xa8, 0xfb, 0xc9, 0xbe, 0xbf, 0x9f, 0xbb, 0xb7, 0x79, 0x8e, 0x18, 0x5, 0xe1, 0x80, 0xbd, 0x50, 0x34, 0x94, 0x81, 0xd3, 0x53, 0xc2, 0x69, 0xa2, 0xd2, 0x4c, 0xcf, 0x6c, 0xf4, 0x57, 0x2c, 0x10, 0x4a, 0x3f, 0xfb, 0x22, 0xfd, 0x8b, 0x97, 0xe2, 0xc9, 0x5b, 0xa6, 0x2b, 0xcd, 0xd6, 0x1b, 0x6b, 0xdb, 0x68, 0x7f, 0x4b, 0xc2, 0xa0, 0x50, 0x34, 0xc0, 0x5, 0xe5, 0x8d, 0xef, 0x24, 0x67, 0xff, 0x93, 0x40, 0xcf, 0x2d, 0x62, 0xa2, 0xa0, 0x50, 0xb1, 0xf1, 0x3a, 0xa8, 0x3d, 0xfd, 0x80, 0xd1, 0xf9, 0xb8, 0x5, 0x22, 0xaf, 0xc8, 0x35, 0x45, 0x90, 0x58, 0x8e, 0xe3, 0x3a, 0x7c, 0xbd, 0x3e, 0x27};
static const uint8_t ypkg_d[256] = {0x7f, 0x76, 0xcd, 0xe, 0xe2, 0xd4, 0xde, 0x5, 0x1c, 0xc6, 0xd9, 0xa8, 0xe, 0x8d, 0xfa, 0x7b, 0xca, 0x1e, 0xaa, 0x27, 0x1a, 0x40, 0xf8, 0xf1, 0x22, 0x87, 0x35, 0xdd, 0xdb, 0xfd, 0xee, 0xf8, 0xc2, 0xbc, 0xbd, 0x1, 0xfb, 0x8b, 0xe2, 0x3e, 0x63, 0xb2, 0xb1, 0x22, 0x5c, 0x56, 0x49, 0x6e, 0x11, 0xbe, 0x7, 0x44, 0xb, 0x9a, 0x26, 0x66, 0xd1, 0x49, 0x2c, 0x8f, 0xd3, 0x1b, 0xcf, 0xa4, 0xa1, 0xb8, 0xd1, 0xfb, 0xa4, 0x9e, 0xd2, 0x21, 0x28, 0x83, 0x9, 0x8a, 0xf6, 0xa0, 0xb, 0xa3, 0xd6, 0xf, 0x9b, 0x63, 0x68, 0xcc, 0xbc, 0xc, 0x4e, 0x14, 0x5b, 0x27, 0xa4, 0xa9, 0xf4, 0x2b, 0xb9, 0xb8, 0x7b, 0xc0, 0xe6, 0x51, 0xad, 0x1d, 0x77, 0xd4, 0x6b, 0xb9, 0xce, 0x20, 0xd1, 0x26, 0x66, 0x7e, 0x5e, 0x9e, 0xa2, 0xe9, 0x6b, 0x90, 0xf3, 0x73, 0xb8, 0x52, 0x8f, 0x44, 0x11, 0x3, 0xc, 0x13, 0x97, 0x39, 0x3d, 0x13, 0x22, 0x58, 0xd5, 0x43, 0x82, 0x49, 0xda, 0x6e, 0x7c, 0xa1, 0xc5, 0x8c, 0xa5, 0xb0, 0x9, 0xe0, 0xce, 0x3d, 0xdf, 0xf4, 0x9d, 0x3c, 0x97, 0x15, 0xe2, 0x6a, 0xc7, 0x2b, 0x3c, 0x50, 0x93, 0x23, 0xdb, 0xba, 0x4a, 0x22, 0x66, 0x44, 0xac, 0x78, 0xbb, 0xe, 0x1a, 0x27, 0x43, 0xb5, 0x71, 0x67, 0xaf, 0xf4, 0xab, 0x48, 0x46, 0x93, 0x73, 0xd0, 0x42, 0xab, 0x93, 0x63, 0xe5, 0x6c, 0x9a, 0xde, 0x50, 0x24, 0xc0, 0x23, 0x7d, 0x99, 0x79, 0x3f, 0x22, 0x7, 0xe0, 0xc1, 0x48, 0x56, 0x1b, 0xdf, 0x83, 0x9, 0x12, 0xb4, 0x2d, 0x45, 0x6b, 0xc9, 0xc0, 0x68, 0x85, 0x99, 0x90, 0x79, 0x96, 0x1a, 0xd7, 0xf5, 0x4d, 0x1f, 0x37, 0x83, 0x40, 0x4a, 0xec, 0x39, 0x37, 0xa6, 0x80, 0x92, 0x7d, 0xc5, 0x80, 0xc7, 0xd6, 0x6f, 0xfe, 0x8a, 0x79, 0x89, 0xc6, 0xb1};
static const br_rsa_public_key ypkg = {
.n = (void*)ypkg_n,
.nlen = sizeof(ypkg_n),
.e = (void*)ypkg_d,
.elen = sizeof(ypkg_d),
};
static void pfs_gen_key(uint32_t idx, const uint8_t* seed, const uint8_t* ekpfs, uint8_t* out)
{
br_hmac_key_context key_ctx;
br_hmac_key_init(&key_ctx, &br_sha256_vtable, ekpfs, 32);
br_hmac_context ctx;
br_hmac_init(&ctx, &key_ctx, 0);
br_hmac_update(&ctx, &idx, sizeof(idx));
br_hmac_update(&ctx, seed, 16);
br_hmac_out(&ctx, out);
}
int pfs_derive_fake_keys(const uint8_t* p_eekpfs, const uint8_t* crypt_seed, uint8_t* ek, uint8_t* sk)
{
uint8_t eekpfs[256];
memcpy(eekpfs, p_eekpfs, 256);
if(!br_rsa_i62_public(eekpfs, 256, &ypkg))
return 0;
if(eekpfs[0] != 0 || eekpfs[1] != 2)
return 0;
size_t idx = 1;
while(idx < 256 && eekpfs[idx])
idx++;
if(idx != 255 - 32)
return 0;
uint8_t* ekpfs = eekpfs+idx+1;
pfs_gen_key(1, crypt_seed, ekpfs, ek);
pfs_gen_key(2, crypt_seed, ekpfs, sk);
return 1;
}
int pfs_hmac_virtual(uint8_t* out, const uint8_t* key, uint64_t data, size_t data_size)
{
br_hmac_key_context key_ctx;
br_hmac_key_init(&key_ctx, &br_sha256_vtable, key, 32);
br_hmac_context ctx;
br_hmac_init(&ctx, &key_ctx, 0);
while(data_size)
{
uint64_t chunk_cur;
uint64_t chunk_end;
if(!virt2phys(data, &chunk_cur, &chunk_end))
return -1;
size_t chk = chunk_end - chunk_cur;
if(chk > data_size)
chk = data_size;
br_hmac_update(&ctx, DMEM+chunk_cur, chk);
data += chk;
data_size -= chk;
}
br_hmac_out(&ctx, out);
return 0;
}
int pfs_xts_virtual(uint64_t dst, uint64_t src, const uint8_t* key, uint64_t start, uint32_t count, int is_encrypt)
{
enum { SECTOR_SIZE = 4096 };
static int aes_cipher = -1;
if(aes_cipher < 0)
{
aes_cipher = register_cipher(&aes_desc);
if(aes_cipher < 0)
{
log_word(0xdeaddeaddeaddead);
log_word(aes_cipher);
return -1;
}
}
symmetric_xts xts = {};
xts_start(aes_cipher, key+16, key, 16, 0, &xts);
while(count--)
{
static uint8_t input[SECTOR_SIZE], output[SECTOR_SIZE];
uint64_t tweak[2] = {start, 0};
if(copy_from_kernel(input, src, SECTOR_SIZE))
return -1;
if(is_encrypt)
xts_encrypt(input, SECTOR_SIZE, output, (void*)tweak, &xts);
else
xts_decrypt(input, SECTOR_SIZE, output, (void*)tweak, &xts);
if(copy_to_kernel(dst, output, SECTOR_SIZE))
return -1;
dst += SECTOR_SIZE;
src += SECTOR_SIZE;
start++;
}
xts_done(&xts);
return 0;
}
+6
View File
@@ -0,0 +1,6 @@
#pragma once
#include <stdint.h>
int pfs_derive_fake_keys(const uint8_t* p_eekpfs, const uint8_t* crypt_seed, uint8_t* ek, uint8_t* sk);
int pfs_hmac_virtual(uint8_t* out, const uint8_t* key, uint64_t data, size_t data_size);
int pfs_xts_virtual(uint64_t dst, uint64_t src, const uint8_t* key, uint64_t start, uint32_t count, int is_encrypt);
+1
View File
@@ -5,6 +5,7 @@ enum
TRAP_UTILS = 0xdead0000,
TRAP_KEKCALL,
TRAP_FSELF,
TRAP_FPKG,
};
#define MKTRAP(kind, idx) (((uint64_t)(kind) << 32) | ((uint64_t)(idx)))
+7
View File
@@ -19,6 +19,7 @@ int virt2phys(uint64_t addr, uint64_t* phys, uint64_t* phys_limit)
if(!(next_pml & 1))
{
log_word(0xdeaddeaddeaddead);
log_word((uint64_t)__builtin_return_address(0));
return 0;
}
if((next_pml & 128) || i == 12)
@@ -40,7 +41,10 @@ int copy_from_kernel(void* dst, uint64_t src, uint64_t sz)
while(sz)
{
if(!virt2phys(src, &phys, &phys_end))
{
log_word((uint64_t)__builtin_return_address(0));
return EFAULT;
}
size_t chk = phys_end - phys;
if(sz < chk)
chk = sz;
@@ -59,7 +63,10 @@ int copy_to_kernel(uint64_t dst, const void* src, uint64_t sz)
while(sz)
{
if(!virt2phys(dst, &phys, &phys_end))
{
log_word((uint64_t)__builtin_return_address(0));
return EFAULT;
}
size_t chk = phys_end - phys;
if(sz < chk)
chk = sz;
+4 -2
View File
@@ -2,6 +2,7 @@
#include <sys/types.h>
#include <stddef.h>
#include "structs.h"
#include "log.h"
extern uint64_t cr3_phys;
extern uint64_t trap_frame;
@@ -23,8 +24,9 @@ int wrmsr(uint32_t which, uint64_t value);
static inline uint64_t kpeek64(uintptr_t kptr)
{
uint64_t ans;
copy_from_kernel(&ans, kptr, sizeof(ans));
uint64_t ans = 0;
if(copy_from_kernel(&ans, kptr, sizeof(ans)))
log_word((uint64_t)__builtin_return_address(0));
return ans;
}