diff --git a/.github/workflows/kpmmgr.yml b/.github/workflows/kpmmgr.yml new file mode 100644 index 00000000..18ba4513 --- /dev/null +++ b/.github/workflows/kpmmgr.yml @@ -0,0 +1,40 @@ +name: Build kpmmgr + +on: + push: + branches: [ "mian" ] + paths: + - '.github/workflows/kpmmgr.yml' + - 'userspace/kpmmgr/**' + workflow_dispatch: + workflow_call: + inputs: + target: + required: true + type: string + os: + required: false + type: string + default: self-hosted + +jobs: + build-susfs: + name: Build userspace kpmmgr + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Build kpmmgr + working-directory: ./userspace/kpmmgr + run: | + $ANDROID_NDK_HOME/ndk-build + + - name: Upload a Build Artifact + uses: actions/upload-artifact@v4 + with: + name: kpmmgr-aarch64-linux-android + path: ./userspace/kpmmgr/libs diff --git a/userspace/kpmmgr/.gitignore b/userspace/kpmmgr/.gitignore new file mode 100644 index 00000000..4b4ce0f2 --- /dev/null +++ b/userspace/kpmmgr/.gitignore @@ -0,0 +1,2 @@ +/obj +/libs \ No newline at end of file diff --git a/userspace/kpmmgr/jni/Android.mk b/userspace/kpmmgr/jni/Android.mk new file mode 100644 index 00000000..a278158f --- /dev/null +++ b/userspace/kpmmgr/jni/Android.mk @@ -0,0 +1,6 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_MODULE := kpmmgr +LOCAL_SRC_FILES := kpmmgr.c +include $(BUILD_EXECUTABLE) diff --git a/userspace/kpmmgr/jni/Application.mk b/userspace/kpmmgr/jni/Application.mk new file mode 100644 index 00000000..873252b9 --- /dev/null +++ b/userspace/kpmmgr/jni/Application.mk @@ -0,0 +1,3 @@ +APP_ABI := arm64-v8a x86_64 +APP_PLATFORM := android-24 +APP_STL := none diff --git a/userspace/kpmmgr/jni/kpmmgr.c b/userspace/kpmmgr/jni/kpmmgr.c new file mode 100644 index 00000000..befc97ce --- /dev/null +++ b/userspace/kpmmgr/jni/kpmmgr.c @@ -0,0 +1,86 @@ +#include +#include +#include +#include +#include +#include + +#define KSU_OPTIONS 0xdeadbeef + +// KPM控制代码 +#define CMD_KPM_CONTROL 28 +#define CMD_KPM_CONTROL_MAX 7 + +// 控制代码 +#define SUKISU_KPM_LOAD 1 +#define SUKISU_KPM_UNLOAD 2 +#define SUKISU_KPM_NUM 3 +#define SUKISU_KPM_LIST 4 +#define SUKISU_KPM_INFO 5 +#define SUKISU_KPM_CONTROL 6 +#define SUKISU_KPM_PRINT 7 + +#define CONTROL_CODE(n) (CMD_KPM_CONTROL + n) + +void print_usage(const char *prog) { + printf("Usage: %s [args]\n", prog); + printf("Commands:\n"); + printf(" load Load a KPM module\n"); + printf(" unload Unload a KPM module\n"); + printf(" num Get number of loaded modules\n"); + printf(" list List loaded KPM modules\n"); + printf(" info Get info of a KPM module\n"); + printf(" control Send control command to a KPM module\n"); + printf(" print Print KPM module list to stdout\n"); +} + +int main(int argc, char *argv[]) { + if (argc < 2) { + print_usage(argv[0]); + return 1; + } + + int ret = -1; + int out = 0; // 存储返回值 + + if (strcmp(argv[1], "load") == 0 && argc >= 3) { + // 加载 KPM 模块 + ret = prctl(KSU_OPTIONS, CONTROL_CODE(SUKISU_KPM_LOAD), argv[2], (argc > 3 ? argv[3] : NULL), &out); + } else if (strcmp(argv[1], "unload") == 0 && argc >= 3) { + // 卸载 KPM 模块 + ret = prctl(KSU_OPTIONS, CONTROL_CODE(SUKISU_KPM_UNLOAD), argv[2], &out); + } else if (strcmp(argv[1], "num") == 0) { + // 获取加载的 KPM 数量 + ret = prctl(KSU_OPTIONS, CONTROL_CODE(SUKISU_KPM_NUM), &out); + } else if (strcmp(argv[1], "list") == 0) { + // 获取模块列表 + char buffer[1024] = {0}; + ret = prctl(KSU_OPTIONS, CONTROL_CODE(SUKISU_KPM_LIST), buffer, sizeof(buffer), &out); + if (ret >= 0) { + printf("%s", buffer); + } + } else if (strcmp(argv[1], "info") == 0 && argc >= 3) { + // 获取指定模块信息 + char buffer[256] = {0}; + ret = prctl(KSU_OPTIONS, CONTROL_CODE(SUKISU_KPM_INFO), argv[2], buffer, &out); + if (ret >= 0) { + printf("%s\n", buffer); + } + } else if (strcmp(argv[1], "control") == 0 && argc >= 4) { + // 控制 KPM 模块 + ret = prctl(KSU_OPTIONS, CONTROL_CODE(SUKISU_KPM_CONTROL), argv[2], argv[3], &out); + } else if (strcmp(argv[1], "print") == 0) { + // 在 stdout 输出 KPM 列表 + ret = prctl(KSU_OPTIONS, CONTROL_CODE(SUKISU_KPM_PRINT), &out); + } else { + print_usage(argv[0]); + return 1; + } + + if (ret < 0) { + printf("Error: %s\n", strerror(errno)); + return -1; + } + + return 0; +}