Skip to content

Commit

Permalink
Load dex only in required processes if we can
Browse files Browse the repository at this point in the history
  • Loading branch information
canyie committed Feb 2, 2021
1 parent 307797c commit 80888f6
Show file tree
Hide file tree
Showing 10 changed files with 270 additions and 105 deletions.
18 changes: 16 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,21 @@ task copyNativeLibs() {
onlyIf { !stripReleaseDebugSymbols.state.upToDate || !file(nativeDir).exists() }
}

task jarClassesDex(type: Jar) {
task jarClassesDex() {
doLast {
copy {
from mergeDexRelease.outputs.files
into file(jarOutputDir)
rename 'classes.dex', 'dreamland.jar'
}
}

// FIXME: the task always up-to-date, disable up-to-date now
// onlyIf { !mergeDexRelease.state.upToDate || !file(jarOutputPath).exists() }
outputs.upToDateWhen { false }
}

/*task jarClassesDex(type: Jar) {
def dexDir = file("$localDir/dex")
doFirst {
Expand All @@ -153,7 +167,7 @@ task jarClassesDex(type: Jar) {
// FIXME: the task always up-to-date, disable up-to-date now
// onlyIf { !mergeDexRelease.state.upToDate || !file(jarOutputPath).exists() }
outputs.upToDateWhen { false }
}
}*/

task zipMagiskFiles(type: Zip) {
from file(tempTemplatePath)
Expand Down
1 change: 1 addition & 0 deletions app/src/main/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ add_library( # Sets the name of the library.
dreamland/android.cpp
dreamland/resources_hook.cpp
dreamland/binder.cpp
dreamland/dex_loader.cpp

# XHook
external/xhook/xhook.c
Expand Down
58 changes: 58 additions & 0 deletions app/src/main/cpp/dreamland/dex_loader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//
// Created by canyie on 2021/2/2.
//

#include "dex_loader.h"
#include "../utils/well_known_classes.h"
#include "android.h"
#include "../utils/scoped_local_ref.h"

using namespace dreamland;

jclass DexLoader::PathClassLoader = nullptr;
jmethodID DexLoader::PathClassLoader_init = nullptr;
jclass DexLoader::InMemoryDexClassLoader = nullptr;
jmethodID DexLoader::InMemoryDexClassLoader_init = nullptr;

void DexLoader::Prepare(JNIEnv* env) {
if (Android::version < Android::kO) {
PathClassLoader = WellKnownClasses::CacheClass(env, "dalvik/system/PathClassLoader");
PathClassLoader_init = WellKnownClasses::CacheMethod(env, PathClassLoader, "<init>",
"(Ljava/lang/String;Ljava/lang/ClassLoader;)V", false);
} else {
InMemoryDexClassLoader = WellKnownClasses::CacheClass(env, "dalvik/system/InMemoryDexClassLoader");
InMemoryDexClassLoader_init = WellKnownClasses::CacheMethod(env, InMemoryDexClassLoader, "<init>",
"(Ljava/nio/ByteBuffer;Ljava/lang/ClassLoader;)V", false);
}
}

jobject DexLoader::FromMemory(JNIEnv* env, char* dex, const size_t size) {
ScopedLocalRef<jobject> system_class_loader(env, env->CallStaticObjectMethod(
WellKnownClasses::java_lang_ClassLoader,
WellKnownClasses::java_lang_ClassLoader_getSystemClassLoader));
ScopedLocalRef<jobject> buffer(env, env->NewDirectByteBuffer(dex, size));
jobject loader = env->NewObject(InMemoryDexClassLoader, InMemoryDexClassLoader_init,
buffer.Get(), system_class_loader.Get());
if (UNLIKELY(env->ExceptionCheck())) {
LOGE("Failed to load dex data");
env->ExceptionDescribe();
env->ExceptionClear();
return nullptr;
}
return loader;
}

jobject DexLoader::FromFile(JNIEnv* env, const char* path) {
ScopedLocalRef<jstring> dex_path(env, path);
ScopedLocalRef<jobject> system_class_loader(env, env->CallStaticObjectMethod(
WellKnownClasses::java_lang_ClassLoader,
WellKnownClasses::java_lang_ClassLoader_getSystemClassLoader));
jobject loader = env->NewObject(PathClassLoader, PathClassLoader_init, dex_path.Get(), system_class_loader.Get());
if (UNLIKELY(env->ExceptionCheck())) {
LOGE("Failed to load dex %s", path);
env->ExceptionDescribe();
env->ExceptionClear();
return nullptr;
}
return loader;
}
25 changes: 25 additions & 0 deletions app/src/main/cpp/dreamland/dex_loader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// Created by canyie on 2021/2/2.
//

#ifndef DREAMLAND_DEX_LOADER_H
#define DREAMLAND_DEX_LOADER_H

#include <jni.h>

namespace dreamland {
class DexLoader {
public:
static void Prepare(JNIEnv* env);
static jobject FromMemory(JNIEnv* env, char* dex, const size_t size);
static jobject FromFile(JNIEnv* env, const char* path);

private:
static jclass PathClassLoader; // For Nougat only
static jmethodID PathClassLoader_init;
static jclass InMemoryDexClassLoader; // For Oreo+
static jmethodID InMemoryDexClassLoader_init;
};
}

#endif //DREAMLAND_DEX_LOADER_H

0 comments on commit 80888f6

Please sign in to comment.