This commit is contained in:
Shauli Bracha 2019-02-28 13:33:25 +02:00
commit 6cc241b974
6 changed files with 97 additions and 10 deletions

View File

@ -123,4 +123,6 @@ public class Main implements KeepAll {
public static native void closeFilesBeforeForkNative();
public static native void reopenFilesAfterForkNative();
public static native void deoptMethodNative(Object object);
}

View File

@ -27,10 +27,12 @@ static char whitelist_path[PATH_MAX];
static char use_whitelist_path[PATH_MAX];
static char black_white_list_path[PATH_MAX];
static char dynamic_modules_path[PATH_MAX];
static char deopt_boot_image_path[PATH_MAX];
static const char *installer_package_name;
static bool black_white_list_enabled = false;
static bool dynamic_modules_enabled = false;
static bool deopt_boot_image_enabled = false;
static bool inited = false;
static const char *get_installer_package_name() {
@ -72,8 +74,11 @@ static void init_once() {
installer_package_name, "blackwhitelist");
snprintf(dynamic_modules_path, PATH_MAX, config_path_tpl, data_path_prefix,
installer_package_name, "dynamicmodules");
snprintf(deopt_boot_image_path, PATH_MAX, config_path_tpl, data_path_prefix,
installer_package_name, "deoptbootimage");
dynamic_modules_enabled = access(dynamic_modules_path, F_OK) == 0;
black_white_list_enabled = access(black_white_list_path, F_OK) == 0;
deopt_boot_image_enabled = access(deopt_boot_image_path, F_OK) == 0;
LOGI("black/white list mode: %d", black_white_list_enabled);
LOGI("dynamic modules mode: %d", dynamic_modules_enabled);
inited = true;
@ -136,7 +141,12 @@ bool is_dynamic_modules_enabled() {
return dynamic_modules_enabled;
}
jstring get_installer_pkg_name(JNIEnv *env) {
bool is_deopt_boot_image_enabled() {
init_once();
return deopt_boot_image_enabled;
}
jstring get_installer_pkg_name(JNIEnv *env, jclass) {
init_once();
return env->NewStringUTF(installer_package_name);
}

View File

@ -5,12 +5,16 @@
#ifndef EDXPOSED_CONFIG_MANAGER_H
#define EDXPOSED_CONFIG_MANAGER_H
#include <jni.h>
bool is_app_need_hook(JNIEnv *env, jstring appDataDir);
bool is_black_white_list_enabled();
bool is_dynamic_modules_enabled();
jstring get_installer_pkg_name(JNIEnv *env);
bool is_deopt_boot_image_enabled();
jstring get_installer_pkg_name(JNIEnv *env, jclass clazz);
#endif //EDXPOSED_CONFIG_MANAGER_H

View File

@ -6,6 +6,7 @@
#include <fcntl.h>
#include <dlfcn.h>
#include <inject/config_manager.h>
#include <native_hook/native_hook.h>
#include "java_hook/java_hook.h"
#include "include/logging.h"
#include "include/fd_utils-inl.h"
@ -64,6 +65,9 @@ static JNINativeMethod hookMethods[] = {
},
{
"reopenFilesAfterForkNative", "()V", (void *)reopenFilesAfterForkNative
},
{
"deoptMethodNative", "(Ljava/lang/Object;)V", (void *)deoptimize_method
}
};
@ -102,7 +106,7 @@ void loadDexAndInit(JNIEnv *env, const char *dexPath) {
jclass entry_class = findClassFromLoader(env, myClassLoader, ENTRY_CLASS_NAME);
if (NULL != entry_class) {
LOGD("HookEntry Class %p", entry_class);
env->RegisterNatives(entry_class, hookMethods, 7);
env->RegisterNatives(entry_class, hookMethods, 8);
isInited = true;
LOGD("RegisterNatives succeed for HookEntry.");
} else {

View File

@ -3,6 +3,7 @@
#include <include/android_build.h>
#include <string>
#include <vector>
#include <inject/config_manager.h>
#include "include/logging.h"
#include "native_hook.h"
@ -13,12 +14,20 @@ static const char *(*getDesc)(void *, std::string *);
static bool (*isInSamePackageBackup)(void *, void *) = nullptr;
// runtime
void *runtime_ = nullptr;
void (*deoptBootImage)(void *runtime) = nullptr;
bool (*runtimeInitBackup)(void *runtime, void *mapAddr) = nullptr;
// instrumentation
void *instru_ = nullptr;
static void *(*instrCstBackup)(void *instru) = nullptr;
void (*deoptMethod)(void *, void *) = nullptr;
bool my_runtimeInit(void *runtime, void *mapAddr) {
if (!runtimeInitBackup) {
LOGE("runtimeInitBackup is null");
@ -45,7 +54,6 @@ static bool onIsInSamePackageCalled(void *thiz, void *that) {
|| strstr(thatDesc, "EdHooker") != nullptr
|| strstr(thisDesc, "com/elderdrivers/riru/") != nullptr
|| strstr(thatDesc, "com/elderdrivers/riru/") != nullptr) {
// LOGE("onIsInSamePackageCalled, %s -> %s", thisDesc, thatDesc);
return true;
}
return (*isInSamePackageBackup)(thiz, that);
@ -61,8 +69,8 @@ static bool onInvokeHiddenAPI() {
* But we don't know the symbols until it's published.
* @author asLody
*/
static bool disable_HiddenAPIPolicyImpl(int api_level, void *artHandle,
void (*hookFun)(void *, void *, void **)) {
static bool disableHiddenAPIPolicyImpl(int api_level, void *artHandle,
void (*hookFun)(void *, void *, void **)) {
if (api_level < ANDROID_P) {
return true;
}
@ -121,7 +129,63 @@ static void hookIsInSamePackage(int api_level, void *artHandle,
reinterpret_cast<void **>(&isInSamePackageBackup));
}
void *my_instruCst(void *instru) {
if (!instrCstBackup) {
LOGE("instrCstBackup is null");
return instru;
}
LOGI("instrCst starts");
void *result = (*instrCstBackup)(instru);
LOGI("instrCst finishes");
if (instru_ != instru) {
LOGI("instru_ changed from %p to %p", instru_, instru);
instru_ = instru;
}
return result;
}
void hookInstrumentation(int api_level, void *artHandle, void (*hookFun)(void *, void *, void **)) {
if (api_level < ANDROID_P) {
// TODO support other api levels
return;
}
void *instruCstSym = dlsym(artHandle,
"_ZN3art15instrumentation15InstrumentationC2Ev");
deoptMethod = reinterpret_cast<void (*)(void *, void *)>(
dlsym(artHandle,
"_ZN3art15instrumentation15Instrumentation40UpdateMethodsCodeToInterpreterEntryPointEPNS_9ArtMethodE"));
if (!instruCstSym) {
LOGE("can't get instruCstSym: %s", dlerror());
return;
}
(*hookFun)(instruCstSym, reinterpret_cast<void *>(my_instruCst),
reinterpret_cast<void **>(&instrCstBackup));
LOGI("instrCst hooked");
}
std::vector<void *> deoptedMethods;
void deoptimize_method(JNIEnv *env, jclass clazz, jobject method) {
if (!deoptMethod) {
LOGE("deoptMethodSym is null, skip deopt");
return;
}
void *reflected_method = env->FromReflectedMethod(method);
if (std::find(deoptedMethods.begin(), deoptedMethods.end(), reflected_method) !=
deoptedMethods.end()) {
LOGD("method %p has been deopted before, skip...", reflected_method);
return;
}
LOGD("deoptimize method: %p", reflected_method);
(*deoptMethod)(instru_, reflected_method);
deoptedMethods.push_back(reflected_method);
LOGD("deoptimize method done: %p");
}
void hookRuntime(int api_level, void *artHandle, void (*hookFun)(void *, void *, void **)) {
if (!is_deopt_boot_image_enabled()) {
return;
}
void *runtimeInitSym = nullptr;
if (api_level >= ANDROID_O) {
// only oreo has deoptBootImageSym in Runtime
@ -177,12 +241,13 @@ void install_inline_hooks() {
LOGE("can't open libart: %s", dlerror());
return;
}
hookIsInSamePackage(api_level, artHandle, hookFun);
hookRuntime(api_level, artHandle, hookFun);
if (disable_HiddenAPIPolicyImpl(api_level, artHandle, hookFun)) {
LOGI("disable_HiddenAPIPolicyImpl done.");
hookInstrumentation(api_level, artHandle, hookFun);
hookIsInSamePackage(api_level, artHandle, hookFun);
if (disableHiddenAPIPolicyImpl(api_level, artHandle, hookFun)) {
LOGI("disableHiddenAPIPolicyImpl done.");
} else {
LOGE("disable_HiddenAPIPolicyImpl failed.");
LOGE("disableHiddenAPIPolicyImpl failed.");
}
dlclose(whaleHandle);
dlclose(artHandle);

View File

@ -21,4 +21,6 @@ static constexpr const char *kLibWhalePath = "/system/lib/libwhale.so";
void install_inline_hooks();
void deoptimize_method(JNIEnv *env, jclass clazz, jobject method);
#endif // HOOK_H