Files
Orbis-Suite-3.0/Playstation/OrbisLibAPI/Utilities.cpp
T
2023-02-17 16:30:32 -07:00

373 lines
9.0 KiB
C++

#include "Common.h"
#include "Utilities.h"
#pragma region Misc
bool LoadModules()
{
auto res = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_SYSTEM_SERVICE);
if (res != 0)
{
klog("LoadModules(): Failed to load SCE_SYSMODULE_INTERNAL_SYSTEM_SERVICE (%llX)\n", res);
return false;
}
res = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_APPINSTUTIL);
if (res != 0)
{
klog("LoadModules(): Failed to load SCE_SYSMODULE_INTERNAL_APPINSTUTIL (%llX)\n", res);
return false;
}
res = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_USER_SERVICE);
if (res != 0)
{
klog("LoadModules(): Failed to load SCE_SYSMODULE_INTERNAL_USER_SERVICE (%llX)\n", res);
return false;
}
res = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_SYS_CORE);
if (res != 0)
{
klog("LoadModules(): Failed to load SCE_SYSMODULE_INTERNAL_SYS_CORE (%llX)\n", res);
return false;
}
res = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_NETCTL);
if (res != 0)
{
klog("LoadModules(): Failed to load SCE_SYSMODULE_INTERNAL_NETCTL (%llX)\n", res);
return false;
}
res = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_NET);
if (res != 0)
{
klog("LoadModules(): Failed to load SCE_SYSMODULE_INTERNAL_NET (%llX)\n", res);
return false;
}
res = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_HTTP);
if (res != 0)
{
klog("LoadModules(): Failed to load SCE_SYSMODULE_INTERNAL_HTTP (%llX)\n", res);
return false;
}
res = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_BGFT);
if (res != 0)
{
klog("LoadModules(): Failed to load SCE_SYSMODULE_INTERNAL_BGFT (%llX)\n", res);
return false;
}
sceSysmoduleLoadModuleInternal(0x8000000D);
// Start up networking interface
res = sceNetInit();
if (res != 0)
{
klog("LoadModules(): sceNetInit failed\n");
return false;
}
// Start up user service.
res = sceUserServiceInitialize(nullptr);
if (res != 0)
{
klog("LoadModules(): sceUserServiceInitialize failed (%llX)\n", res);
return false;
}
// Init temporary wrapper for lncutils.
res = sceLncUtilInitialize();
if (res != 0)
{
klog("LoadModules(): sceLncUtilInitialize failed (%llX)\n", res);
return false;
}
// Init SysCoreUtils.
res = sceApplicationInitialize();
if (res != 0)
{
klog("LoadModules(): sceApplicationInitialize failed (%llX)\n", res);
return false;
}
// Init App install utils.
res = sceAppInstUtilInitialize();
if (res != 0)
{
klog("LoadModules(): sceAppInstUtilInitialize failed (%llX)\n", res);
return false;
}
klog("LoadModules(): Success!\n");
return true;
//res = sceSysmoduleLoadModuleInternal(0xA4);
}
void Notify(const char* MessageFMT, ...)
{
OrbisNotificationRequest Buffer;
//Create full string from va list.
va_list args;
va_start(args, MessageFMT);
vsprintf(Buffer.message, MessageFMT, args);
va_end(args);
//Populate the notify buffer.
Buffer.type = OrbisNotificationRequestType::NotificationRequest; //this one is just a standard one and will print what ever is stored at the buffer.Message.
Buffer.unk3 = 0;
Buffer.useIconImageUri = 1; //Bool to use a custom uri.
Buffer.targetId = -1; //Not sure if name is correct but is always set to -1.
strcpy(Buffer.iconUri, "https://i.imgur.com/SJPIBGG.png"); //Copy the uri to the buffer.
//From user land we can call int64_t sceKernelSendNotificationRequest(int64_t unk1, char* Buffer, size_t size, int64_t unk2) which is a libkernel import.
sceKernelSendNotificationRequest(0, &Buffer, 3120, 0);
}
void Notify_Custom(const char* IconURI, const char* MessageFMT, ...)
{
OrbisNotificationRequest Buffer;
//Create full string from va list.
va_list args;
va_start(args, MessageFMT);
vsprintf(Buffer.message, MessageFMT, args);
va_end(args);
//Populate the notify buffer.
Buffer.type = OrbisNotificationRequestType::NotificationRequest; //this one is just a standard one and will print what ever is stored at the buffer.Message.
Buffer.unk3 = 0;
Buffer.useIconImageUri = 1; //Bool to use a custom uri.
Buffer.targetId = -1; //Not sure if name is correct but is always set to -1.
strcpy(Buffer.iconUri, IconURI); //Copy the uri to the buffer.
//From user land we can call int64_t sceKernelSendNotificationRequest(int64_t unk1, char* Buffer, size_t size, int64_t unk2) which is a libkernel import.
sceKernelSendNotificationRequest(0, &Buffer, 3120, 0);
//What sceKernelSendNotificationRequest is doing is opening the device "/dev/notification0" or "/dev/notification1"
// and writing the NotifyBuffer we created to it. Somewhere in ShellUI it is read and parsed into a json which is where
// I found some clues on how to build the buffer.
}
void klog(const char* fmt, ...)
{
char Buffer[0x200];
//Create full string from va list.
va_list args;
va_start(args, fmt);
vsprintf(Buffer, fmt, args);
va_end(args);
sceKernelDebugOutText(0, Buffer);
}
bool Jailbreak()
{
struct jbc_cred cred;
if (jbc_get_cred(&cred) != 0)
{
klog("jbc failed to get cred.\n");
return false;
}
if (jbc_jailbreak_cred(&cred) != 0)
{
klog("jbc failed to jailbreak cred.\n");
return false;
}
//cred.sonyCred = 0x3800000000010003;
if (jbc_set_cred(&cred) != 0)
{
klog("jbc failed to set cred.\n");
return false;
}
return true;
}
bool CopySflash()
{
int sflashFd = sceKernelOpen("/dev/sflash0", ORBIS_KERNEL_O_RDONLY, 0);
int backupFd = sceKernelOpen("/data/Orbis Suite/sflash0", ORBIS_KERNEL_O_CREAT | ORBIS_KERNEL_O_WRONLY | ORBIS_KERNEL_O_APPEND, 0777);
if (sflashFd && backupFd)
{
auto buffer = (unsigned char*)malloc(4 * 1024 * 1024);
if (buffer == nullptr)
{
klog("failled to allocate memory for sflash read.\n");
return false;
}
size_t bytesRead = 0;
while ((bytesRead = sceKernelRead(sflashFd, buffer, 4 * 1024 * 1024)) > 0)
{
sceKernelWrite(backupFd, buffer, bytesRead);
}
free(buffer);
sceKernelClose(sflashFd);
sceKernelClose(backupFd);
return true;
}
return false;
}
int getMacAddress(OrbisNetIfName ifName_Num, char* strOut, size_t len)
{
if (len < 18)
{
klog("getMacAddress(): Output len must be >= 18.\n");
return -1;
}
OrbisNetIfEntry ifEntry;
auto res = sceNetGetIfList(ifName_Num, &ifEntry, 1);
if (res < 0)
{
klog("getMacAddress(): failed to get IfList for %i\n", ifName_Num);
return res;
}
return sceNetEtherNtostr(ifEntry.MacAddress, strOut, len);
}
#pragma endregion
void hexdump(void* ptr, int buflen) {
unsigned char* buf = (unsigned char*)ptr;
int i, j;
for (i = 0; i < buflen; i += 16) {
klog("%06x: ", i);
for (j = 0; j < 16; j++)
if (i + j < buflen)
klog("%02x ", buf[i + j]);
else
klog(" ");
klog(" ");
for (j = 0; j < 16; j++)
if (i + j < buflen)
klog("%c", isprint(buf[i + j]) ? buf[i + j] : '.');
klog("\n");
}
}
int GetProcessList(std::vector<kinfo_proc>& ProcessList)
{
size_t length;
static int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_PROC, 0 };
// Get the size of buffer needed.
if (sysctl(name, 3, nullptr, &length, nullptr, NULL) < 0)
return -1;
// Resize our vector to accommodate.
ProcessList.resize(length / sizeof(kinfo_proc));
// Retrive the processes.
if (sysctl(name, 3, ProcessList.data(), &length, nullptr, NULL) < 0)
return -1;
// Remove duplicates.
ProcessList.erase(std::unique(ProcessList.begin(), ProcessList.end(), [](kinfo_proc const& a, kinfo_proc const& b)
{
sceKernelGetProcessName(a.pid, (char*)a.name);
return a.pid == b.pid;
}), ProcessList.end());
return 0;
}
static void build_iovec(iovec** iov, int* iovlen, const char* name, const void* val, size_t len) {
int i;
if (*iovlen < 0)
return;
i = *iovlen;
*iov = (iovec*)realloc(*iov, sizeof * *iov * (i + 2));
if (*iov == NULL) {
*iovlen = -1;
return;
}
(*iov)[i].iov_base = strdup(name);
(*iov)[i].iov_len = strlen(name) + 1;
++i;
(*iov)[i].iov_base = (void*)val;
if (len == (size_t)-1) {
if (val != NULL)
len = strlen((const char*)val) + 1;
else
len = 0;
}
(*iov)[i].iov_len = (int)len;
*iovlen = ++i;
}
int nmount(struct iovec* iov, unsigned int niov, int flags)
{
return syscall(378, iov, niov, flags);
}
bool LinkDir(const char* Dir, const char* LinkedDir)
{
auto res = sceKernelMkdir(LinkedDir, 0777);
if (res != 0)
{
if (res == 0x80020011)
{
klog("Directory '%s' already exists!\n", LinkedDir);
return true;
}
klog("Failed to make dir '%s' err: %llX\n", LinkedDir, res);
return false;
}
struct iovec* iov = NULL;
int iovlen = 0;
build_iovec(&iov, &iovlen, "fstype", "nullfs", -1);
build_iovec(&iov, &iovlen, "fspath", LinkedDir, -1);
build_iovec(&iov, &iovlen, "target", Dir, -1);
if (nmount(iov, iovlen, 0))
{
klog("nmount failed\n");
sceKernelRmdir(LinkedDir);
return false;
}
return true;
}
bool LoadToolbox()
{
// Mount data & hostapp into ShellUI sandbox
LinkDir("/data/", "/mnt/sandbox/NPXS20001_000/data");
LinkDir("/hostapp/", "/mnt/sandbox/NPXS20001_000/hostapp");
auto handle = sys_sdk_proc_prx_load("SceShellUI", "/user/data/Orbis Toolbox/OrbisToolbox-2.0.sprx");
if (handle > 0) {
klog("Orbis Toolbox loaded! %d\n", handle);
return true;
}
else
{
klog("error: %d\n", handle);
Notify("Failed to load Orbis Toolbox!");
return false;
}
}