From a628528cd8c6a127a7f28cdbd8276fbe2bbc55ec Mon Sep 17 00:00:00 2001 From: kotori0 Date: Wed, 2 Feb 2022 01:31:51 +0800 Subject: [PATCH] Fix memory leaks && use RAII on obfuscation methods --- core/src/main/cpp/main/api/riru_main.cpp | 2 +- core/src/main/cpp/main/api/zygisk_main.cpp | 2 +- core/src/main/cpp/main/include/jni_helper.h | 6 +++- core/src/main/cpp/main/src/context.cpp | 4 +-- core/src/main/cpp/main/src/jni/yahfa.cpp | 15 ++++---- core/src/main/cpp/main/src/service.cpp | 11 +++--- daemon/src/main/cpp/obfuscation.cpp | 38 +++++++++++++++------ 7 files changed, 48 insertions(+), 30 deletions(-) diff --git a/core/src/main/cpp/main/api/riru_main.cpp b/core/src/main/cpp/main/api/riru_main.cpp index 4404f7a2..00c2499b 100644 --- a/core/src/main/cpp/main/api/riru_main.cpp +++ b/core/src/main/cpp/main/api/riru_main.cpp @@ -15,7 +15,7 @@ * along with LSPosed. If not, see . * * Copyright (C) 2020 EdXposed Contributors - * Copyright (C) 2021 LSPosed Contributors + * Copyright (C) 2021 - 2022 LSPosed Contributors */ #include diff --git a/core/src/main/cpp/main/api/zygisk_main.cpp b/core/src/main/cpp/main/api/zygisk_main.cpp index f78049ca..2bd44ca4 100644 --- a/core/src/main/cpp/main/api/zygisk_main.cpp +++ b/core/src/main/cpp/main/api/zygisk_main.cpp @@ -328,7 +328,7 @@ namespace lspd { auto *process = env_->FindClass("android/os/Process"); auto *set_argv0 = env_->GetStaticMethodID(process, "setArgV0", "(Ljava/lang/String;)V"); - env_->CallStaticVoidMethod(process, set_argv0, env_->NewStringUTF("system_server")); + JNI_CallStaticVoidMethod(env_, process, set_argv0, JNI_NewStringUTF(env_, "system_server")); } Context::GetInstance()->OnNativeForkSystemServerPost(env_); } diff --git a/core/src/main/cpp/main/include/jni_helper.h b/core/src/main/cpp/main/include/jni_helper.h index 17a0ab35..7eea74c2 100644 --- a/core/src/main/cpp/main/include/jni_helper.h +++ b/core/src/main/cpp/main/include/jni_helper.h @@ -15,7 +15,7 @@ * along with LSPosed. If not, see . * * Copyright (C) 2020 EdXposed Contributors - * Copyright (C) 2021 LSPosed Contributors + * Copyright (C) 2021 - 2022 LSPosed Contributors */ #pragma once @@ -191,6 +191,10 @@ inline auto wrap_scope(JNIEnv *env, T &&x) { } else return x; } +inline auto JNI_NewStringUTF(JNIEnv *env, std::string_view sv) { + return ScopedLocalRef(env, env->NewStringUTF(sv.data())); +} + template requires(std::is_function_v) [[maybe_unused]] diff --git a/core/src/main/cpp/main/src/context.cpp b/core/src/main/cpp/main/src/context.cpp index e98445ea..298ec9e4 100644 --- a/core/src/main/cpp/main/src/context.cpp +++ b/core/src/main/cpp/main/src/context.cpp @@ -15,7 +15,7 @@ * along with LSPosed. If not, see . * * Copyright (C) 2020 EdXposed Contributors - * Copyright (C) 2021 LSPosed Contributors + * Copyright (C) 2021 - 2022 LSPosed Contributors */ #include @@ -147,7 +147,7 @@ namespace lspd { } if (mid) [[likely]] { auto target = JNI_CallObjectMethod(env, class_loader, mid, - env->NewStringUTF(class_name.data())); + JNI_NewStringUTF(env, class_name.data())); if (target) { return target; } diff --git a/core/src/main/cpp/main/src/jni/yahfa.cpp b/core/src/main/cpp/main/src/jni/yahfa.cpp index f903522c..501381c3 100644 --- a/core/src/main/cpp/main/src/jni/yahfa.cpp +++ b/core/src/main/cpp/main/src/jni/yahfa.cpp @@ -15,7 +15,7 @@ * along with LSPosed. If not, see . * * Copyright (C) 2020 EdXposed Contributors - * Copyright (C) 2021 LSPosed Contributors + * Copyright (C) 2021 - 2022 LSPosed Contributors */ #include "yahfa.h" @@ -36,7 +36,7 @@ namespace lspd { std::unordered_set hooked_methods_; std::shared_mutex hooked_methods_lock_; - std::vector> jit_movements_; + std::vector> jit_movements_; std::shared_mutex jit_movements_lock_; std::string obfuscated_signature_; @@ -52,12 +52,12 @@ namespace lspd { hooked_methods_.insert(art_method); } - void recordJitMovement(void *target, void* backup) { + void recordJitMovement(void *target, void *backup) { std::unique_lock lk(jit_movements_lock_); jit_movements_.emplace_back(target, backup); } - std::vector> getJitMovements() { + std::vector> getJitMovements() { std::unique_lock lk(jit_movements_lock_); return std::move(jit_movements_); } @@ -197,10 +197,9 @@ namespace lspd { "(Ljava/lang/String;)Ljava/lang/Class;"); } if (my_cl) { - auto target = JNI_CallObjectMethod(env, my_cl, kMid, env->NewStringUTF("LspHooker_")); - if (target) { - return (jclass) target.release(); - } + auto target = JNI_CallObjectMethod(env, my_cl, kMid, + JNI_NewStringUTF(env, "LspHooker_")); + if (target) return (jclass) target.release(); } return nullptr; } diff --git a/core/src/main/cpp/main/src/service.cpp b/core/src/main/cpp/main/src/service.cpp index 5d3a8533..4a598a0f 100644 --- a/core/src/main/cpp/main/src/service.cpp +++ b/core/src/main/cpp/main/src/service.cpp @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with LSPosed. If not, see . * - * Copyright (C) 2021 LSPosed Contributors + * Copyright (C) 2021 - 2022 LSPosed Contributors */ // @@ -215,8 +215,7 @@ namespace lspd { return {env, nullptr}; } - // TODO: memory leak? - auto *bridge_service_name = env->NewStringUTF(BRIDGE_SERVICE_NAME.data()); + auto bridge_service_name = JNI_NewStringUTF(env, BRIDGE_SERVICE_NAME.data()); auto bridge_service = JNI_CallStaticObjectMethod(env, service_manager_class_, get_service_method_, bridge_service_name); if (!bridge_service) { @@ -229,7 +228,7 @@ namespace lspd { auto data = JNI_CallStaticObjectMethod(env, parcel_class_, obtain_method_); auto reply = JNI_CallStaticObjectMethod(env, parcel_class_, obtain_method_); - auto *descriptor = env->NewStringUTF(BRIDGE_SERVICE_DESCRIPTOR.data()); + auto descriptor = JNI_NewStringUTF(env, BRIDGE_SERVICE_DESCRIPTOR.data()); JNI_CallVoidMethod(env, data, write_interface_token_method_, descriptor); JNI_CallVoidMethod(env, data, write_int_method_, BRIDGE_ACTION_GET_BINDER); JNI_CallVoidMethod(env, data, write_string_method_, nice_name); @@ -261,7 +260,7 @@ namespace lspd { } // Get Binder for LSPSystemServerService. // The binder itself was inject into system service "serial" - auto *bridge_service_name = env->NewStringUTF(SYSTEM_SERVER_BRIDGE_SERVICE_NAME.data()); + auto bridge_service_name = JNI_NewStringUTF(env, SYSTEM_SERVER_BRIDGE_SERVICE_NAME); ScopedLocalRef binder{env, nullptr}; for (int i = 0; i < 3; ++i) { binder = JNI_CallStaticObjectMethod(env, service_manager_class_, @@ -285,7 +284,7 @@ namespace lspd { JNI_CallVoidMethod(env, data, write_int_method_, getuid()); // data.writeInt(uid) JNI_CallVoidMethod(env, data, write_int_method_, getpid()); - JNI_CallVoidMethod(env, data, write_string_method_, env->NewStringUTF("android")); + JNI_CallVoidMethod(env, data, write_string_method_, JNI_NewStringUTF(env, "android")); JNI_CallVoidMethod(env, data, write_strong_binder_method_, heart_beat_binder); auto res = JNI_CallBooleanMethod(env, binder, transact_method_, diff --git a/daemon/src/main/cpp/obfuscation.cpp b/daemon/src/main/cpp/obfuscation.cpp index 7c0883c1..4dc88eb9 100644 --- a/daemon/src/main/cpp/obfuscation.cpp +++ b/daemon/src/main/cpp/obfuscation.cpp @@ -1,3 +1,22 @@ +/* + * This file is part of LSPosed. + * + * LSPosed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LSPosed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LSPosed. If not, see . + * + * Copyright (C) 2022 LSPosed Contributors + */ + // // Created by Kotori2 on 2021/12/1. // @@ -89,14 +108,11 @@ ustring obfuscateDex(void *dex, size_t size) { return new_dex; } -jobject new_sharedmem(JNIEnv* env, jint size) { - jclass clazz = env->FindClass("android/os/SharedMemory"); - auto *ref = env->NewGlobalRef(clazz); - jmethodID mid = env->GetStaticMethodID(clazz, "create", "(Ljava/lang/String;I)Landroid/os/SharedMemory;"); - jstring empty_str = env->NewStringUTF(""); - jobject new_mem = env->CallStaticObjectMethod(clazz, mid, empty_str, static_cast(size)); - env->DeleteGlobalRef(ref); - env->DeleteLocalRef(empty_str); +ScopedLocalRef new_sharedmem(JNIEnv* env, jint size) { + auto clazz = JNI_FindClass(env, "android/os/SharedMemory"); + auto mid = JNI_GetStaticMethodID(env, clazz, "create", "(Ljava/lang/String;I)Landroid/os/SharedMemory;"); + auto empty_str = JNI_NewStringUTF(env, ""); + auto new_mem = JNI_CallStaticObjectMethod(env, clazz, mid, empty_str, static_cast(size)); return new_mem; } @@ -133,7 +149,7 @@ Java_org_lsposed_lspd_service_ObfuscationManager_preloadDex(JNIEnv *env, jclass auto new_dex = obfuscateDex(addr, size); LOGD("LSPApplicationService::preloadDex: %p, size=%zu", new_dex.data(), new_dex.size()); auto new_mem = new_sharedmem(env, new_dex.size()); - lspdDex = env->NewGlobalRef(new_mem); + lspdDex = JNI_NewGlobalRef(env, new_mem); auto new_fd = ASharedMemory_dupFromJava(env, lspdDex); auto new_addr = mmap(nullptr, new_dex.size(), PROT_READ | PROT_WRITE, MAP_SHARED, new_fd, 0); if (new_addr == MAP_FAILED) { @@ -170,7 +186,7 @@ Java_org_lsposed_lspd_service_ObfuscationManager_obfuscateDex(JNIEnv *env, jclas // create new SharedMem since it cannot be resized auto new_mem = new_sharedmem(env, new_dex.size()); - int new_fd = ASharedMemory_dupFromJava(env, new_mem); + int new_fd = ASharedMemory_dupFromJava(env, new_mem.get()); mem = mmap(nullptr, new_dex.size(), PROT_READ | PROT_WRITE, MAP_SHARED, new_fd, 0); if (mem == MAP_FAILED) { @@ -178,5 +194,5 @@ Java_org_lsposed_lspd_service_ObfuscationManager_obfuscateDex(JNIEnv *env, jclas } memcpy(mem, new_dex.data(), new_dex.size()); ASharedMemory_setProt(fd, PROT_READ); - return new_mem; + return new_mem.release(); } \ No newline at end of file