#include #include #include #include #include #include #include "zygisk.hpp" #define LOG_TAG "CamSwapperZygisk" #define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) #define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) #define HOOK_LIB_PATH "/data/local/camera_magic/libcamera_hook.so" using zygisk::Api; using zygisk::AppSpecializeArgs; using zygisk::ServerSpecializeArgs; static bool is_camera_process(const char *process_name) { if (!process_name) return false; return (strstr(process_name, "cameraserver") != nullptr) || (strstr(process_name, "camera.provider") != nullptr) || (strstr(process_name, "android.hardware.camera") != nullptr); } class CamSwapperModule : public zygisk::ModuleBase { public: void onLoad(Api *api, JNIEnv *env) override { this->api = api; this->env = env; ALOGI("CamSwapper Zygisk module loaded"); } void preAppSpecialize(AppSpecializeArgs *args) override { if (args && args->nice_name) { const char *process = env->GetStringUTFChars(args->nice_name, nullptr); if (process) { ALOGI("preAppSpecialize: %s", process); env->ReleaseStringUTFChars(args->nice_name, process); } } } void postAppSpecialize(const AppSpecializeArgs *args) override { if (args && args->nice_name) { const char *process = env->GetStringUTFChars(args->nice_name, nullptr); if (process) { ALOGI("postAppSpecialize: %s", process); if (is_camera_process(process)) { ALOGI("Loading hook in camera app: %s", process); load_hook_lib(); } env->ReleaseStringUTFChars(args->nice_name, process); } } } void preServerSpecialize(ServerSpecializeArgs *args) override { ALOGI("preServerSpecialize: system_server"); } void postServerSpecialize(const ServerSpecializeArgs *args) override { ALOGI("postServerSpecialize: system_server ready, loading hook"); load_hook_lib(); } private: Api *api; JNIEnv *env; void load_hook_lib() { struct stat st; if (stat(HOOK_LIB_PATH, &st) != 0) { ALOGE("Hook library not found: %s", HOOK_LIB_PATH); return; } void *handle = dlopen(HOOK_LIB_PATH, RTLD_NOW | RTLD_LOCAL); if (!handle) { ALOGE("dlopen(%s) failed: %s", HOOK_LIB_PATH, dlerror()); return; } ALOGI("Hook library loaded: %s (handle=%p)", HOOK_LIB_PATH, handle); } }; REGISTER_ZYGISK_MODULE(CamSwapperModule)