summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReiko Asakura2021-02-28 23:59:02 -0500
committerReiko Asakura2021-02-28 23:59:02 -0500
commit97e52cd700fc1879c4cf3bfb9b82673ab1968883 (patch)
treea6459cec0dda1da18270f45ef73f1a2c79204fe6
parentRefactor module NID lookup functions (diff)
downloadmusicpremium-97e52cd700fc1879c4cf3bfb9b82673ab1968883.tar.gz
Refactor hook and inject functions
-rw-r--r--CMakeLists.txt1
-rw-r--r--musicpremium.c54
-rw-r--r--patch.c79
-rw-r--r--patch.h37
4 files changed, 133 insertions, 38 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e770894..9fb76f5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -43,6 +43,7 @@ add_library("${ELF}" MODULE
musicpremium.emd
module.c
opcode.c
+ patch.c
)
target_link_libraries("${ELF}"
diff --git a/musicpremium.c b/musicpremium.c
index 213c021..bcafc4c 100644
--- a/musicpremium.c
+++ b/musicpremium.c
@@ -14,6 +14,7 @@
#include "module.h"
#include "opcode.h"
+#include "patch.h"
#define GLZ(x) do {\
if ((x) < 0) { goto fail; }\
@@ -29,24 +30,11 @@
#define STREQ(s1, s2) (strncmp(s1, s2, sizeof(s1)) == 0)
-#define INJECT_ABS(idx, dest, src, size)\
- (inject_id[idx] = taiInjectAbsForKernel(\
- KERNEL_PID, dest, src, size))
-
-#define HOOK_EXPORT(idx, mod, libnid, funcnid, func)\
- (hook_id[idx] = taiHookFunctionExportForKernel(\
- KERNEL_PID, hook_ref+idx, mod, libnid, funcnid, func##_hook))
-
-#define HOOK_ABS(idx, addr, func)\
- (hook_id[idx] = taiHookFunctionAbs(\
- KERNEL_PID, hook_ref+idx, addr, func##_hook))
-
-#define N_INJECT 1
-static SceUID inject_id[N_INJECT];
-
-#define N_HOOK 2
-static SceUID hook_id[N_HOOK];
-static tai_hook_ref_t hook_ref[N_HOOK];
+SceUID bgm_port_priority_patch_id = -1;
+SceUID sceAudioOutOpenPort_hook_id = -1;
+tai_hook_ref_t sceAudioOutOpenPort_hook_ref;
+SceUID sceAppMgrAcquireBgmPort_impl_hook_id = -1;
+tai_hook_ref_t sceAppMgrAcquireBgmPort_impl_hook_ref;
static int (*sceAppMgrAcquireBgmPortWithPriority)(int priority);
static int (*sceAppMgrReleaseBgmPort)(void);
@@ -81,12 +69,12 @@ static int sceAudioOutOpenPort_hook(int portType, int len, int freq, int param)
// redirect to voice port if not Adrenaline
if (GET_MODULE(SCE_KERNEL_PROCESS_ID_SELF, "AdrenalineUser", &minfo) < 0) {
- port = TAI_CONTINUE(int, hook_ref[0], SCE_AUDIO_OUT_PORT_TYPE_VOICE, len, freq, param);
+ port = HOOK_NEXT(sceAudioOutOpenPort, SCE_AUDIO_OUT_PORT_TYPE_VOICE, len, freq, param);
goto done;
}
}
- port = TAI_CONTINUE(int, hook_ref[0], portType, len, freq, param);
+ port = HOOK_NEXT(sceAudioOutOpenPort, portType, len, freq, param);
done:
return port;
@@ -100,36 +88,26 @@ static int sceAppMgrAcquireBgmPort_impl_hook(void) {
sceKernelGetProcessTitleId(SCE_KERNEL_PROCESS_ID_SELF, tid, sizeof(tid));
if (STREQ(tid, "VITASHELL") || STREQ(tid, "ELEVENMPV")) {
- ret = TAI_CONTINUE(int, hook_ref[1]);
+ ret = HOOK_NEXT(sceAppMgrAcquireBgmPort_impl);
if (ret == 0) { sceAppMgrReleaseBgmPort(); }
ret = sceAppMgrAcquireBgmPortWithPriority(0x82);
goto done;
}
}
- ret = TAI_CONTINUE(int, hook_ref[1]);
+ ret = HOOK_NEXT(sceAppMgrAcquireBgmPort_impl);
done:
return ret;
}
-static void startup(void) {
- memset(inject_id, 0xFF, sizeof(inject_id));
- memset(hook_id, 0xFF, sizeof(hook_id));
- memset(hook_ref, 0xFF, sizeof(hook_ref));
-}
-
static void cleanup(void) {
- for (int i = 0; i < N_INJECT; i++) {
- if (inject_id[i] >= 0) { taiInjectReleaseForKernel(inject_id[i]); }
- }
- for (int i = 0; i < N_HOOK; i++) {
- if (hook_id[i] >= 0) { taiHookReleaseForKernel(hook_id[i], hook_ref[i]); }
- }
+ UNINJECT(bgm_port_priority);
+ UNHOOK(sceAudioOutOpenPort);
+ UNHOOK(sceAppMgrAcquireBgmPort_impl);
}
int module_start(SceSize argc, const void *argv) { (void)argc; (void)argv;
- startup();
// get SceAppMgr exports
GLZ(GET_EXPORT("SceAppMgr", 0x8AF17416, 0xAAED7419, (void *)&sceAppMgrAcquireBgmPortWithPriority));
@@ -140,10 +118,10 @@ int module_start(SceSize argc, const void *argv) { (void)argc; (void)argv;
GLZ(get_addr(&inject_addr, &hook_addr));
// mov.w r3, #0x78
- GLZ(INJECT_ABS(0, inject_addr, "\x4f\xf0\x78\x03", 4));
+ GLZ(INJECT_ABS(inject_addr, "\x4f\xf0\x78\x03", 4, bgm_port_priority));
- GLZ(HOOK_EXPORT(0, "SceAudio", 0x438BB957, 0x5BC341E4, sceAudioOutOpenPort));
- GLZ(HOOK_ABS(1, hook_addr, sceAppMgrAcquireBgmPort_impl));
+ GLZ(HOOK_EXPORT("SceAudio", 0x438BB957, 0x5BC341E4, sceAudioOutOpenPort));
+ GLZ(HOOK_ABS(hook_addr, sceAppMgrAcquireBgmPort_impl));
return SCE_KERNEL_START_SUCCESS;
diff --git a/patch.c b/patch.c
new file mode 100644
index 0000000..ea233bf
--- /dev/null
+++ b/patch.c
@@ -0,0 +1,79 @@
+/*
+ Copyright (C) 2020-2021 Reiko Asakura. All Rights Reserved.
+
+ Music Premium
+*/
+
+#include <libdbg.h>
+
+#include "patch.h"
+
+/* ARGSUSED */
+int hook_export(
+ const char *module, uint32_t libnid, uint32_t funcnid, const void *func,
+ SceUID *hook_id, tai_hook_ref_t *hook_ref, const char *name)
+{
+ *hook_id = taiHookFunctionExportForKernel(KERNEL_PID, hook_ref, module, libnid, funcnid, func);
+ if (*hook_id < 0) {
+ SCE_DBG_LOG_ERROR("Failed to hook %s %08X", name, *hook_id);
+ } else {
+ SCE_DBG_LOG_INFO("Hooked %s %08X", name, *hook_id);
+ }
+ return *hook_id;
+}
+
+/* ARGSUSED */
+int hook_abs(void *dest, const void *func, SceUID *hook_id, tai_hook_ref_t *hook_ref, const char *name) {
+ *hook_id = taiHookFunctionAbs(KERNEL_PID, hook_ref, dest, func);
+ if (*hook_id < 0) {
+ SCE_DBG_LOG_ERROR("Failed to hook %s %08X", name, *hook_id);
+ } else {
+ SCE_DBG_LOG_INFO("Hooked %s %08X", name, *hook_id);
+ }
+ return *hook_id;
+}
+
+/* ARGSUSED */
+int unhook(SceUID *hook_id, tai_hook_ref_t hook_ref, const char *name) {
+ int ret = SCE_OK;
+ if (*hook_id < 0) {
+ SCE_DBG_LOG_WARNING("Skipped unhooking %s %08X", name, *hook_id);
+ } else {
+ ret = taiHookReleaseForKernel(*hook_id, hook_ref);
+ if (ret == SCE_OK) {
+ SCE_DBG_LOG_INFO("Unhooked %s %08X", name, *hook_id);
+ *hook_id = -1;
+ } else {
+ SCE_DBG_LOG_ERROR("Failed to unhook %s %08X %08X", name, *hook_id, ret);
+ }
+ }
+ return ret;
+}
+
+/* ARGSUSED */
+int inject_abs(void *dest, const void *src, size_t size, SceUID *inject_id, const char *name) {
+ *inject_id = taiInjectAbsForKernel(KERNEL_PID, dest, src, size);
+ if (*inject_id < 0) {
+ SCE_DBG_LOG_ERROR("Failed to inject %s %08X", name, *inject_id);
+ } else {
+ SCE_DBG_LOG_INFO("Injected %s %08X", name, *inject_id);
+ }
+ return *inject_id;
+}
+
+/* ARGSUSED */
+int uninject(SceUID *inject_id, const char *name) {
+ int ret = SCE_OK;
+ if (*inject_id < 0) {
+ SCE_DBG_LOG_WARNING("Skipped uninjecting %s %08X", name, *inject_id);
+ } else {
+ ret = taiInjectReleaseForKernel(*inject_id);
+ if (ret == SCE_OK) {
+ SCE_DBG_LOG_INFO("Uninjected %s %08X", name, *inject_id);
+ *inject_id = -1;
+ } else {
+ SCE_DBG_LOG_ERROR("Failed to uninject %s %08X %08X", name, *inject_id, ret);
+ }
+ }
+ return ret;
+}
diff --git a/patch.h b/patch.h
new file mode 100644
index 0000000..126c17c
--- /dev/null
+++ b/patch.h
@@ -0,0 +1,37 @@
+/*
+ Copyright (C) 2020-2021 Reiko Asakura. All Rights Reserved.
+
+ Music Premium
+*/
+
+#ifndef PATCH_H_
+#define PATCH_H_
+
+#include <taihen.h>
+
+#define HOOK_NEXT(func, ...) TAI_NEXT(func##_hook, func##_hook_ref, ##__VA_ARGS__)
+
+#define HOOK_EXPORT(module, libnid, funcnid, func) \
+ hook_export(module, libnid, funcnid, func##_hook, &func##_hook_id, &func##_hook_ref, #func)
+
+#define HOOK_ABS(dest, func) hook_abs(dest, func##_hook, &func##_hook_id, &func##_hook_ref, #func)
+
+#define UNHOOK(func) unhook(&func##_hook_id, func##_hook_ref, #func)
+
+#define INJECT_ABS(dest, src, size, name) inject_abs(dest, src, size, &name##_patch_id, #name)
+
+#define UNINJECT(name) uninject(&name##_patch_id, #name)
+
+int hook_export(
+ const char *module, uint32_t libnid, uint32_t funcnid, const void *func,
+ SceUID *hook_id, tai_hook_ref_t *hook_ref, const char *name);
+
+int hook_abs(void *dest, const void *func, SceUID *hook_id, tai_hook_ref_t *hook_ref, const char *name);
+
+int unhook(SceUID *hook_id, tai_hook_ref_t hook_ref, const char *name);
+
+int inject_abs(void *dest, const void *src, size_t size, SceUID *inject_id, const char *name);
+
+int uninject(SceUID *inject_id, const char *name);
+
+#endif