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