[core] Only allow hidden api for recognized classloaders (#537)
This commit is contained in:
parent
94ef17f06d
commit
d22a4efe72
|
|
@ -20,56 +20,84 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "symbol_cache.h"
|
||||||
#include "base/object.h"
|
#include "base/object.h"
|
||||||
|
#include "context.h"
|
||||||
|
#include "runtime.h"
|
||||||
|
|
||||||
namespace art {
|
namespace art {
|
||||||
|
|
||||||
namespace hidden_api {
|
namespace hidden_api {
|
||||||
|
|
||||||
enum Action {
|
CREATE_FUNC_SYMBOL_ENTRY(void, DexFile_setTrusted, JNIEnv *env, jclass clazz,
|
||||||
kAllow,
|
jobject j_cookie) {
|
||||||
kAllowButWarn,
|
if (LIKELY(DexFile_setTrustedSym != nullptr)) {
|
||||||
kAllowButWarnAndToast,
|
Runtime::Current()->SetJavaDebuggable(true);
|
||||||
kDeny
|
DexFile_setTrustedSym(env, clazz, j_cookie);
|
||||||
|
Runtime::Current()->SetJavaDebuggable(false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
CREATE_HOOK_STUB_ENTRIES(
|
inline void
|
||||||
"_ZN3art9hiddenapi6detail19GetMemberActionImplINS_9ArtMethodEEENS0_6ActionEPT_NS_20HiddenApiAccessFlags7ApiListES4_NS0_12AccessMethodE",
|
maybeSetTrusted(JNIEnv *env, jclass clazz, jobject class_loader, jobject j_cookie) {
|
||||||
Action, GetMethodActionImpl, (), {
|
static auto get_parent = env->GetMethodID(env->FindClass("java/lang/ClassLoader"),
|
||||||
return Action::kAllow;
|
"getParent", "()Ljava/lang/ClassLoader;");
|
||||||
});
|
for (auto current = lspd::Context::GetInstance()->GetCurrentClassLoader();
|
||||||
|
class_loader != nullptr;
|
||||||
|
class_loader = env->CallObjectMethod(class_loader, get_parent)) {
|
||||||
|
if (!current || env->IsSameObject(class_loader, current)) {
|
||||||
|
DexFile_setTrusted(env, clazz, j_cookie);
|
||||||
|
LOGD("Set classloader as trusted");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CREATE_HOOK_STUB_ENTRIES(
|
CREATE_HOOK_STUB_ENTRIES(
|
||||||
"_ZN3art9hiddenapi6detail19GetMemberActionImplINS_8ArtFieldEEENS0_6ActionEPT_NS_20HiddenApiAccessFlags7ApiListES4_NS0_12AccessMethodE",
|
"_ZN3artL25DexFile_openDexFileNativeEP7_JNIEnvP7_jclassP8_jstringS5_iP8_jobjectP13_jobjectArray",
|
||||||
Action, GetFieldActionImpl, (), {
|
jobject, DexFile_openDexFileNative, (JNIEnv * env,
|
||||||
return Action::kAllow;
|
jclass clazz,
|
||||||
});
|
jstring javaSourceName,
|
||||||
|
jstring javaOutputName,
|
||||||
|
jint flags,
|
||||||
|
jobject class_loader,
|
||||||
|
jobjectArray dex_elements), {
|
||||||
|
auto j_cookie = backup(env, clazz, javaSourceName, javaOutputName, flags,
|
||||||
|
class_loader,
|
||||||
|
dex_elements);
|
||||||
|
maybeSetTrusted(env, clazz, class_loader, j_cookie);
|
||||||
|
return j_cookie;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
CREATE_HOOK_STUB_ENTRIES(
|
CREATE_HOOK_STUB_ENTRIES(
|
||||||
"_ZN3art9hiddenapi6detail28ShouldDenyAccessToMemberImplINS_9ArtMethodEEEbPT_NS0_7ApiListENS0_12AccessMethodE",
|
"_ZN3artL34DexFile_openInMemoryDexFilesNativeEP7_JNIEnvP7_jclassP13_jobjectArrayS5_P10_jintArrayS7_P8_jobjectS5_",
|
||||||
bool, ShouldDenyAccessToMethodImpl, (), {
|
jobject, DexFile_openInMemoryDexFilesNative, (JNIEnv * env,
|
||||||
return false;
|
jclass clazz,
|
||||||
});
|
jobjectArray buffers,
|
||||||
|
jobjectArray arrays,
|
||||||
|
jintArray jstarts,
|
||||||
|
jintArray jends,
|
||||||
|
jobject class_loader,
|
||||||
|
jobjectArray dex_elements), {
|
||||||
|
auto j_cookie = backup(env, clazz, buffers, arrays, jstarts, jends,
|
||||||
|
class_loader,
|
||||||
|
dex_elements);
|
||||||
|
maybeSetTrusted(env, clazz, class_loader, j_cookie);
|
||||||
|
return j_cookie;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
CREATE_HOOK_STUB_ENTRIES(
|
|
||||||
"_ZN3art9hiddenapi6detail28ShouldDenyAccessToMemberImplINS_8ArtFieldEEEbPT_NS0_7ApiListENS0_12AccessMethodE",
|
|
||||||
bool, ShouldDenyAccessToFieldImpl, (), {
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
// @ApiSensitive(Level.HIGH)
|
|
||||||
static void DisableHiddenApi(void *handle) {
|
static void DisableHiddenApi(void *handle) {
|
||||||
|
|
||||||
const int api_level = lspd::GetAndroidApiLevel();
|
const int api_level = lspd::GetAndroidApiLevel();
|
||||||
if (api_level < __ANDROID_API_P__) {
|
if (api_level < __ANDROID_API_P__) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (api_level == __ANDROID_API_P__) {
|
DexFile_setTrustedSym = reinterpret_cast<decltype(DexFile_setTrustedSym)>(lspd::sym_setTrusted);
|
||||||
lspd::HookSyms(handle, GetMethodActionImpl);
|
lspd::HookSymNoHandle(lspd::sym_openDexFileNative, DexFile_openDexFileNative);
|
||||||
lspd::HookSyms(handle, GetFieldActionImpl);
|
lspd::HookSymNoHandle(lspd::sym_openInMemoryDexFilesNative,
|
||||||
} else {
|
DexFile_openInMemoryDexFilesNative);
|
||||||
lspd::HookSyms(handle, ShouldDenyAccessToMethodImpl);
|
|
||||||
lspd::HookSyms(handle, ShouldDenyAccessToFieldImpl);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,11 @@ namespace art {
|
||||||
class Runtime : public lspd::HookedObject {
|
class Runtime : public lspd::HookedObject {
|
||||||
private:
|
private:
|
||||||
inline static Runtime *instance_;
|
inline static Runtime *instance_;
|
||||||
|
CREATE_MEM_FUNC_SYMBOL_ENTRY(void, SetJavaDebuggable, void *thiz, bool value) {
|
||||||
|
if (LIKELY(SetJavaDebuggableSym)) {
|
||||||
|
SetJavaDebuggableSym(thiz, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Runtime(void *thiz) : HookedObject(thiz) {}
|
Runtime(void *thiz) : HookedObject(thiz) {}
|
||||||
|
|
@ -35,10 +40,15 @@ namespace art {
|
||||||
return instance_;
|
return instance_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetJavaDebuggable(bool value) {
|
||||||
|
SetJavaDebuggable(thiz_, value);
|
||||||
|
}
|
||||||
|
|
||||||
// @ApiSensitive(Level.LOW)
|
// @ApiSensitive(Level.LOW)
|
||||||
static void Setup(void *handle) {
|
static void Setup(void *handle) {
|
||||||
RETRIEVE_FIELD_SYMBOL(instance, "_ZN3art7Runtime9instance_E");
|
RETRIEVE_FIELD_SYMBOL(instance, "_ZN3art7Runtime9instance_E");
|
||||||
void * thiz = *reinterpret_cast<void**>(instance);
|
RETRIEVE_MEM_FUNC_SYMBOL(SetJavaDebuggable, "_ZN3art7Runtime17SetJavaDebuggableEb");
|
||||||
|
void *thiz = *reinterpret_cast<void **>(instance);
|
||||||
LOGD("_ZN3art7Runtime9instance_E = %p", thiz);
|
LOGD("_ZN3art7Runtime9instance_E = %p", thiz);
|
||||||
instance_ = new Runtime(thiz);
|
instance_ = new Runtime(thiz);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -220,8 +220,8 @@ namespace lspd {
|
||||||
auto binder = skip_ ? ScopedLocalRef<jobject>{env, nullptr}
|
auto binder = skip_ ? ScopedLocalRef<jobject>{env, nullptr}
|
||||||
: Service::instance()->RequestBinder(env, nice_name_);
|
: Service::instance()->RequestBinder(env, nice_name_);
|
||||||
if (binder) {
|
if (binder) {
|
||||||
LoadDex(env);
|
|
||||||
InstallInlineHooks();
|
InstallInlineHooks();
|
||||||
|
LoadDex(env);
|
||||||
Init(env);
|
Init(env);
|
||||||
LOGD("Done prepare");
|
LOGD("Done prepare");
|
||||||
FindAndCall(env, "forkAndSpecializePost",
|
FindAndCall(env, "forkAndSpecializePost",
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ namespace lspd {
|
||||||
return std::move(instance_);
|
return std::move(instance_);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline auto GetCurrentClassLoader() const { return inject_class_loader_; }
|
inline jobject GetCurrentClassLoader() const { return inject_class_loader_; }
|
||||||
|
|
||||||
void CallOnPostFixupStaticTrampolines(void *class_ptr);
|
void CallOnPostFixupStaticTrampolines(void *class_ptr);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -70,8 +70,8 @@ namespace lspd {
|
||||||
if (art_hooks_installed) {
|
if (art_hooks_installed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
art::hidden_api::DisableHiddenApi(art_handle);
|
|
||||||
art::Runtime::Setup(art_handle);
|
art::Runtime::Setup(art_handle);
|
||||||
|
art::hidden_api::DisableHiddenApi(art_handle);
|
||||||
art::art_method::Setup(art_handle);
|
art::art_method::Setup(art_handle);
|
||||||
art::Thread::Setup(art_handle);
|
art::Thread::Setup(art_handle);
|
||||||
art::ClassLinker::Setup(art_handle);
|
art::ClassLinker::Setup(art_handle);
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@ namespace lspd {
|
||||||
Service::exec_transact_replace(jboolean *res, JNIEnv *env, [[maybe_unused]] jobject obj,
|
Service::exec_transact_replace(jboolean *res, JNIEnv *env, [[maybe_unused]] jobject obj,
|
||||||
va_list args) {
|
va_list args) {
|
||||||
jint code;
|
jint code;
|
||||||
|
|
||||||
va_list copy;
|
va_list copy;
|
||||||
va_copy(copy, args);
|
va_copy(copy, args);
|
||||||
code = va_arg(copy, jint);
|
code = va_arg(copy, jint);
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,9 @@ namespace lspd {
|
||||||
void *sym_system_property_get = nullptr;
|
void *sym_system_property_get = nullptr;
|
||||||
void *sym_get_property = nullptr;
|
void *sym_get_property = nullptr;
|
||||||
void *handle_libart = nullptr;
|
void *handle_libart = nullptr;
|
||||||
|
void *sym_openInMemoryDexFilesNative = nullptr;
|
||||||
|
void *sym_openDexFileNative = nullptr;
|
||||||
|
void *sym_setTrusted = nullptr;
|
||||||
|
|
||||||
struct soinfo;
|
struct soinfo;
|
||||||
|
|
||||||
|
|
@ -117,9 +120,14 @@ namespace lspd {
|
||||||
for (const auto &soinfo : linker_get_solist()) {
|
for (const auto &soinfo : linker_get_solist()) {
|
||||||
if (const auto &real_path = soinfo->get_realpath(), &soname = soinfo->get_soname();
|
if (const auto &real_path = soinfo->get_realpath(), &soname = soinfo->get_soname();
|
||||||
(real_path &&
|
(real_path &&
|
||||||
std::string_view(real_path).find(kLibArtName) != std::string_view::npos) ||
|
std::string_view(real_path).find(kLibArtName) != std::string_view::npos)) {
|
||||||
(soname &&
|
auto art = SandHook::ElfImg(real_path);
|
||||||
std::string_view(soname).find(kLibArtName) != std::string_view::npos)) {
|
if ((sym_openDexFileNative = reinterpret_cast<void *>(art.getSymbAddress(
|
||||||
|
"_ZN3artL25DexFile_openDexFileNativeEP7_JNIEnvP7_jclassP8_jstringS5_iP8_jobjectP13_jobjectArray"))) &&
|
||||||
|
(sym_openInMemoryDexFilesNative = reinterpret_cast<void *>(art.getSymbAddress(
|
||||||
|
"_ZN3artL34DexFile_openInMemoryDexFilesNativeEP7_JNIEnvP7_jclassP13_jobjectArrayS5_P10_jintArrayS7_P8_jobjectS5_"))) &&
|
||||||
|
(sym_setTrusted = reinterpret_cast<void *>(art.getSymbAddress(
|
||||||
|
"_ZN3artL18DexFile_setTrustedEP7_JNIEnvP7_jclassP8_jobject"))))
|
||||||
return soinfo->to_handle();
|
return soinfo->to_handle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,9 @@ namespace lspd {
|
||||||
extern void *sym_system_property_get;
|
extern void *sym_system_property_get;
|
||||||
extern void *sym_get_property;
|
extern void *sym_get_property;
|
||||||
extern void *handle_libart;
|
extern void *handle_libart;
|
||||||
|
extern void *sym_openInMemoryDexFilesNative;
|
||||||
|
extern void *sym_openDexFileNative;
|
||||||
|
extern void *sym_setTrusted;
|
||||||
|
|
||||||
void InitSymbolCache();
|
void InitSymbolCache();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue