1
0
Fork 0
mirror of https://github.com/Atmosphere-NX/Atmosphere.git synced 2024-12-23 10:52:13 +00:00

SM: Add compile-time smhax flag, finishing module. (Closes #62)

This commit is contained in:
Michael Scire 2018-05-01 23:21:39 -06:00
parent bda056562c
commit 3c87c4c3c3
4 changed files with 51 additions and 5 deletions

View file

@ -46,7 +46,7 @@ ARCH := -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE
CFLAGS := -g -Wall -O2 -ffunction-sections \ CFLAGS := -g -Wall -O2 -ffunction-sections \
$(ARCH) $(DEFINES) $(ARCH) $(DEFINES)
CFLAGS += $(INCLUDE) -D__SWITCH__ CFLAGS += $(INCLUDE) -D__SWITCH__ -DSM_ENABLE_SMHAX
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17 CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17

View file

@ -6,6 +6,10 @@
static Registration::Process g_process_list[REGISTRATION_LIST_MAX_PROCESS] = {0}; static Registration::Process g_process_list[REGISTRATION_LIST_MAX_PROCESS] = {0};
static Registration::Service g_service_list[REGISTRATION_LIST_MAX_SERVICE] = {0}; static Registration::Service g_service_list[REGISTRATION_LIST_MAX_SERVICE] = {0};
static u64 g_initial_process_id_low = 0;
static u64 g_initial_process_id_high = 0;
static bool g_determined_initial_process_ids = false;
u64 GetServiceNameLength(u64 service) { u64 GetServiceNameLength(u64 service) {
u64 service_name_len = 0; u64 service_name_len = 0;
while (service & 0xFF) { while (service & 0xFF) {
@ -107,6 +111,30 @@ bool Registration::ValidateSacAgainstRestriction(u8 *r_sac, size_t r_sac_size, u
return true; return true;
} }
void Registration::CacheInitialProcessIdLimits() {
if (g_determined_initial_process_ids) {
return;
}
if (kernelAbove400()) {
svcGetSystemInfo(&g_initial_process_id_low, 2, 0, 0);
svcGetSystemInfo(&g_initial_process_id_high, 2, 0, 0);
} else {
g_initial_process_id_low = 0;
g_initial_process_id_high = REGISTRATION_INITIAL_PID_MAX;
}
g_determined_initial_process_ids = true;
}
bool Registration::IsInitialProcess(u64 pid) {
CacheInitialProcessIdLimits();
return g_initial_process_id_low <= pid && pid <= g_initial_process_id_high;
}
u64 Registration::GetInitialProcessId() {
CacheInitialProcessIdLimits();
return g_initial_process_id_low;
}
/* Process management. */ /* Process management. */
Result Registration::RegisterProcess(u64 pid, u8 *acid_sac, size_t acid_sac_size, u8 *aci0_sac, size_t aci0_sac_size) { Result Registration::RegisterProcess(u64 pid, u8 *acid_sac, size_t acid_sac_size, u8 *aci0_sac, size_t aci0_sac_size) {
Registration::Process *proc = GetFreeProcess(); Registration::Process *proc = GetFreeProcess();
@ -178,7 +206,7 @@ Result Registration::GetServiceForPid(u64 pid, u64 service, Handle *out) {
return 0xC15; return 0xC15;
} }
if (pid >= REGISTRATION_PID_BUILTIN_MAX && service != smEncodeName("dbg:m")) { if (!IsInitialProcess(pid)) {
Registration::Process *proc = GetProcessForPid(pid); Registration::Process *proc = GetProcessForPid(pid);
if (proc == NULL) { if (proc == NULL) {
return 0x415; return 0x415;
@ -204,7 +232,7 @@ Result Registration::RegisterServiceForPid(u64 pid, u64 service, u64 max_session
return 0xC15; return 0xC15;
} }
if (pid >= REGISTRATION_PID_BUILTIN_MAX) { if (!IsInitialProcess(pid)) {
Registration::Process *proc = GetProcessForPid(pid); Registration::Process *proc = GetProcessForPid(pid);
if (proc == NULL) { if (proc == NULL) {
return 0x415; return 0x415;
@ -288,7 +316,7 @@ Result Registration::UnregisterServiceForPid(u64 pid, u64 service) {
return 0xE15; return 0xE15;
} }
if (target_service->owner_pid != pid) { if (!IsInitialProcess(pid) && target_service->owner_pid != pid) {
return 0x1015; return 0x1015;
} }

View file

@ -4,7 +4,7 @@
#define REGISTRATION_LIST_MAX_PROCESS (0x40) #define REGISTRATION_LIST_MAX_PROCESS (0x40)
#define REGISTRATION_LIST_MAX_SERVICE (0x100) #define REGISTRATION_LIST_MAX_SERVICE (0x100)
#define REGISTRATION_MAX_SAC_SIZE (0x200) #define REGISTRATION_MAX_SAC_SIZE (0x200)
#define REGISTRATION_PID_BUILTIN_MAX 0x50 #define REGISTRATION_INITIAL_PID_MAX 0x50
class Registration { class Registration {
public: public:
@ -27,6 +27,9 @@ class Registration {
static Registration::Service *GetFreeService(); static Registration::Service *GetFreeService();
static bool IsValidForSac(u8 *sac, size_t sac_size, u64 service, bool is_host); static bool IsValidForSac(u8 *sac, size_t sac_size, u64 service, bool is_host);
static bool ValidateSacAgainstRestriction(u8 *r_sac, size_t r_sac_size, u8 *sac, size_t sac_size); static bool ValidateSacAgainstRestriction(u8 *r_sac, size_t r_sac_size, u8 *sac, size_t sac_size);
static void CacheInitialProcessIdLimits();
static bool IsInitialProcess(u64 pid);
static u64 GetInitialProcessId();
/* Process management. */ /* Process management. */
static Result RegisterProcess(u64 pid, u8 *acid_sac, size_t acid_sac_size, u8 *aci0_sac, size_t aci0_sac_size); static Result RegisterProcess(u64 pid, u8 *acid_sac, size_t acid_sac_size, u8 *aci0_sac, size_t aci0_sac_size);

View file

@ -39,6 +39,11 @@ std::tuple<Result> UserService::initialize(PidDescriptor pid) {
std::tuple<Result, MovedHandle> UserService::get_service(u64 service) { std::tuple<Result, MovedHandle> UserService::get_service(u64 service) {
Handle session_h = 0; Handle session_h = 0;
Result rc = 0x415; Result rc = 0x415;
#ifdef SM_ENABLE_SMHAX
if (!this->has_initialized) {
rc = Registration::GetServiceForPid(Registration::GetInitialProcessId(), service, &session_h);
}
#endif
if (this->has_initialized) { if (this->has_initialized) {
rc = Registration::GetServiceForPid(this->pid, service, &session_h); rc = Registration::GetServiceForPid(this->pid, service, &session_h);
} }
@ -58,6 +63,11 @@ std::tuple<Result, MovedHandle> UserService::deferred_get_service(u64 service) {
std::tuple<Result, MovedHandle> UserService::register_service(u64 service, u8 is_light, u32 max_sessions) { std::tuple<Result, MovedHandle> UserService::register_service(u64 service, u8 is_light, u32 max_sessions) {
Handle service_h = 0; Handle service_h = 0;
Result rc = 0x415; Result rc = 0x415;
#ifdef SM_ENABLE_SMHAX
if (!this->has_initialized) {
rc = Registration::RegisterServiceForPid(Registration::GetInitialProcessId(), service, max_sessions, is_light != 0, &service_h);
}
#endif
if (this->has_initialized) { if (this->has_initialized) {
rc = Registration::RegisterServiceForPid(this->pid, service, max_sessions, is_light != 0, &service_h); rc = Registration::RegisterServiceForPid(this->pid, service, max_sessions, is_light != 0, &service_h);
} }
@ -66,6 +76,11 @@ std::tuple<Result, MovedHandle> UserService::register_service(u64 service, u8 is
std::tuple<Result> UserService::unregister_service(u64 service) { std::tuple<Result> UserService::unregister_service(u64 service) {
Result rc = 0x415; Result rc = 0x415;
#ifdef SM_ENABLE_SMHAX
if (!this->has_initialized) {
rc = Registration::UnregisterServiceForPid(Registration::GetInitialProcessId(), service);
}
#endif
if (this->has_initialized) { if (this->has_initialized) {
rc = Registration::UnregisterServiceForPid(this->pid, service); rc = Registration::UnregisterServiceForPid(this->pid, service);
} }