Fix memory leaks && use RAII on obfuscation methods
This commit is contained in:
parent
8d2a8c4c3f
commit
a628528cd8
|
|
@ -15,7 +15,7 @@
|
||||||
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
|
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020 EdXposed Contributors
|
* Copyright (C) 2020 EdXposed Contributors
|
||||||
* Copyright (C) 2021 LSPosed Contributors
|
* Copyright (C) 2021 - 2022 LSPosed Contributors
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
|
|
|
||||||
|
|
@ -328,7 +328,7 @@ namespace lspd {
|
||||||
auto *process = env_->FindClass("android/os/Process");
|
auto *process = env_->FindClass("android/os/Process");
|
||||||
auto *set_argv0 = env_->GetStaticMethodID(process, "setArgV0",
|
auto *set_argv0 = env_->GetStaticMethodID(process, "setArgV0",
|
||||||
"(Ljava/lang/String;)V");
|
"(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_);
|
Context::GetInstance()->OnNativeForkSystemServerPost(env_);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
|
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020 EdXposed Contributors
|
* Copyright (C) 2020 EdXposed Contributors
|
||||||
* Copyright (C) 2021 LSPosed Contributors
|
* Copyright (C) 2021 - 2022 LSPosed Contributors
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
@ -191,6 +191,10 @@ inline auto wrap_scope(JNIEnv *env, T &&x) {
|
||||||
} else return x;
|
} else return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline auto JNI_NewStringUTF(JNIEnv *env, std::string_view sv) {
|
||||||
|
return ScopedLocalRef(env, env->NewStringUTF(sv.data()));
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Func, typename ...Args>
|
template<typename Func, typename ...Args>
|
||||||
requires(std::is_function_v<Func>)
|
requires(std::is_function_v<Func>)
|
||||||
[[maybe_unused]]
|
[[maybe_unused]]
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
|
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020 EdXposed Contributors
|
* Copyright (C) 2020 EdXposed Contributors
|
||||||
* Copyright (C) 2021 LSPosed Contributors
|
* Copyright (C) 2021 - 2022 LSPosed Contributors
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
|
|
@ -147,7 +147,7 @@ namespace lspd {
|
||||||
}
|
}
|
||||||
if (mid) [[likely]] {
|
if (mid) [[likely]] {
|
||||||
auto target = JNI_CallObjectMethod(env, class_loader, mid,
|
auto target = JNI_CallObjectMethod(env, class_loader, mid,
|
||||||
env->NewStringUTF(class_name.data()));
|
JNI_NewStringUTF(env, class_name.data()));
|
||||||
if (target) {
|
if (target) {
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
|
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020 EdXposed Contributors
|
* Copyright (C) 2020 EdXposed Contributors
|
||||||
* Copyright (C) 2021 LSPosed Contributors
|
* Copyright (C) 2021 - 2022 LSPosed Contributors
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "yahfa.h"
|
#include "yahfa.h"
|
||||||
|
|
@ -36,7 +36,7 @@ namespace lspd {
|
||||||
std::unordered_set<const void *> hooked_methods_;
|
std::unordered_set<const void *> hooked_methods_;
|
||||||
std::shared_mutex hooked_methods_lock_;
|
std::shared_mutex hooked_methods_lock_;
|
||||||
|
|
||||||
std::vector<std::pair<void *, void*>> jit_movements_;
|
std::vector<std::pair<void *, void *>> jit_movements_;
|
||||||
std::shared_mutex jit_movements_lock_;
|
std::shared_mutex jit_movements_lock_;
|
||||||
|
|
||||||
std::string obfuscated_signature_;
|
std::string obfuscated_signature_;
|
||||||
|
|
@ -52,12 +52,12 @@ namespace lspd {
|
||||||
hooked_methods_.insert(art_method);
|
hooked_methods_.insert(art_method);
|
||||||
}
|
}
|
||||||
|
|
||||||
void recordJitMovement(void *target, void* backup) {
|
void recordJitMovement(void *target, void *backup) {
|
||||||
std::unique_lock lk(jit_movements_lock_);
|
std::unique_lock lk(jit_movements_lock_);
|
||||||
jit_movements_.emplace_back(target, backup);
|
jit_movements_.emplace_back(target, backup);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::pair<void*, void*>> getJitMovements() {
|
std::vector<std::pair<void *, void *>> getJitMovements() {
|
||||||
std::unique_lock lk(jit_movements_lock_);
|
std::unique_lock lk(jit_movements_lock_);
|
||||||
return std::move(jit_movements_);
|
return std::move(jit_movements_);
|
||||||
}
|
}
|
||||||
|
|
@ -197,10 +197,9 @@ namespace lspd {
|
||||||
"(Ljava/lang/String;)Ljava/lang/Class;");
|
"(Ljava/lang/String;)Ljava/lang/Class;");
|
||||||
}
|
}
|
||||||
if (my_cl) {
|
if (my_cl) {
|
||||||
auto target = JNI_CallObjectMethod(env, my_cl, kMid, env->NewStringUTF("LspHooker_"));
|
auto target = JNI_CallObjectMethod(env, my_cl, kMid,
|
||||||
if (target) {
|
JNI_NewStringUTF(env, "LspHooker_"));
|
||||||
return (jclass) target.release();
|
if (target) return (jclass) target.release();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
|
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2021 LSPosed Contributors
|
* Copyright (C) 2021 - 2022 LSPosed Contributors
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -215,8 +215,7 @@ namespace lspd {
|
||||||
return {env, nullptr};
|
return {env, nullptr};
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: memory leak?
|
auto bridge_service_name = JNI_NewStringUTF(env, BRIDGE_SERVICE_NAME.data());
|
||||||
auto *bridge_service_name = env->NewStringUTF(BRIDGE_SERVICE_NAME.data());
|
|
||||||
auto bridge_service = JNI_CallStaticObjectMethod(env, service_manager_class_,
|
auto bridge_service = JNI_CallStaticObjectMethod(env, service_manager_class_,
|
||||||
get_service_method_, bridge_service_name);
|
get_service_method_, bridge_service_name);
|
||||||
if (!bridge_service) {
|
if (!bridge_service) {
|
||||||
|
|
@ -229,7 +228,7 @@ namespace lspd {
|
||||||
auto data = JNI_CallStaticObjectMethod(env, parcel_class_, obtain_method_);
|
auto data = JNI_CallStaticObjectMethod(env, parcel_class_, obtain_method_);
|
||||||
auto reply = 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_interface_token_method_, descriptor);
|
||||||
JNI_CallVoidMethod(env, data, write_int_method_, BRIDGE_ACTION_GET_BINDER);
|
JNI_CallVoidMethod(env, data, write_int_method_, BRIDGE_ACTION_GET_BINDER);
|
||||||
JNI_CallVoidMethod(env, data, write_string_method_, nice_name);
|
JNI_CallVoidMethod(env, data, write_string_method_, nice_name);
|
||||||
|
|
@ -261,7 +260,7 @@ namespace lspd {
|
||||||
}
|
}
|
||||||
// Get Binder for LSPSystemServerService.
|
// Get Binder for LSPSystemServerService.
|
||||||
// The binder itself was inject into system service "serial"
|
// 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<jobject> binder{env, nullptr};
|
ScopedLocalRef<jobject> binder{env, nullptr};
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
binder = JNI_CallStaticObjectMethod(env, service_manager_class_,
|
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_, getuid()); // data.writeInt(uid)
|
||||||
JNI_CallVoidMethod(env, data, write_int_method_, getpid());
|
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);
|
JNI_CallVoidMethod(env, data, write_strong_binder_method_, heart_beat_binder);
|
||||||
|
|
||||||
auto res = JNI_CallBooleanMethod(env, binder, transact_method_,
|
auto res = JNI_CallBooleanMethod(env, binder, transact_method_,
|
||||||
|
|
|
||||||
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 LSPosed Contributors
|
||||||
|
*/
|
||||||
|
|
||||||
//
|
//
|
||||||
// Created by Kotori2 on 2021/12/1.
|
// Created by Kotori2 on 2021/12/1.
|
||||||
//
|
//
|
||||||
|
|
@ -89,14 +108,11 @@ ustring obfuscateDex(void *dex, size_t size) {
|
||||||
return new_dex;
|
return new_dex;
|
||||||
}
|
}
|
||||||
|
|
||||||
jobject new_sharedmem(JNIEnv* env, jint size) {
|
ScopedLocalRef<jobject> new_sharedmem(JNIEnv* env, jint size) {
|
||||||
jclass clazz = env->FindClass("android/os/SharedMemory");
|
auto clazz = JNI_FindClass(env, "android/os/SharedMemory");
|
||||||
auto *ref = env->NewGlobalRef(clazz);
|
auto mid = JNI_GetStaticMethodID(env, clazz, "create", "(Ljava/lang/String;I)Landroid/os/SharedMemory;");
|
||||||
jmethodID mid = env->GetStaticMethodID(clazz, "create", "(Ljava/lang/String;I)Landroid/os/SharedMemory;");
|
auto empty_str = JNI_NewStringUTF(env, "");
|
||||||
jstring empty_str = env->NewStringUTF("");
|
auto new_mem = JNI_CallStaticObjectMethod(env, clazz, mid, empty_str, static_cast<jint>(size));
|
||||||
jobject new_mem = env->CallStaticObjectMethod(clazz, mid, empty_str, static_cast<jint>(size));
|
|
||||||
env->DeleteGlobalRef(ref);
|
|
||||||
env->DeleteLocalRef(empty_str);
|
|
||||||
return new_mem;
|
return new_mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -133,7 +149,7 @@ Java_org_lsposed_lspd_service_ObfuscationManager_preloadDex(JNIEnv *env, jclass
|
||||||
auto new_dex = obfuscateDex(addr, size);
|
auto new_dex = obfuscateDex(addr, size);
|
||||||
LOGD("LSPApplicationService::preloadDex: %p, size=%zu", new_dex.data(), new_dex.size());
|
LOGD("LSPApplicationService::preloadDex: %p, size=%zu", new_dex.data(), new_dex.size());
|
||||||
auto new_mem = new_sharedmem(env, 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_fd = ASharedMemory_dupFromJava(env, lspdDex);
|
||||||
auto new_addr = mmap(nullptr, new_dex.size(), PROT_READ | PROT_WRITE, MAP_SHARED, new_fd, 0);
|
auto new_addr = mmap(nullptr, new_dex.size(), PROT_READ | PROT_WRITE, MAP_SHARED, new_fd, 0);
|
||||||
if (new_addr == MAP_FAILED) {
|
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
|
// create new SharedMem since it cannot be resized
|
||||||
auto new_mem = new_sharedmem(env, new_dex.size());
|
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);
|
mem = mmap(nullptr, new_dex.size(), PROT_READ | PROT_WRITE, MAP_SHARED, new_fd, 0);
|
||||||
if (mem == MAP_FAILED) {
|
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());
|
memcpy(mem, new_dex.data(), new_dex.size());
|
||||||
ASharedMemory_setProt(fd, PROT_READ);
|
ASharedMemory_setProt(fd, PROT_READ);
|
||||||
return new_mem;
|
return new_mem.release();
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue