reduce memory allocation && properly close fds
This commit is contained in:
parent
d3b0140230
commit
9760e8d733
|
|
@ -82,7 +82,7 @@ namespace lspd {
|
||||||
void Context::LoadDex(JNIEnv *env, int fd, size_t size) {
|
void Context::LoadDex(JNIEnv *env, int fd, size_t size) {
|
||||||
LOGD("Context::LoadDex: %d", fd);
|
LOGD("Context::LoadDex: %d", fd);
|
||||||
// map fd to memory. fd should be created with ASharedMemory_create.
|
// map fd to memory. fd should be created with ASharedMemory_create.
|
||||||
dex_ = PreloadedDex(fd, size); // for RAII...
|
auto dex = PreloadedDex(fd, size); // for RAII...
|
||||||
|
|
||||||
auto classloader = JNI_FindClass(env, "java/lang/ClassLoader");
|
auto classloader = JNI_FindClass(env, "java/lang/ClassLoader");
|
||||||
auto getsyscl_mid = JNI_GetStaticMethodID(
|
auto getsyscl_mid = JNI_GetStaticMethodID(
|
||||||
|
|
@ -96,7 +96,7 @@ namespace lspd {
|
||||||
auto initMid = JNI_GetMethodID(env, in_memory_classloader, "<init>",
|
auto initMid = JNI_GetMethodID(env, in_memory_classloader, "<init>",
|
||||||
"(Ljava/nio/ByteBuffer;Ljava/lang/ClassLoader;)V");
|
"(Ljava/nio/ByteBuffer;Ljava/lang/ClassLoader;)V");
|
||||||
auto byte_buffer_class = JNI_FindClass(env, "java/nio/ByteBuffer");
|
auto byte_buffer_class = JNI_FindClass(env, "java/nio/ByteBuffer");
|
||||||
auto dex_buffer = env->NewDirectByteBuffer(dex_.data(), dex_.size());
|
auto dex_buffer = env->NewDirectByteBuffer(dex.data(), dex.size());
|
||||||
if (auto my_cl = JNI_NewObject(env, in_memory_classloader, initMid,
|
if (auto my_cl = JNI_NewObject(env, in_memory_classloader, initMid,
|
||||||
dex_buffer, sys_classloader)) {
|
dex_buffer, sys_classloader)) {
|
||||||
inject_class_loader_ = JNI_NewGlobalRef(env, my_cl);
|
inject_class_loader_ = JNI_NewGlobalRef(env, my_cl);
|
||||||
|
|
@ -199,7 +199,9 @@ namespace lspd {
|
||||||
// Call application_binder directly if application binder is available,
|
// Call application_binder directly if application binder is available,
|
||||||
// or we proxy the request from system server binder
|
// or we proxy the request from system server binder
|
||||||
auto dex = instance->RequestLSPDex(env, application_binder ? application_binder : system_server_binder);
|
auto dex = instance->RequestLSPDex(env, application_binder ? application_binder : system_server_binder);
|
||||||
LoadDex(env, std::get<0>(dex), std::get<1>(dex));
|
auto dex_fd = std::get<0>(dex);
|
||||||
|
LoadDex(env, dex_fd, std::get<1>(dex));
|
||||||
|
close(dex_fd);
|
||||||
instance->HookBridge(*this, env);
|
instance->HookBridge(*this, env);
|
||||||
|
|
||||||
if (application_binder) {
|
if (application_binder) {
|
||||||
|
|
@ -264,7 +266,9 @@ namespace lspd {
|
||||||
if (binder) {
|
if (binder) {
|
||||||
InstallInlineHooks();
|
InstallInlineHooks();
|
||||||
auto dex = instance->RequestLSPDex(env, binder);
|
auto dex = instance->RequestLSPDex(env, binder);
|
||||||
LoadDex(env, std::get<0>(dex), std::get<1>(dex));
|
auto dex_fd = std::get<0>(dex);
|
||||||
|
LoadDex(env, dex_fd, std::get<1>(dex));
|
||||||
|
close(dex_fd);
|
||||||
obfuscated_signature_ = std::move(std::get<2>(dex));
|
obfuscated_signature_ = std::move(std::get<2>(dex));
|
||||||
Init(env);
|
Init(env);
|
||||||
LOGD("Done prepare");
|
LOGD("Done prepare");
|
||||||
|
|
|
||||||
|
|
@ -110,8 +110,6 @@ namespace lspd {
|
||||||
std::size_t size_;
|
std::size_t size_;
|
||||||
};
|
};
|
||||||
|
|
||||||
PreloadedDex dex_{};
|
|
||||||
|
|
||||||
Context() {}
|
Context() {}
|
||||||
|
|
||||||
void LoadDex(JNIEnv *env, int fd, size_t size);
|
void LoadDex(JNIEnv *env, int fd, size_t size);
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ namespace lspd {
|
||||||
LOGE("ParcelFileDescriptor not found");
|
LOGE("ParcelFileDescriptor not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
get_fd_method = JNI_GetMethodID(env, parcel_file_descriptor_class_, "getFd", "()I");
|
detach_fd_method_ = JNI_GetMethodID(env, parcel_file_descriptor_class_, "detachFd", "()I");
|
||||||
|
|
||||||
if (auto dead_object_exception_class = JNI_FindClass(env,
|
if (auto dead_object_exception_class = JNI_FindClass(env,
|
||||||
"android/os/DeadObjectException")) {
|
"android/os/DeadObjectException")) {
|
||||||
|
|
@ -299,8 +299,6 @@ namespace lspd {
|
||||||
if (res) {
|
if (res) {
|
||||||
JNI_CallVoidMethod(env, reply, read_exception_method_);
|
JNI_CallVoidMethod(env, reply, read_exception_method_);
|
||||||
app_binder = JNI_CallObjectMethod(env, reply, read_strong_binder_method_);
|
app_binder = JNI_CallObjectMethod(env, reply, read_strong_binder_method_);
|
||||||
} else {
|
|
||||||
LOGE("Service::RequestSystemServerBinder binder.transact failed?");
|
|
||||||
}
|
}
|
||||||
JNI_CallVoidMethod(env, data, recycleMethod_);
|
JNI_CallVoidMethod(env, data, recycleMethod_);
|
||||||
JNI_CallVoidMethod(env, reply, recycleMethod_);
|
JNI_CallVoidMethod(env, reply, recycleMethod_);
|
||||||
|
|
@ -323,7 +321,7 @@ namespace lspd {
|
||||||
return {-1, 0, ""};
|
return {-1, 0, ""};
|
||||||
}
|
}
|
||||||
auto parcel_fd = JNI_CallObjectMethod(env, reply, read_file_descriptor_method_);
|
auto parcel_fd = JNI_CallObjectMethod(env, reply, read_file_descriptor_method_);
|
||||||
int fd = JNI_CallIntMethod(env, parcel_fd, get_fd_method);
|
int fd = JNI_CallIntMethod(env, parcel_fd, detach_fd_method_);
|
||||||
auto size = JNI_CallLongMethod(env, reply, read_long_method_);
|
auto size = JNI_CallLongMethod(env, reply, read_long_method_);
|
||||||
auto signature = JNI_CallObjectMethod(env, reply, read_string_method_);
|
auto signature = JNI_CallObjectMethod(env, reply, read_string_method_);
|
||||||
JNI_CallVoidMethod(env, data, recycleMethod_);
|
JNI_CallVoidMethod(env, data, recycleMethod_);
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ namespace lspd {
|
||||||
jmethodID read_string_method_ = nullptr;
|
jmethodID read_string_method_ = nullptr;
|
||||||
|
|
||||||
jclass parcel_file_descriptor_class_ = nullptr;
|
jclass parcel_file_descriptor_class_ = nullptr;
|
||||||
jmethodID get_fd_method = nullptr;
|
jmethodID detach_fd_method_ = nullptr;
|
||||||
|
|
||||||
jclass deadObjectExceptionClass_ = nullptr;
|
jclass deadObjectExceptionClass_ = nullptr;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,24 +33,25 @@
|
||||||
#include "slicer/reader.h"
|
#include "slicer/reader.h"
|
||||||
#include "slicer/writer.h"
|
#include "slicer/writer.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "jni_helper.h"
|
#include "obfuscation.h"
|
||||||
|
|
||||||
class WA: public dex::Writer::Allocator {
|
extern "C"
|
||||||
std::unordered_map<void*, size_t> allocated_;
|
JNIEXPORT void JNICALL
|
||||||
public:
|
Java_org_lsposed_lspd_service_ObfuscationManager_init(JNIEnv *env, jclass ) {
|
||||||
void* Allocate(size_t size) override {
|
LOGD("ObfuscationManager.init");
|
||||||
auto *mem = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
if (auto file_descriptor = JNI_FindClass(env, "java/io/FileDescriptor")) {
|
||||||
allocated_[mem] = size;
|
class_file_descriptor = JNI_NewGlobalRef(env, file_descriptor);
|
||||||
return mem;
|
} else return;
|
||||||
}
|
|
||||||
void Free(void* ptr) override {
|
|
||||||
munmap(ptr, allocated_[ptr]);
|
|
||||||
allocated_.erase(ptr);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static std::string obfuscated_signature;
|
method_file_descriptor_ctor = JNI_GetMethodID(env, class_file_descriptor, "<init>", "(I)V");
|
||||||
static const std::string old_signature = "Lde/robv/android/xposed";
|
|
||||||
|
if (auto shared_memory = JNI_FindClass(env, "android/os/SharedMemory")) {
|
||||||
|
class_shared_memory = JNI_NewGlobalRef(env, shared_memory);
|
||||||
|
} else return;
|
||||||
|
|
||||||
|
method_shared_memory_ctor = JNI_GetMethodID(env, class_shared_memory, "<init>", "(Ljava/io/FileDescriptor;)V");
|
||||||
|
LOGD("ObfuscationManager init successfully");
|
||||||
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
JNIEXPORT jstring JNICALL
|
JNIEXPORT jstring JNICALL
|
||||||
|
|
@ -84,10 +85,9 @@ Java_org_lsposed_lspd_service_ObfuscationManager_getObfuscatedSignature(JNIEnv *
|
||||||
return env->NewStringUTF(obfuscated_signature.c_str());
|
return env->NewStringUTF(obfuscated_signature.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
using ustring = std::basic_string<uint8_t>;
|
int obfuscateDex(const void *dex, size_t size) {
|
||||||
ustring obfuscateDex(void *dex, size_t size) {
|
|
||||||
const char* new_sig = obfuscated_signature.c_str();
|
const char* new_sig = obfuscated_signature.c_str();
|
||||||
dex::Reader reader{reinterpret_cast<dex::u1*>(dex), size};
|
dex::Reader reader{reinterpret_cast<const dex::u1*>(dex), size};
|
||||||
|
|
||||||
reader.CreateFullIr();
|
reader.CreateFullIr();
|
||||||
auto ir = reader.GetIr();
|
auto ir = reader.GetIr();
|
||||||
|
|
@ -102,29 +102,16 @@ ustring obfuscateDex(void *dex, size_t size) {
|
||||||
|
|
||||||
size_t new_size;
|
size_t new_size;
|
||||||
WA allocator;
|
WA allocator;
|
||||||
auto *p_dex = writer.CreateImage(&allocator, &new_size);
|
auto *p_dex = writer.CreateImage(&allocator, &new_size); // allocates memory only once
|
||||||
ustring new_dex(p_dex, new_size);
|
return allocator.GetFd(p_dex);
|
||||||
allocator.Free(p_dex);
|
|
||||||
return new_dex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ScopedLocalRef<jobject> 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<jint>(size));
|
|
||||||
return new_mem;
|
|
||||||
}
|
|
||||||
|
|
||||||
static jobject lspdDex = nullptr;
|
|
||||||
static std::mutex dex_lock;
|
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
JNIEXPORT jint JNICALL
|
JNIEXPORT jint JNICALL
|
||||||
Java_org_lsposed_lspd_service_ObfuscationManager_preloadDex(JNIEnv *env, jclass ) {
|
Java_org_lsposed_lspd_service_ObfuscationManager_preloadDex(JNIEnv *, jclass ) {
|
||||||
using namespace std::string_literals;
|
using namespace std::string_literals;
|
||||||
std::lock_guard lg(dex_lock);
|
std::lock_guard lg(dex_lock);
|
||||||
if (lspdDex) return ASharedMemory_dupFromJava(env, lspdDex);
|
if (lspdDex != -1) return lspdDex;
|
||||||
std::string dex_path = "/data/adb/modules/"s + lspd::moduleName + "/" + lspd::kDexPath;
|
std::string dex_path = "/data/adb/modules/"s + lspd::moduleName + "/" + lspd::kDexPath;
|
||||||
|
|
||||||
std::unique_ptr<FILE, decltype(&fclose)> f{fopen(dex_path.data(), "rb"), &fclose};
|
std::unique_ptr<FILE, decltype(&fclose)> f{fopen(dex_path.data(), "rb"), &fclose};
|
||||||
|
|
@ -147,25 +134,16 @@ 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: %d, size=%zu", new_dex, ASharedMemory_getSize(new_dex));
|
||||||
auto new_mem = new_sharedmem(env, new_dex.size());
|
lspdDex = new_dex;
|
||||||
lspdDex = JNI_NewGlobalRef(env, new_mem);
|
return new_dex;
|
||||||
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) {
|
|
||||||
LOGE("Failed to map new dex to memory?");
|
|
||||||
}
|
|
||||||
memmove(new_addr, new_dex.data(), new_dex.size());
|
|
||||||
|
|
||||||
return new_fd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
JNIEXPORT jlong JNICALL
|
JNIEXPORT jlong JNICALL
|
||||||
Java_org_lsposed_lspd_service_ObfuscationManager_getPreloadedDexSize(JNIEnv *env, jclass ) {
|
Java_org_lsposed_lspd_service_ObfuscationManager_getPreloadedDexSize(JNIEnv *, jclass ) {
|
||||||
if (lspdDex) {
|
if (lspdDex != -1) {
|
||||||
auto fd = ASharedMemory_dupFromJava(env, lspdDex);
|
return ASharedMemory_getSize(lspdDex);
|
||||||
return ASharedMemory_getSize(fd);
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -176,23 +154,19 @@ Java_org_lsposed_lspd_service_ObfuscationManager_obfuscateDex(JNIEnv *env, jclas
|
||||||
jobject memory) {
|
jobject memory) {
|
||||||
int fd = ASharedMemory_dupFromJava(env, memory);
|
int fd = ASharedMemory_dupFromJava(env, memory);
|
||||||
auto size = ASharedMemory_getSize(fd);
|
auto size = ASharedMemory_getSize(fd);
|
||||||
ustring mem_wrapper;
|
LOGD("fd=%d, size=%zu", fd, size);
|
||||||
mem_wrapper.resize(size);
|
|
||||||
read(fd, mem_wrapper.data(), size);
|
|
||||||
|
|
||||||
void *mem = mem_wrapper.data();
|
const void* mem = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||||
|
|
||||||
auto new_dex = obfuscateDex(mem, size);
|
|
||||||
|
|
||||||
// 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.get());
|
|
||||||
|
|
||||||
mem = mmap(nullptr, new_dex.size(), PROT_READ | PROT_WRITE, MAP_SHARED, new_fd, 0);
|
|
||||||
if (mem == MAP_FAILED) {
|
if (mem == MAP_FAILED) {
|
||||||
LOGE("Failed to map new dex to memory?");
|
LOGE("old dex map failed?");
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
memcpy(mem, new_dex.data(), new_dex.size());
|
|
||||||
ASharedMemory_setProt(fd, PROT_READ);
|
auto new_fd = obfuscateDex(mem, size);
|
||||||
return new_mem.release();
|
|
||||||
|
// construct new shared mem with fd
|
||||||
|
auto java_fd = JNI_NewObject(env, class_file_descriptor, method_file_descriptor_ctor, new_fd);
|
||||||
|
auto java_sm = JNI_NewObject(env, class_shared_memory, method_shared_memory_ctor, java_fd);
|
||||||
|
|
||||||
|
return java_sm.release();
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
#include "jni_helper.h"
|
||||||
|
|
||||||
|
static std::string obfuscated_signature;
|
||||||
|
static const std::string old_signature = "Lde/robv/android/xposed";
|
||||||
|
static int lspdDex = -1;
|
||||||
|
static std::mutex dex_lock;
|
||||||
|
|
||||||
|
static jclass class_file_descriptor;
|
||||||
|
static jmethodID method_file_descriptor_ctor;
|
||||||
|
|
||||||
|
static jclass class_shared_memory;
|
||||||
|
static jmethodID method_shared_memory_ctor;
|
||||||
|
|
||||||
|
class WA: public dex::Writer::Allocator {
|
||||||
|
// addr: {size, fd}
|
||||||
|
std::unordered_map<void*, std::pair<size_t, int>> allocated_;
|
||||||
|
public:
|
||||||
|
inline void* Allocate(size_t size) override {
|
||||||
|
auto fd = ASharedMemory_create("", size);
|
||||||
|
auto *mem = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||||
|
allocated_[mem] = {size, fd};
|
||||||
|
return mem;
|
||||||
|
}
|
||||||
|
inline void Free(void* ptr) override {
|
||||||
|
auto alloc_data = allocated_.at(ptr);
|
||||||
|
close(alloc_data.second);
|
||||||
|
allocated_.erase(ptr);
|
||||||
|
}
|
||||||
|
inline int GetFd(void* ptr) {
|
||||||
|
auto alloc_data = allocated_.find(ptr);
|
||||||
|
if (alloc_data == allocated_.end()) return -1;
|
||||||
|
return (*alloc_data).second.second;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -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) 2021 - 2022 LSPosed Contributors
|
||||||
|
*/
|
||||||
|
|
||||||
package org.lsposed.lspd.service;
|
package org.lsposed.lspd.service;
|
||||||
|
|
||||||
import static org.lsposed.lspd.service.ServiceManager.TAG;
|
import static org.lsposed.lspd.service.ServiceManager.TAG;
|
||||||
|
|
@ -296,9 +315,10 @@ public class ConfigFileManager {
|
||||||
var byteBuffer = memory.mapReadWrite();
|
var byteBuffer = memory.mapReadWrite();
|
||||||
Channels.newChannel(in).read(byteBuffer);
|
Channels.newChannel(in).read(byteBuffer);
|
||||||
SharedMemory.unmap(byteBuffer);
|
SharedMemory.unmap(byteBuffer);
|
||||||
memory = ObfuscationManager.obfuscateDex(memory);
|
var new_memory = ObfuscationManager.obfuscateDex(memory);
|
||||||
memory.setProtect(OsConstants.PROT_READ);
|
memory.close();
|
||||||
preLoadedDexes.add(memory);
|
new_memory.setProtect(OsConstants.PROT_READ);
|
||||||
|
preLoadedDexes.add(new_memory);
|
||||||
} catch (IOException | ErrnoException e) {
|
} catch (IOException | ErrnoException e) {
|
||||||
Log.w(TAG, "Can not load " + dexFile + " in " + apkFile, e);
|
Log.w(TAG, "Can not load " + dexFile + " in " + apkFile, e);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ package org.lsposed.lspd.service;
|
||||||
import android.os.SharedMemory;
|
import android.os.SharedMemory;
|
||||||
|
|
||||||
public class ObfuscationManager {
|
public class ObfuscationManager {
|
||||||
|
static native void init();
|
||||||
|
|
||||||
// For module dexes
|
// For module dexes
|
||||||
static native SharedMemory obfuscateDex(SharedMemory memory);
|
static native SharedMemory obfuscateDex(SharedMemory memory);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,7 @@ public class ServiceManager {
|
||||||
logcatService.start();
|
logcatService.start();
|
||||||
|
|
||||||
Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
|
Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
|
||||||
|
ObfuscationManager.init();
|
||||||
ObfuscationManager.getObfuscatedSignature();
|
ObfuscationManager.getObfuscatedSignature();
|
||||||
ObfuscationManager.preloadDex();
|
ObfuscationManager.preloadDex();
|
||||||
Looper.prepareMainLooper();
|
Looper.prepareMainLooper();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue