[core] Only allow hidden api for recognized classloaders (#537)

This commit is contained in:
LoveSy 2021-05-06 14:09:02 +08:00 committed by GitHub
parent 94ef17f06d
commit d22a4efe72
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 89 additions and 41 deletions

View File

@ -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);
}
}; };
} }

View File

@ -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);
} }

View File

@ -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",

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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();
} }
} }

View File

@ -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();
} }