Fix IllegalAccessException via inline hooking method "IsInSamePackage" in libart.so, using Whale framework

This commit is contained in:
solohsu 2019-02-09 17:03:25 +08:00
parent c179778ce3
commit 285ced4cf9
4 changed files with 99 additions and 15 deletions

View File

@ -0,0 +1,30 @@
#ifndef WHALE_ANDROID_ANDROID_BUILD_H_
#define WHALE_ANDROID_ANDROID_BUILD_H_
#include <cstdint>
#include <cstdlib>
#include <sys/system_properties.h>
#define ANDROID_ICE_CREAM_SANDWICH 14
#define ANDROID_ICE_CREAM_SANDWICH_MR1 15
#define ANDROID_JELLY_BEAN 16
#define ANDROID_JELLY_BEAN_MR1 17
#define ANDROID_JELLY_BEAN_MR2 18
#define ANDROID_KITKAT 19
#define ANDROID_KITKAT_WATCH 20
#define ANDROID_LOLLIPOP 21
#define ANDROID_LOLLIPOP_MR1 22
#define ANDROID_M 23
#define ANDROID_N 24
#define ANDROID_N_MR1 25
#define ANDROID_O 26
#define ANDROID_O_MR1 27
#define ANDROID_P 28
static inline int32_t GetAndroidApiLevel() {
char prop_value[PROP_VALUE_MAX];
__system_property_get("ro.build.version.sdk", prop_value);
return atoi(prop_value);
}
#endif // WHALE_ANDROID_ANDROID_BUILD_H_

View File

@ -7,6 +7,7 @@
#include <dlfcn.h>
#include "java_hook/java_hook.h"
#include "include/logging.h"
#include "native_hook/native_hook.h"
extern "C"
{
@ -44,6 +45,7 @@ void loadDexAndInit(JNIEnv *env, const char *dexPath) {
if (isInited) {
return;
}
install_inline_hooks();
jclass clzClassLoader = env->FindClass("java/lang/ClassLoader");
LOGD("java/lang/ClassLoader: %p", clzClassLoader);
jmethodID mdgetSystemClassLoader = env->GetStaticMethodID(clzClassLoader,

View File

@ -1,20 +1,62 @@
#include <cstdio>
#include <cstring>
#include <chrono>
#include <fcntl.h>
#include <unistd.h>
#include <sys/vfs.h>
#include <sys/stat.h>
#include <dirent.h>
#include <dlfcn.h>
#include <cstdlib>
#include <include/android_build.h>
#include <string>
#include <sys/system_properties.h>
#include <jni.h>
#include "include/riru.h"
#include "include/logging.h"
#include "native_hook.h"
#include "java_hook/java_hook.h"
#include "inject/framework_hook.h"
static const char *(*getDesc)(void *, std::string *);
static bool (*isInSamePackageBackup)(void *, void *) = nullptr;
bool onIsInSamePackageCalled(void *thiz, void *that) {
std::string storage1, storage2;
const char *thisDesc = (*getDesc)(thiz, &storage1);
const char *thatDesc = (*getDesc)(that, &storage2);
// LOGE("onIsInSamePackageCalled, %s -> %s", thisDesc, thatDesc);
if (strstr(thisDesc, "EdHooker") != nullptr || strstr(thatDesc, "EdHooker") != nullptr) {
return true;
}
return (*isInSamePackageBackup)(thiz, that);
}
void install_inline_hooks() {
int api_level = GetAndroidApiLevel();
if (api_level < ANDROID_LOLLIPOP) {
return;
}
void *whaleHandle = dlopen(kLibWhalePath, RTLD_NOW);
if (!whaleHandle) {
LOGE("can't open libwhale");
return;
}
void *hookFunSym = dlsym(whaleHandle, "WInlineHookFunction");
if (!hookFunSym) {
LOGE("can't get WInlineHookFunction");
return;
}
void (*hookFun)(void *, void *, void **) = reinterpret_cast<void (*)(void *, void *,
void **)>(hookFunSym);
void *artHandle = dlopen(kLibArtPath, RTLD_NOW);
if (!artHandle) {
LOGE("can't open libart");
return;
}
// 5.0 - 7.1
const char *isInSamePackageSym = "_ZN3art6mirror5Class15IsInSamePackageEPS1_";
const char *getDescriptorSym = "_ZN3art6mirror5Class13GetDescriptorEPNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE";
if (api_level >= ANDROID_O) {
// 8.0 and later
isInSamePackageSym = "_ZN3art6mirror5Class15IsInSamePackageENS_6ObjPtrIS1_EE";
}
void *original = dlsym(artHandle, isInSamePackageSym);
getDesc = reinterpret_cast<const char *(*)(void *, std::string *)>(dlsym(artHandle,
getDescriptorSym));
if (!original) {
LOGE("can't get isInSamePackageSym");
return;
}
(*hookFun)(original, reinterpret_cast<void *>(onIsInSamePackageCalled),
reinterpret_cast<void **>(&isInSamePackageBackup));
}

View File

@ -3,6 +3,14 @@
#include <xhook/xhook.h>
#if defined(__LP64__)
static constexpr const char *kLibArtPath = "/system/lib64/libart.so";
static constexpr const char *kLibWhalePath = "/system/lib64/libwhale.so";
#else
static constexpr const char *kLibArtPath = "/system/lib/libart.so";
static constexpr const char *kLibWhalePath = "/system/lib/libwhale.so";
#endif
#define XHOOK_REGISTER(NAME) \
if (xhook_register(".*", #NAME, (void*) new_##NAME, (void **) &old_##NAME) != 0) \
LOGE("failed to register hook " #NAME "."); \
@ -11,4 +19,6 @@
static ret (*old_##func)(__VA_ARGS__); \
static ret new_##func(__VA_ARGS__)
void install_inline_hooks();
#endif // HOOK_H