mitm/cfg: pass around override status for decision-making

This commit is contained in:
Michael Scire 2019-11-21 04:03:19 -08:00 committed by SciresM
parent 37e065fa2d
commit 421324b498
59 changed files with 425 additions and 265 deletions

View file

@ -164,10 +164,9 @@ namespace ams::cfg {
return 1;
}
bool IsOverrideKeyHeld(const OverrideKey *cfg) {
u64 kHeld = 0;
bool keys_triggered = (R_SUCCEEDED(hid::GetKeysHeld(&kHeld)) && ((kHeld & cfg->key_combination) != 0));
return IsSdCardInitialized() && (cfg->override_by_default ^ keys_triggered);
constexpr inline bool IsOverrideMatch(const OverrideStatus &status, const OverrideKey &cfg) {
bool keys_triggered = ((status.keys_held & cfg.key_combination) != 0);
return (cfg.override_by_default ^ keys_triggered);
}
void ParseIniFile(util::ini::Handler handler, const char *path, void *user_ctx) {
@ -207,82 +206,45 @@ namespace ams::cfg {
}
bool IsHblOverrideKeyHeld(ncm::ProgramId program_id) {
OverrideStatus CaptureOverrideStatus(ncm::ProgramId program_id) {
OverrideStatus status = {};
/* If the SD card isn't initialized, we can't override. */
if (!IsSdCardInitialized()) {
return false;
return status;
}
/* For system modules and anything launched before the home menu, always override. */
if (program_id < ncm::ProgramId::AppletStart || !pm::info::HasLaunchedProgram(ncm::ProgramId::AppletQlaunch)) {
return true;
status.SetProgramSpecific();
return status;
}
/* Unconditionally refresh loader.ini contents. */
RefreshLoaderConfiguration();
/* Check HBL config. */
return IsHblProgramId(program_id) && IsOverrideKeyHeld(&g_hbl_override_config.override_key);
}
bool IsProgramOverrideKeyHeld(ncm::ProgramId program_id) {
/* If the SD card isn't initialized, we can't override. */
if (!IsSdCardInitialized()) {
return false;
/* If we can't read the key state, don't override anything. */
if (R_FAILED(hid::GetKeysHeld(&status.keys_held))) {
return status;
}
/* For system modules and anything launched before the home menu, always override. */
if (program_id < ncm::ProgramId::AppletStart || !pm::info::HasLaunchedProgram(ncm::ProgramId::AppletQlaunch)) {
return true;
/* Detect Hbl. */
if (IsHblProgramId(program_id) && IsOverrideMatch(status, g_hbl_override_config.override_key)) {
status.SetHbl();
}
/* Unconditionally refresh loader.ini contents. */
RefreshLoaderConfiguration();
/* Detect content specific keys. */
const auto content_cfg = GetContentOverrideConfig(program_id);
return IsOverrideKeyHeld(&content_cfg.override_key);
}
void GetOverrideKeyHeldStatus(bool *out_hbl, bool *out_program, ncm::ProgramId program_id) {
/* If the SD card isn't initialized, we can't override. */
if (!IsSdCardInitialized()) {
*out_hbl = false;
*out_program = false;
return;
if (IsOverrideMatch(status, content_cfg.override_key)) {
status.SetProgramSpecific();
}
/* For system modules and anything launched before the home menu, always override. */
if (program_id < ncm::ProgramId::AppletStart || !pm::info::HasLaunchedProgram(ncm::ProgramId::AppletQlaunch)) {
*out_hbl = false;
*out_program = true;
return;
/* Only allow cheat enable if not HBL. */
if (!status.IsHbl() && IsOverrideMatch(status, content_cfg.cheat_enable_key)) {
status.SetCheatEnabled();
}
/* Unconditionally refresh loader.ini contents. */
RefreshLoaderConfiguration();
/* Set HBL output. */
*out_hbl = IsHblProgramId(program_id) && IsOverrideKeyHeld(&g_hbl_override_config.override_key);
/* Set content specific output. */
const auto content_cfg = GetContentOverrideConfig(program_id);
*out_program = IsOverrideKeyHeld(&content_cfg.override_key);
}
bool IsCheatEnableKeyHeld(ncm::ProgramId program_id) {
/* If the SD card isn't initialized, don't apply cheats. */
if (!IsSdCardInitialized()) {
return false;
}
/* Don't apply cheats to HBL. */
if (IsHblOverrideKeyHeld(program_id)) {
return false;
}
const auto content_cfg = GetContentOverrideConfig(program_id);
return IsOverrideKeyHeld(&content_cfg.cheat_enable_key);
return status;
}
/* HBL Configuration utilities. */

View file

@ -31,3 +31,18 @@ Result ldrDmntAtmosphereHasLaunchedProgram(bool *out, u64 program_id) {
Result ldrPmAtmosphereHasLaunchedProgram(bool *out, u64 program_id) {
return _ldrAtmosphereHasLaunchedProgram(ldrPmGetServiceSession(), out, program_id);
}
Result ldrPmAtmosphereGetProgramInfo(LoaderProgramInfo *out_program_info, CfgOverrideStatus *out_status, const NcmProgramLocation *loc) {
return serviceDispatchInOut(ldrPmGetServiceSession(), 65001, *loc, *out_status,
.buffer_attrs = { SfBufferAttr_Out | SfBufferAttr_HipcPointer | SfBufferAttr_FixedSize },
.buffers = { { out_program_info, sizeof(*out_program_info) } },
);
}
Result ldrPmAtmospherePinProgram(u64 *out, const NcmProgramLocation *loc, const CfgOverrideStatus *status) {
const struct {
NcmProgramLocation loc;
CfgOverrideStatus status;
} in = { *loc, *status };
return serviceDispatchInOut(ldrPmGetServiceSession(), 65002, in, *out);
}

View file

@ -11,9 +11,17 @@
extern "C" {
#endif
typedef struct {
u64 keys_down;
u64 flags;
} CfgOverrideStatus;
Result ldrPmAtmosphereHasLaunchedProgram(bool *out, u64 program_id);
Result ldrDmntAtmosphereHasLaunchedProgram(bool *out, u64 program_id);
Result ldrPmAtmosphereGetProgramInfo(LoaderProgramInfo *out, CfgOverrideStatus *out_status, const NcmProgramLocation *loc);
Result ldrPmAtmospherePinProgram(u64 *out, const NcmProgramLocation *loc, const CfgOverrideStatus *status);
#ifdef __cplusplus
}
#endif

View file

@ -40,4 +40,15 @@ namespace ams::ldr::pm {
return ldrPmAtmosphereHasLaunchedProgram(out, static_cast<u64>(program_id));
}
Result AtmosphereGetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc) {
static_assert(sizeof(*out_status) == sizeof(CfgOverrideStatus), "CfgOverrideStatus definition!");
return ldrPmAtmosphereGetProgramInfo(reinterpret_cast<LoaderProgramInfo *>(out), reinterpret_cast<CfgOverrideStatus *>(out_status), reinterpret_cast<const NcmProgramLocation *>(&loc));
}
Result AtmospherePinProgram(PinId *out, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status) {
static_assert(sizeof(*out) == sizeof(u64), "PinId definition!");
static_assert(sizeof(status) == sizeof(CfgOverrideStatus), "CfgOverrideStatus definition!");
return ldrPmAtmospherePinProgram(reinterpret_cast<u64 *>(out), reinterpret_cast<const NcmProgramLocation *>(&loc), reinterpret_cast<const CfgOverrideStatus *>(&status));
}
}

View file

@ -28,10 +28,31 @@ Result pminfoAtmosphereHasLaunchedProgram(bool *out, u64 program_id) {
return rc;
}
Result pmdmntAtmosphereGetProcessInfo(Handle* handle_out, NcmProgramLocation *loc_out, u64 pid) {
Result pminfoAtmosphereGetProcessInfo(NcmProgramLocation *loc_out, CfgOverrideStatus *status_out, u64 pid) {
struct {
NcmProgramLocation loc;
CfgOverrideStatus status;
} out;
Result rc = serviceDispatchInOut(pmdmntGetServiceSession(), 65002, pid, out);
if (R_SUCCEEDED(rc)) {
if (loc_out) *loc_out = out.loc;
if (status_out) *status_out = out.status;
}
return rc;
}
Result pmdmntAtmosphereGetProcessInfo(Handle* handle_out, NcmProgramLocation *loc_out, CfgOverrideStatus *status_out, u64 pid) {
Handle tmp_handle;
Result rc = serviceDispatchInOut(pmdmntGetServiceSession(), 65000, pid, *loc_out,
struct {
NcmProgramLocation loc;
CfgOverrideStatus status;
} out;
Result rc = serviceDispatchInOut(pmdmntGetServiceSession(), 65000, pid, out,
.out_handle_attrs = { SfOutHandleAttr_HipcCopy },
.out_handles = &tmp_handle,
);
@ -42,6 +63,9 @@ Result pmdmntAtmosphereGetProcessInfo(Handle* handle_out, NcmProgramLocation *lo
} else {
svcCloseHandle(tmp_handle);
}
if (loc_out) *loc_out = out.loc;
if (status_out) *status_out = out.status;
}
return rc;

View file

@ -11,10 +11,16 @@
extern "C" {
#endif
typedef struct {
u64 keys_held;
u64 flags;
} CfgOverrideStatus;
Result pminfoAtmosphereGetProcessId(u64 *out_pid, u64 program_id);
Result pminfoAtmosphereHasLaunchedProgram(bool *out, u64 program_id);
Result pminfoAtmosphereGetProcessInfo(NcmProgramLocation *loc_out, CfgOverrideStatus *status_out, u64 pid);
Result pmdmntAtmosphereGetProcessInfo(Handle *out, NcmProgramLocation *loc_out, u64 pid);
Result pmdmntAtmosphereGetProcessInfo(Handle *out, NcmProgramLocation *loc_out, CfgOverrideStatus *status_out, u64 pid);
Result pmdmntAtmosphereGetCurrentLimitInfo(u64 *out_cur, u64 *out_lim, u32 group, u32 resource);
#ifdef __cplusplus

View file

@ -39,10 +39,12 @@ namespace ams::pm::dmnt {
return ResultSuccess();
}
Result AtmosphereGetProcessInfo(Handle *out_handle, ncm::ProgramLocation *out_loc, os::ProcessId process_id) {
Result AtmosphereGetProcessInfo(Handle *out_handle, ncm::ProgramLocation *out_loc, cfg::OverrideStatus *out_status, os::ProcessId process_id) {
*out_handle = INVALID_HANDLE;
*out_loc = {};
return pmdmntAtmosphereGetProcessInfo(out_handle, reinterpret_cast<NcmProgramLocation *>(out_loc), static_cast<u64>(process_id));
*out_status = {};
static_assert(sizeof(*out_status) == sizeof(CfgOverrideStatus));
return pmdmntAtmosphereGetProcessInfo(out_handle, reinterpret_cast<NcmProgramLocation *>(out_loc), reinterpret_cast<CfgOverrideStatus *>(out_status), static_cast<u64>(process_id));
}
Result AtmosphereGetCurrentLimitInfo(u64 *out_current_value, u64 *out_limit_value, ResourceLimitGroup group, LimitableResource resource) {

View file

@ -40,6 +40,15 @@ namespace ams::pm::info {
return pminfoAtmosphereGetProcessId(reinterpret_cast<u64 *>(out_process_id), static_cast<u64>(program_id));
}
Result GetProcessInfo(ncm::ProgramLocation *out_loc, cfg::OverrideStatus *out_status, os::ProcessId process_id) {
std::scoped_lock lk(g_info_lock);
*out_loc = {};
*out_status = {};
static_assert(sizeof(*out_status) == sizeof(CfgOverrideStatus));
return pminfoAtmosphereGetProcessInfo(reinterpret_cast<NcmProgramLocation *>(out_loc), reinterpret_cast<CfgOverrideStatus *>(out_status), static_cast<u64>(process_id));
}
Result WEAK HasLaunchedProgram(bool *out, ncm::ProgramId program_id) {
std::scoped_lock lk(g_info_lock);

View file

@ -30,8 +30,8 @@ namespace ams::sf::hipc::impl {
public:
MitmQueryService(ServerManagerBase::MitmQueryFunction qf) : query_function(qf) { /* ... */ }
void ShouldMitm(sf::Out<bool> out, os::ProcessId process_id, ncm::ProgramId program_id) {
out.SetValue(this->query_function(process_id, program_id));
void ShouldMitm(sf::Out<bool> out, const sm::MitmProcessInfo &client_info) {
out.SetValue(this->query_function(client_info));
}
public:
DEFINE_SERVICE_DISPATCH_TABLE {

View file

@ -107,21 +107,16 @@ Result smAtmosphereMitmDeclareFuture(SmServiceName name) {
return _smAtmosphereCmdInServiceNameNoOut(name, smGetServiceSession(), 65006);
}
Result smAtmosphereMitmAcknowledgeSession(Service *srv_out, u64 *pid_out, u64 *tid_out, SmServiceName name) {
Result smAtmosphereMitmAcknowledgeSession(Service *srv_out, void *_out, SmServiceName name) {
struct {
u64 pid;
u64 tid;
} out;
u64 process_id;
u64 program_id;
u64 keys_held;
u64 flags;
} *out = _out;
Result rc = serviceDispatchInOut(&g_smAtmosphereMitmSrv, 65003, name, out,
return serviceDispatchInOut(&g_smAtmosphereMitmSrv, 65003, name, *out,
.out_num_objects = 1,
.out_objects = srv_out,
);
if (R_SUCCEEDED(rc)) {
if (pid_out) *pid_out = out.pid;
if (tid_out) *tid_out = out.tid;
}
return rc;
}

View file

@ -28,7 +28,7 @@ void smAtmosphereCloseSession(Service *srv);
Result smAtmosphereMitmInstall(Service *fwd_srv, Handle *handle_out, Handle *query_out, SmServiceName name);
Result smAtmosphereMitmUninstall(SmServiceName name);
Result smAtmosphereMitmDeclareFuture(SmServiceName name);
Result smAtmosphereMitmAcknowledgeSession(Service *srv_out, u64 *pid_out, u64 *tid_out, SmServiceName name);
Result smAtmosphereMitmAcknowledgeSession(Service *srv_out, void *info_out, SmServiceName name);
#ifdef __cplusplus
}

View file

@ -19,8 +19,9 @@
namespace ams::sm::manager {
/* Manager API. */
Result RegisterProcess(os::ProcessId process_id, ncm::ProgramId program_id, const void *acid, size_t acid_size, const void *aci, size_t aci_size) {
return smManagerAtmosphereRegisterProcess(static_cast<u64>(process_id), static_cast<u64>(program_id), acid, acid_size, aci, aci_size);
Result RegisterProcess(os::ProcessId process_id, ncm::ProgramId program_id, cfg::OverrideStatus status, const void *acid, size_t acid_size, const void *aci, size_t aci_size) {
static_assert(sizeof(status) == sizeof(CfgOverrideStatus), "CfgOverrideStatus definition");
return smManagerAtmosphereRegisterProcess(static_cast<u64>(process_id), static_cast<u64>(program_id), reinterpret_cast<const CfgOverrideStatus *>(&status), acid, acid_size, aci, aci_size);
}
Result UnregisterProcess(os::ProcessId process_id) {

View file

@ -36,9 +36,9 @@ namespace ams::sm::mitm {
});
}
Result AcknowledgeSession(Service *out_service, os::ProcessId *out_process_id, ncm::ProgramId *out_program_id, ServiceName name) {
Result AcknowledgeSession(Service *out_service, MitmProcessInfo *out_info, ServiceName name) {
return impl::DoWithMitmAcknowledgementSession([&]() {
return smAtmosphereMitmAcknowledgeSession(out_service, &out_process_id->value, &out_program_id->value, impl::ConvertName(name));
return smAtmosphereMitmAcknowledgeSession(out_service, reinterpret_cast<void *>(out_info), impl::ConvertName(name));
});
}

View file

@ -19,11 +19,12 @@ Result smManagerAtmosphereEndInitialDefers(void) {
return serviceDispatch(smManagerGetServiceSession(), 65000);
}
Result smManagerAtmosphereRegisterProcess(u64 pid, u64 tid, const void *acid_sac, size_t acid_sac_size, const void *aci_sac, size_t aci_sac_size) {
Result smManagerAtmosphereRegisterProcess(u64 pid, u64 tid, const CfgOverrideStatus *status, const void *acid_sac, size_t acid_sac_size, const void *aci_sac, size_t aci_sac_size) {
const struct {
u64 pid;
u64 tid;
} in = { pid, tid };
CfgOverrideStatus status;
} in = { pid, tid, *status };
return serviceDispatchIn(smManagerGetServiceSession(), 65002, in,
.buffer_attrs = {
SfBufferAttr_In | SfBufferAttr_HipcMapAlias,

View file

@ -11,8 +11,13 @@
extern "C" {
#endif
typedef struct {
u64 keys_held;
u64 flags;
} CfgOverrideStatus;
Result smManagerAtmosphereEndInitialDefers(void);
Result smManagerAtmosphereRegisterProcess(u64 pid, u64 tid, const void *acid_sac, size_t acid_sac_size, const void *aci_sac, size_t aci_sac_size);
Result smManagerAtmosphereRegisterProcess(u64 pid, u64 tid, const CfgOverrideStatus *status, const void *acid_sac, size_t acid_sac_size, const void *aci_sac, size_t aci_sac_size);
Result smManagerAtmosphereHasMitm(bool *out, SmServiceName name);
#ifdef __cplusplus