mirror of
https://github.com/holdmysocks/ps5-tailscale.git
synced 2026-10-06 09:00:19 +02:00
A payload that runs the Tailscale client (tsnet, userspace networking) on a jailbroken PS5: a C launcher built with ps5-payload-sdk that loads a Go program in-process, an installer that registers it with the console's payload autoloader and adds a home screen icon, and the patch that makes Go 1.27.1 speak the PS5's FreeBSD 9 era syscall interface.
81 lines
2.6 KiB
C
81 lines
2.6 KiB
C
/* Find out which buffer sizes getdirentries(196)/getdents(272) accept on the
|
|
* PS5's filesystems, and what the returned records look like. */
|
|
|
|
#include <fcntl.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#include <sys/mount.h>
|
|
#include <sys/param.h>
|
|
#include <sys/stat.h>
|
|
|
|
static long
|
|
raw(long n, long a, long b, long c, long d) {
|
|
long ret;
|
|
unsigned char cf;
|
|
register long r10 __asm__("r10") = d;
|
|
__asm__ volatile("syscall; setc %1" : "+a"(n), "=q"(cf) : "D"(a), "S"(b), "d"(c), "r"(r10) : "rcx", "r11", "r8", "r9", "memory");
|
|
ret = n;
|
|
return cf ? -ret : ret;
|
|
}
|
|
|
|
int
|
|
main(void) {
|
|
static const char *dirs[] = {"/", "/data", "/dev", "/system", "/user", "/system_data", "/mnt", 0};
|
|
static const int sizes[] = {256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536};
|
|
static char buf[65536];
|
|
|
|
setvbuf(stdout, 0, _IONBF, 0);
|
|
for (int d = 0; dirs[d]; d++) {
|
|
struct statfs sfs;
|
|
struct stat st;
|
|
memset(&sfs, 0, sizeof(sfs));
|
|
if (statfs(dirs[d], &sfs)) {
|
|
printf("%s: statfs failed\n", dirs[d]);
|
|
continue;
|
|
}
|
|
stat(dirs[d], &st);
|
|
printf("%s: fstype=%s bsize=%lu iosize=%lu st_blksize=%d sizeof(statfs)=%zu\n", dirs[d], sfs.f_fstypename,
|
|
(unsigned long)sfs.f_bsize, (unsigned long)sfs.f_iosize, (int)st.st_blksize, sizeof(sfs));
|
|
for (size_t s = 0; s < sizeof(sizes) / sizeof(sizes[0]); s++) {
|
|
int fd = open(dirs[d], O_RDONLY | O_DIRECTORY);
|
|
if (fd < 0) {
|
|
printf(" open failed\n");
|
|
break;
|
|
}
|
|
long base = 0;
|
|
long n1 = raw(196, fd, (long)buf, sizes[s], (long)&base);
|
|
long off1 = lseek(fd, 0, SEEK_CUR);
|
|
long n2 = raw(196, fd, (long)buf, sizes[s], (long)&base);
|
|
close(fd);
|
|
fd = open(dirs[d], O_RDONLY | O_DIRECTORY);
|
|
long n3 = raw(272, fd, (long)buf, sizes[s], 0);
|
|
close(fd);
|
|
printf(" size %-6d getdirentries=%ld (off after=%ld, next=%ld) getdents=%ld\n", sizes[s], n1, off1, n2, n3);
|
|
}
|
|
}
|
|
|
|
/* Dump the first records of /data to confirm the dirent layout. */
|
|
int fd = open("/data", O_RDONLY | O_DIRECTORY);
|
|
long base = 0;
|
|
long n = raw(196, fd, (long)buf, sizeof(buf), (long)&base);
|
|
printf("/data records (n=%ld):\n", n);
|
|
for (long pos = 0; pos + 8 <= n && pos < 400;) {
|
|
uint32_t fileno;
|
|
uint16_t reclen;
|
|
memcpy(&fileno, buf + pos, 4);
|
|
memcpy(&reclen, buf + pos + 4, 2);
|
|
printf(" +%ld fileno=%u reclen=%u type=%u namlen=%u name=%.*s\n", pos, fileno, reclen, (uint8_t)buf[pos + 6],
|
|
(uint8_t)buf[pos + 7], (uint8_t)buf[pos + 7], buf + pos + 8);
|
|
if (!reclen) {
|
|
break;
|
|
}
|
|
pos += reclen;
|
|
}
|
|
close(fd);
|
|
return 0;
|
|
}
|