update with daemon

This commit is contained in:
Chee Yee
2023-07-30 22:37:15 -07:00
parent b5a4b93e9c
commit d0196d3b53
16 changed files with 274 additions and 66 deletions
+3
View File
@@ -44,6 +44,7 @@ add_executable(ezremote_client
source/actions.cpp
source/config.cpp
source/crypt.c
source/daemon.cpp
source/fs.cpp
source/gui.cpp
source/getentropy.c
@@ -52,6 +53,7 @@ add_executable(ezremote_client
source/installer.cpp
source/lang.cpp
source/main.cpp
source/md5.cpp
source/orbis_jbc.c
source/system.cpp
source/sfo.cpp
@@ -103,4 +105,5 @@ target_link_libraries(ezremote_client
SceNet
SceBgft
SceAppInstUtil
SceLncUtil
)
-12
View File
@@ -39,7 +39,6 @@ add_executable(ezremote_client
../source/crypt.c
../source/fs.cpp
../source/getentropy.c
../source/ime_dialog.cpp
../source/inifile.c
../source/installer.cpp
../source/lang.cpp
@@ -58,14 +57,8 @@ target_link_libraries(ezremote_client
dbglogger
c
c++
png
webp
jpeg
z
pthread
SDL2
SDL2_image
samplerate
jbc
crypto
ssl
@@ -82,14 +75,9 @@ target_link_libraries(ezremote_client
SceShellCoreUtil
SceSysmodule
SceSystemService
ScePigletv2VSH
ScePrecompiledShaders
SceRtc
SceUserService
ScePad
SceAudioOut
SceSysUtil
SceImeDialog
SceNet
SceBgft
SceAppInstUtil
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1
View File
@@ -17,6 +17,7 @@
#define TMP_EDITOR_FILE DATA_PATH "/tmp_editor.txt"
#define TMP_SFO_PATH DATA_PATH "/tmp_pkg.sfo"
#define TMP_ICON_PATH DATA_PATH "/tmp_icon.png"
#define DAEMON_PATH "/system/vsh/app/RMTC00002"
#define CONFIG_GLOBAL "Global"
+91
View File
@@ -0,0 +1,91 @@
#include <orbis/libkernel.h>
#include <orbis/SystemService.h>
#include "config.h"
#include "fs.h"
#include "md5.h"
#include "daemon.h"
extern "C"
{
#include "orbis_jbc.h"
int sceLncUtilGetAppId(const char *title_id);
}
#include "dbglogger.h"
uint32_t LaunchDaemon(const char *title_id)
{
uint32_t userId = -1;
int libcmi = sceKernelLoadStartModule("/system/common/lib/libSceSystemService.sprx", 0, NULL, 0, 0, 0);
if (libcmi > 0)
{
LncAppParam param;
param.size = sizeof(LncAppParam);
param.user_id = userId;
param.app_opt = 0;
param.crash_report = 0;
param.LaunchAppCheck_flag = LaunchApp_SkipSystemUpdate;
dbglogger_log("Calling sceLncUtilLaunchApp");
return sceLncUtilLaunchApp(title_id, NULL, &param);
}
return 0;
}
bool IsDaemonOutdated()
{
bool res = true;
dbglogger_log("In IsDaemonOutdated");
if (FS::FileExists(DAEMON_PATH "/eboot.bin"))
{
res = md5FileCompare(DAEMON_PATH "/eboot.bin", "/mnt/sandbox/pfsmnt/RMTC00001-app0/daemon/daemon.self") == 0;
dbglogger_log("Daemon Is Outdated?: %s", res ? "Yes" : "No");
}
return res;
}
bool BootDaemonService()
{
dbglogger_log("Booting daemon");
if (!FS::FolderExists(DAEMON_PATH) || IsDaemonOutdated())
{
dbglogger_log("mounting /system");
if (mount_large_fs("/dev/da0x4.crypt", "/system", "exfatfs", "511", MNT_UPDATE) < 0)
{
dbglogger_log("mounting /system failed with %s", strerror(errno));
}
else
{
FS::MkDirs(DAEMON_PATH);
FS::MkDirs(DAEMON_PATH "/sce_sys");
dbglogger_log("copying param.sfo");
if (FS::Copy("/system/vsh/app/NPXS21007/sce_sys/param.sfo", DAEMON_PATH "/sce_sys/param.sfo"))
{
dbglogger_log("copying daemon.self");
if (!FS::Copy("/mnt/sandbox/pfsmnt/RMTC00001-app0/daemon/daemon.self", DAEMON_PATH "/eboot.bin"))
{
return false;
}
}
else
{
return false;
}
}
}
dbglogger_log("Calling sceLncUtilGetAppId");
uint32_t appid = sceLncUtilGetAppId("RMTC00002");
if ((appid & ~0xFFFFFF) != 0x60000000)
{
dbglogger_log("Start launching RMTC00002");
uint32_t appid = LaunchDaemon("RMTC00002");
dbglogger_log("Launched Daemon AppId: %x", appid);
}
else
dbglogger_log("Found Daemon AppId: %x", appid);
return true;
}
+6
View File
@@ -0,0 +1,6 @@
#ifndef DAEMON_H
#define DAEMON_H
bool BootDaemonService();
#endif
+15 -15
View File
@@ -26,13 +26,10 @@ extern "C"
#include "orbis_jbc.h"
}
#define FRAME_WIDTH 1920
#define FRAME_HEIGHT 1080
#define NET_HEAP_SIZE (5 * 1024 * 1024)
static void terminate()
{
INSTALLER::Exit();
terminate_jbc();
sceSystemServiceLoadExec("exit", NULL);
}
@@ -40,33 +37,36 @@ static void terminate()
int main()
{
dbglogger_init();
dbglogger_log("If you see this you've set up dbglogger correctly.");
dbglogger_log("In daemon");
int rc;
// No buffering
setvbuf(stdout, NULL, _IONBF, 0);
// load common modules
dbglogger_log("loading modules");
if (sceSysmoduleLoadModuleInternal(ORBIS_SYSMODULE_IME_DIALOG) < 0) return 0;
if (sceSysmoduleLoadModuleInternal(ORBIS_SYSMODULE_INTERNAL_SYSTEM_SERVICE) < 0) return 0;
if (sceSysmoduleLoadModuleInternal(ORBIS_SYSMODULE_INTERNAL_USER_SERVICE) < 0) return 0;
if (sceSysmoduleLoadModuleInternal(ORBIS_SYSMODULE_INTERNAL_BGFT) < 0) return 0;
if (sceSysmoduleLoadModuleInternal(ORBIS_SYSMODULE_INTERNAL_APP_INST_UTIL) < 0) return 0;
if (sceSysmoduleLoadModuleInternal(ORBIS_SYSMODULE_INTERNAL_PAD) < 0) return 0;
if (sceSysmoduleLoadModuleInternal(ORBIS_SYSMODULE_INTERNAL_AUDIOOUT) < 0 || sceAudioOutInit() != 0) return 0;
if (sceSysmoduleLoadModuleInternal(ORBIS_SYSMODULE_INTERNAL_NET) < 0 || sceNetInit() != 0) return 0;
dbglogger_log("sceUserServiceInitialize");
OrbisUserServiceInitializeParams param;
param.priority = ORBIS_KERNEL_PRIO_FIFO_LOWEST;
sceUserServiceInitialize(&param);
sceNetPoolCreate("simple", NET_HEAP_SIZE, 0);
if (INSTALLER::Init() < 0)
return 0;
dbglogger_log("initialize_jbc");
if (!initialize_jbc())
{
terminate();
}
atexit(terminate);
CONFIG::LoadConfig();
HttpServer::ServerThread(nullptr);
dbglogger_log("load_sys_modules");
if (load_sys_modules() != 0)
return 0;
atexit(terminate);
dbglogger_log("Exit daemon");
return 0;
}
+5 -1
View File
@@ -20,6 +20,7 @@
#include "server/http_server.h"
#include "clients/gdrive.h"
#include "config.h"
#include "daemon.h"
#include "lang.h"
#include "gui.h"
#include "util.h"
@@ -320,7 +321,10 @@ int main()
{
terminate();
}
HttpServer::Start();
//HttpServer::Start();
if (!BootDaemonService())
return 0;
if (load_sys_modules() != 0)
return 0;
+81 -38
View File
@@ -4,6 +4,8 @@
*/
#include "md5.h"
#include "fs.h"
#include "dbglogger.h"
/*
* Constants defined by the MD5 algorithm
@@ -14,7 +16,7 @@
#define D 0x10325476
static uint32_t S[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21};
@@ -58,15 +60,16 @@ static uint8_t PADDING[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/*
* Rotates a 32-bit word left by n bits
*/
uint32_t rotateLeft(uint32_t x, uint32_t n){
uint32_t rotateLeft(uint32_t x, uint32_t n)
{
return (x << n) | (x >> (32 - n));
}
/*
* Initialize a context
*/
void md5Init(MD5Context *ctx){
void md5Init(MD5Context *ctx)
{
ctx->size = (uint64_t)0;
ctx->buffer[0] = (uint32_t)A;
@@ -81,27 +84,31 @@ void md5Init(MD5Context *ctx){
* If the input fills out a block of 512 bits, apply the algorithm (md5Step)
* and save the result in the buffer. Also updates the overall size.
*/
void md5Update(MD5Context *ctx, uint8_t *input_buffer, size_t input_len){
void md5Update(MD5Context *ctx, uint8_t *input_buffer, size_t input_len)
{
uint32_t input[16];
unsigned int offset = ctx->size % 64;
ctx->size += (uint64_t)input_len;
// Copy each byte in input_buffer into the next space in our context input
for(unsigned int i = 0; i < input_len; ++i){
ctx->input[offset++] = (uint8_t)*(input_buffer + i);
for (unsigned int i = 0; i < input_len; ++i)
{
ctx->input[offset++] = (uint8_t) * (input_buffer + i);
// If we've filled our context input, copy it into our local array input
// then reset the offset to 0 and fill in a new buffer.
// Every time we fill out a chunk, we run it through the algorithm
// to enable some back and forth between cpu and i/o
if(offset % 64 == 0){
for(unsigned int j = 0; j < 16; ++j){
if (offset % 64 == 0)
{
for (unsigned int j = 0; j < 16; ++j)
{
// Convert to little-endian
// The local variable `input` our 512-bit chunk separated into 32-bit words
// we can use in calculations
input[j] = (uint32_t)(ctx->input[(j * 4) + 3]) << 24 |
(uint32_t)(ctx->input[(j * 4) + 2]) << 16 |
(uint32_t)(ctx->input[(j * 4) + 1]) << 8 |
(uint32_t)(ctx->input[(j * 4) + 1]) << 8 |
(uint32_t)(ctx->input[(j * 4)]);
}
md5Step(ctx->buffer, input);
@@ -114,7 +121,8 @@ void md5Update(MD5Context *ctx, uint8_t *input_buffer, size_t input_len){
* Pad the current input to get to 448 bytes, append the size in bits to the very end,
* and save the result of the final iteration into digest.
*/
void md5Finalize(MD5Context *ctx){
void md5Finalize(MD5Context *ctx)
{
uint32_t input[16];
unsigned int offset = ctx->size % 64;
unsigned int padding_length = offset < 56 ? 56 - offset : (56 + 64) - offset;
@@ -125,10 +133,11 @@ void md5Finalize(MD5Context *ctx){
// Do a final update (internal to this function)
// Last two 32-bit words are the two halves of the size (converted from bytes to bits)
for(unsigned int j = 0; j < 14; ++j){
for (unsigned int j = 0; j < 14; ++j)
{
input[j] = (uint32_t)(ctx->input[(j * 4) + 3]) << 24 |
(uint32_t)(ctx->input[(j * 4) + 2]) << 16 |
(uint32_t)(ctx->input[(j * 4) + 1]) << 8 |
(uint32_t)(ctx->input[(j * 4) + 1]) << 8 |
(uint32_t)(ctx->input[(j * 4)]);
}
input[14] = (uint32_t)(ctx->size * 8);
@@ -137,9 +146,10 @@ void md5Finalize(MD5Context *ctx){
md5Step(ctx->buffer, input);
// Move the result into digest (convert from little-endian)
for(unsigned int i = 0; i < 4; ++i){
for (unsigned int i = 0; i < 4; ++i)
{
ctx->digest[(i * 4) + 0] = (uint8_t)((ctx->buffer[i] & 0x000000FF));
ctx->digest[(i * 4) + 1] = (uint8_t)((ctx->buffer[i] & 0x0000FF00) >> 8);
ctx->digest[(i * 4) + 1] = (uint8_t)((ctx->buffer[i] & 0x0000FF00) >> 8);
ctx->digest[(i * 4) + 2] = (uint8_t)((ctx->buffer[i] & 0x00FF0000) >> 16);
ctx->digest[(i * 4) + 3] = (uint8_t)((ctx->buffer[i] & 0xFF000000) >> 24);
}
@@ -148,7 +158,8 @@ void md5Finalize(MD5Context *ctx){
/*
* Step on 512 bits of input with the main MD5 algorithm.
*/
void md5Step(uint32_t *buffer, uint32_t *input){
void md5Step(uint32_t *buffer, uint32_t *input)
{
uint32_t AA = buffer[0];
uint32_t BB = buffer[1];
uint32_t CC = buffer[2];
@@ -158,24 +169,26 @@ void md5Step(uint32_t *buffer, uint32_t *input){
unsigned int j;
for(unsigned int i = 0; i < 64; ++i){
switch(i / 16){
case 0:
E = F(BB, CC, DD);
j = i;
break;
case 1:
E = G(BB, CC, DD);
j = ((i * 5) + 1) % 16;
break;
case 2:
E = H(BB, CC, DD);
j = ((i * 3) + 5) % 16;
break;
default:
E = I(BB, CC, DD);
j = (i * 7) % 16;
break;
for (unsigned int i = 0; i < 64; ++i)
{
switch (i / 16)
{
case 0:
E = F(BB, CC, DD);
j = i;
break;
case 1:
E = G(BB, CC, DD);
j = ((i * 5) + 1) % 16;
break;
case 2:
E = H(BB, CC, DD);
j = ((i * 3) + 5) % 16;
break;
default:
E = I(BB, CC, DD);
j = (i * 7) % 16;
break;
}
uint32_t temp = DD;
@@ -195,7 +208,8 @@ void md5Step(uint32_t *buffer, uint32_t *input){
* Functions that run the algorithm on the provided input and put the digest into result.
* result should be able to store 16 bytes.
*/
void md5String(char *input, uint8_t *result){
void md5String(char *input, uint8_t *result)
{
MD5Context ctx;
md5Init(&ctx);
md5Update(&ctx, (uint8_t *)input, strlen(input));
@@ -204,14 +218,16 @@ void md5String(char *input, uint8_t *result){
memcpy(result, ctx.digest, 16);
}
void md5File(FILE *file, uint8_t *result){
char *input_buffer = malloc(1024);
void md5File(FILE *file, uint8_t *result)
{
char *input_buffer = (char *)malloc(1024);
size_t input_size = 0;
MD5Context ctx;
md5Init(&ctx);
while((input_size = fread(input_buffer, 1, 1024, file)) > 0){
while ((input_size = fread(input_buffer, 1, 1024, file)) > 0)
{
md5Update(&ctx, (uint8_t *)input_buffer, input_size);
}
@@ -221,3 +237,30 @@ void md5File(FILE *file, uint8_t *result){
memcpy(result, ctx.digest, 16);
}
int md5FileCompare(const char *file1, const char *file2)
{
uint8_t res1[MD5_HASH_LENGTH];
uint8_t res2[MD5_HASH_LENGTH];
FILE *fd1 = FS::OpenRead(file1);
FILE *fd2 = FS::OpenRead(file2);
md5File(fd1, res1);
md5File(fd2, res2);
dbglogger_log("res1=%x", res1);
dbglogger_log("res2=%x", res2);
for (int i = 0; i < MD5_HASH_LENGTH; i++)
{
if (res1[i] != res2[i])
{
fclose(fd1);
fclose(fd2);
return 1;
}
}
fclose(fd1);
fclose(fd2);
return 0;
}
+4
View File
@@ -5,6 +5,9 @@
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#define MD5_HASH_LENGTH 16
typedef struct{
uint64_t size; // Size of input in bytes
@@ -20,5 +23,6 @@ void md5Step(uint32_t *buffer, uint32_t *input);
void md5String(char *input, uint8_t *result);
void md5File(FILE *file, uint8_t *result);
int md5FileCompare(const char *file1, const char *file2);
#endif
+61
View File
@@ -2,9 +2,70 @@
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <sys/uio.h>
#include <orbis/libkernel.h>
#include <libjbc.h>
#define SYSCALL(nr, fn) __attribute__((naked)) fn\
{\
asm volatile("mov $" #nr ", %rax\nmov %rcx, %r10\nsyscall\nret");\
}
SYSCALL(22, static int unmount(const char* path, int flags))
SYSCALL(378, static int nmount(struct iovec* iov, unsigned int niov, int flags))
static void build_iovec(struct iovec** iov, int* iovlen, const char* name, const void* val, size_t len) {
int i;
if (*iovlen < 0)
return;
i = *iovlen;
*iov = (struct 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 mount_large_fs(const char* device, const char* mountpoint, const char* fstype, const char* mode, unsigned int flags)
{
struct iovec* iov = NULL;
int iovlen = 0;
unmount(mountpoint, 0);
build_iovec(&iov, &iovlen, "fstype", fstype, -1);
build_iovec(&iov, &iovlen, "fspath", mountpoint, -1);
build_iovec(&iov, &iovlen, "from", device, -1);
build_iovec(&iov, &iovlen, "large", "yes", -1);
build_iovec(&iov, &iovlen, "timezone", "static", -1);
build_iovec(&iov, &iovlen, "async", "", -1);
build_iovec(&iov, &iovlen, "ignoreacl", "", -1);
if (mode) {
build_iovec(&iov, &iovlen, "dirmask", mode, -1);
build_iovec(&iov, &iovlen, "mask", mode, -1);
}
return nmount(iov, iovlen, flags);
}
// Variables for (un)jailbreaking
jbc_cred g_Cred;
jbc_cred g_RootCreds;
+3
View File
@@ -1,7 +1,10 @@
#ifndef __ORBIS_JBC_H__
#define __ORBIS_JBC_H__
#define MNT_UPDATE 0x0000000000010000ULL
int initialize_jbc();
void terminate_jbc();
int mount_large_fs(const char* device, const char* mountpoint, const char* fstype, const char* mode, unsigned int flags);
#endif
+4
View File
@@ -1075,7 +1075,11 @@ namespace HttpServer
{
return;
}
#ifndef DAEMON
int ret = pthread_create(&http_server_thid, NULL, ServerThread, NULL);
#else
ServerThread(nullptr);
#endif
}
void Stop()