Update JingMatrix/LSPosed

To avoid a crash in the fisrt launch (#7), we cannot use PLT
.inline_hooker to DisableBackgroundVerification.

Remove ccache to avoid difference between CI builds and local builds.
This commit is contained in:
JingMatrix 2024-09-12 11:12:02 +02:00
parent a85a0fa578
commit 557d56091d
7 changed files with 189 additions and 179 deletions

View File

@ -58,17 +58,6 @@ jobs:
with: with:
gradle-home-cache-cleanup: true gradle-home-cache-cleanup: true
- name: Setup ccache
uses: hendrikmuhs/ccache-action@v1
with:
max-size: 2G
key: lsp
restore-keys: lsp
save: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
- name: Setup Android SDK
uses: android-actions/setup-android@v3
- name: Setup ninja - name: Setup ninja
uses: seanmiddleditch/gha-setup-ninja@master uses: seanmiddleditch/gha-setup-ninja@master
with: with:

2
core

@ -1 +1 @@
Subproject commit bdba029fe9ebde961a4e7f9047226d4d7258c233 Subproject commit db9b97e53d39bb06d8ba706b74ccf01a80f2221c

View File

@ -10,47 +10,49 @@
using namespace lsplant; using namespace lsplant;
namespace art { namespace art {
CREATE_MEM_HOOK_STUB_ENTRY( class ProfileSaver {
"_ZN3art12ProfileSaver20ProcessProfilingInfoEbPt", private:
bool, ProcessProfilingInfo, (void * thiz, bool, uint16_t *), { inline static MemberHooker<"_ZN3art12ProfileSaver20ProcessProfilingInfoEbPt", ProfileSaver,
bool(bool, uint16_t *)>
ProcessProfilingInfo_ = +[](ProfileSaver *thiz, bool a, uint16_t *b) {
LOGD("skipped profile saving"); LOGD("skipped profile saving");
return true; return true;
}); };
CREATE_MEM_HOOK_STUB_ENTRY( inline static MemberHooker<"_ZN3art12ProfileSaver20ProcessProfilingInfoEbbPt", ProfileSaver,
"_ZN3art12ProfileSaver20ProcessProfilingInfoEbbPt", bool(bool, bool, uint16_t *)>
bool, ProcessProfilingInfoWithBool, (void * thiz, bool, bool, uint16_t *), { ProcessProfilingInfoWithBool_ = +[](ProfileSaver *thiz, bool, bool, uint16_t *) {
LOGD("skipped profile saving"); LOGD("skipped profile saving");
return true; return true;
}); };
CREATE_HOOK_STUB_ENTRY( inline static Hooker<"execve",
"execve", int(const char *pathname, const char *argv[], char *const envp[])>
int, execve, (const char *pathname, const char *argv[], char *const envp[]), { execve_ = +[](const char *pathname, const char *argv[], char *const envp[]) {
if (strstr(pathname, "dex2oat")) { if (strstr(pathname, "dex2oat")) {
size_t count = 0; size_t count = 0;
while (argv[count++] != nullptr); while (argv[count++] != nullptr);
std::unique_ptr<const char *[]> new_args = std::make_unique<const char *[]>( std::unique_ptr<const char *[]> new_args =
count + 1); std::make_unique<const char *[]>(count + 1);
for (size_t i = 0; i < count - 1; ++i) for (size_t i = 0; i < count - 1; ++i) new_args[i] = argv[i];
new_args[i] = argv[i];
new_args[count - 1] = "--inline-max-code-units=0"; new_args[count - 1] = "--inline-max-code-units=0";
new_args[count] = nullptr; new_args[count] = nullptr;
LOGD("dex2oat by disable inline!"); LOGD("dex2oat by disable inline!");
int ret = backup(pathname, new_args.get(), envp); int ret = execve_(pathname, new_args.get(), envp);
return ret; return ret;
} }
int ret = backup(pathname, argv, envp); int ret = execve_(pathname, argv, envp);
return ret; return ret;
}); };
public:
static void DisableInline(const HookHandler &handler) { static void DisableInline(const HookHandler &handler) {
HookSyms(handler, ProcessProfilingInfo, ProcessProfilingInfoWithBool); handler.hook(ProcessProfilingInfo_);
HookSymNoHandle(handler, reinterpret_cast<void*>(&::execve), execve); handler.hook(ProcessProfilingInfoWithBool_);
handler.hook(execve_);
} }
} };
} // namespace art
#endif // LSPATCH_PROFILE_SAVER_H #endif // LSPATCH_PROFILE_SAVER_H

View File

@ -26,39 +26,46 @@
using namespace lsplant; using namespace lsplant;
namespace art { namespace art {
CREATE_MEM_HOOK_STUB_ENTRY( class FileManager {
"_ZN3art14OatFileManager25RunBackgroundVerificationERKNSt3__16vectorIPKNS_7DexFileENS1_9allocatorIS5_EEEEP8_jobjectPKc", public:
void, RunBackgroundVerificationWithContext, inline static MemberHooker<
(void * thiz, const std::vector<const void *> &dex_files, "_ZN3art14OatFileManager25RunBackgroundVerificationERKNSt3__"
jobject class_loader, "16vectorIPKNS_7DexFileENS1_9allocatorIS5_EEEEP8_jobjectPKc",
const char *class_loader_context), { FileManager, void(const std::vector<const void *> &, jobject, const char *)>
RunBackgroundVerificationWithContext_ =
+[](FileManager *thiz, const std::vector<const void *> &dex_files, jobject class_loader,
const char *class_loader_context) {
if (lspd::Context::GetInstance()->GetCurrentClassLoader() == nullptr) { if (lspd::Context::GetInstance()->GetCurrentClassLoader() == nullptr) {
LOGD("Disabled background verification"); LOGD("Disabled background verification");
return; return;
} }
backup(thiz, dex_files, class_loader, class_loader_context); RunBackgroundVerificationWithContext_(thiz, dex_files, class_loader,
}); class_loader_context);
};
CREATE_MEM_HOOK_STUB_ENTRY( inline static MemberHooker<
"_ZN3art14OatFileManager25RunBackgroundVerificationERKNSt3__16vectorIPKNS_7DexFileENS1_9allocatorIS5_EEEEP8_jobject", "_ZN3art14OatFileManager25RunBackgroundVerificationERKNSt3__"
void, RunBackgroundVerification, "16vectorIPKNS_7DexFileENS1_9allocatorIS5_EEEEP8_jobject",
(void * thiz, const std::vector<const void *> &dex_files, FileManager, void(const std::vector<const void *> &, jobject)>
jobject class_loader), { RunBackgroundVerification_ =
+[](FileManager *thiz, const std::vector<const void *> &dex_files,
jobject class_loader) {
if (lspd::Context::GetInstance()->GetCurrentClassLoader() == nullptr) { if (lspd::Context::GetInstance()->GetCurrentClassLoader() == nullptr) {
LOGD("Disabled background verification"); LOGD("Disabled background verification");
return; return;
} }
backup(thiz, dex_files, class_loader); RunBackgroundVerification_(thiz, dex_files, class_loader);
}); };
public:
static void DisableBackgroundVerification(const lsplant::HookHandler &handler) { static void DisableBackgroundVerification(const lsplant::HookHandler &handler) {
const int api_level = lspd::GetAndroidApiLevel(); const int api_level = lspd::GetAndroidApiLevel();
if (api_level >= __ANDROID_API_Q__) { if (api_level >= __ANDROID_API_Q__) {
HookSyms(handler, RunBackgroundVerificationWithContext, RunBackgroundVerification); handler.hook(RunBackgroundVerificationWithContext_);
handler.hook(RunBackgroundVerification_);
} }
} }
} };
} // namespace art
#endif // LSPATCH_OAT_FILE_MANAGER_H #endif // LSPATCH_OAT_FILE_MANAGER_H

View File

@ -2,6 +2,7 @@
// Created by VIP on 2021/4/25. // Created by VIP on 2021/4/25.
// //
#include "../src/native_api.h"
#include "bypass_sig.h" #include "bypass_sig.h"
#include "elf_util.h" #include "elf_util.h"
#include "logging.h" #include "logging.h"
@ -15,20 +16,28 @@ namespace lspd {
std::string apkPath; std::string apkPath;
std::string redirectPath; std::string redirectPath;
CREATE_HOOK_STUB_ENTRY( inline static lsplant::Hooker<"__openat", int(int, const char*, int flag, int)> __openat_ =
"__openat", +[](int fd, const char* pathname, int flag, int mode) {
int, __openat,
(int fd, const char* pathname, int flag, int mode), {
if (pathname == apkPath) { if (pathname == apkPath) {
LOGD("redirect openat"); LOGD("redirect openat");
return backup(fd, redirectPath.c_str(), flag, mode); return __openat_(fd, redirectPath.c_str(), flag, mode);
} }
return backup(fd, pathname, flag, mode); return __openat_(fd, pathname, flag, mode);
}); };
LSP_DEF_NATIVE_METHOD(void, SigBypass, enableOpenatHook, jstring origApkPath, jstring cacheApkPath) { bool HookOpenat(const lsplant::HookHandler& handler) { return handler.hook(__openat_); }
auto sym_openat = SandHook::ElfImg("libc.so").getSymbAddress<void *>("__openat");
auto r = HookSymNoHandle(handler, sym_openat, __openat); LSP_DEF_NATIVE_METHOD(void, SigBypass, enableOpenatHook, jstring origApkPath,
jstring cacheApkPath) {
auto r = HookOpenat(lsplant::InitInfo{
.inline_hooker =
[](auto t, auto r) {
void* bk = nullptr;
return HookInline(t, r, &bk) == 0 ? bk : nullptr;
},
.art_symbol_resolver =
[](auto symbol) { return SandHook::ElfImg("libc.so").getSymbAddress(symbol); },
});
if (!r) { if (!r) {
LOGE("Hook __openat fail"); LOGE("Hook __openat fail");
return; return;
@ -42,10 +51,8 @@ namespace lspd {
} }
static JNINativeMethod gMethods[] = { static JNINativeMethod gMethods[] = {
LSP_NATIVE_METHOD(SigBypass, enableOpenatHook, "(Ljava/lang/String;Ljava/lang/String;)V") LSP_NATIVE_METHOD(SigBypass, enableOpenatHook, "(Ljava/lang/String;Ljava/lang/String;)V")};
};
void RegisterBypass(JNIEnv* env) { void RegisterBypass(JNIEnv* env) { REGISTER_LSP_NATIVE_METHODS(SigBypass); }
REGISTER_LSP_NATIVE_METHODS(SigBypass);
} } // namespace lspd
}

View File

@ -21,12 +21,13 @@
// Created by Nullptr on 2022/3/17. // Created by Nullptr on 2022/3/17.
// //
#include "art/runtime/oat_file_manager.h" #include "patch_loader.h"
#include "art/runtime/jit/profile_saver.h" #include "art/runtime/jit/profile_saver.h"
#include "art/runtime/oat_file_manager.h"
#include "elf_util.h" #include "elf_util.h"
#include "jni/bypass_sig.h" #include "jni/bypass_sig.h"
#include "native_util.h" #include "native_util.h"
#include "patch_loader.h"
#include "symbol_cache.h" #include "symbol_cache.h"
#include "utils/jni_helper.hpp" #include "utils/jni_helper.hpp"
@ -36,17 +37,21 @@ namespace lspd {
void PatchLoader::LoadDex(JNIEnv* env, Context::PreloadedDex&& dex) { void PatchLoader::LoadDex(JNIEnv* env, Context::PreloadedDex&& dex) {
auto class_activity_thread = JNI_FindClass(env, "android/app/ActivityThread"); auto class_activity_thread = JNI_FindClass(env, "android/app/ActivityThread");
auto class_activity_thread_app_bind_data = JNI_FindClass(env, "android/app/ActivityThread$AppBindData"); auto class_activity_thread_app_bind_data =
JNI_FindClass(env, "android/app/ActivityThread$AppBindData");
auto class_loaded_apk = JNI_FindClass(env, "android/app/LoadedApk"); auto class_loaded_apk = JNI_FindClass(env, "android/app/LoadedApk");
auto mid_current_activity_thread = JNI_GetStaticMethodID(env, class_activity_thread, "currentActivityThread", auto mid_current_activity_thread = JNI_GetStaticMethodID(
"()Landroid/app/ActivityThread;"); env, class_activity_thread, "currentActivityThread", "()Landroid/app/ActivityThread;");
auto mid_get_classloader = JNI_GetMethodID(env, class_loaded_apk, "getClassLoader", "()Ljava/lang/ClassLoader;"); auto mid_get_classloader =
JNI_GetMethodID(env, class_loaded_apk, "getClassLoader", "()Ljava/lang/ClassLoader;");
auto fid_m_bound_application = JNI_GetFieldID(env, class_activity_thread, "mBoundApplication", auto fid_m_bound_application = JNI_GetFieldID(env, class_activity_thread, "mBoundApplication",
"Landroid/app/ActivityThread$AppBindData;"); "Landroid/app/ActivityThread$AppBindData;");
auto fid_info = JNI_GetFieldID(env, class_activity_thread_app_bind_data, "info", "Landroid/app/LoadedApk;"); auto fid_info =
JNI_GetFieldID(env, class_activity_thread_app_bind_data, "info", "Landroid/app/LoadedApk;");
auto activity_thread = JNI_CallStaticObjectMethod(env, class_activity_thread, mid_current_activity_thread); auto activity_thread =
JNI_CallStaticObjectMethod(env, class_activity_thread, mid_current_activity_thread);
auto m_bound_application = JNI_GetObjectField(env, activity_thread, fid_m_bound_application); auto m_bound_application = JNI_GetObjectField(env, activity_thread, fid_m_bound_application);
auto info = JNI_GetObjectField(env, m_bound_application, fid_info); auto info = JNI_GetObjectField(env, m_bound_application, fid_info);
auto stub_classloader = JNI_CallObjectMethod(env, info, mid_get_classloader); auto stub_classloader = JNI_CallObjectMethod(env, info, mid_get_classloader);
@ -61,7 +66,8 @@ namespace lspd {
"(Ljava/nio/ByteBuffer;Ljava/lang/ClassLoader;)V"); "(Ljava/nio/ByteBuffer;Ljava/lang/ClassLoader;)V");
auto byte_buffer_class = JNI_FindClass(env, "java/nio/ByteBuffer"); auto byte_buffer_class = JNI_FindClass(env, "java/nio/ByteBuffer");
auto dex_buffer = env->NewDirectByteBuffer(dex.data(), dex.size()); auto dex_buffer = env->NewDirectByteBuffer(dex.data(), dex.size());
if (auto my_cl = JNI_NewObject(env, in_memory_classloader, mid_init, dex_buffer, stub_classloader)) { if (auto my_cl =
JNI_NewObject(env, in_memory_classloader, mid_init, dex_buffer, stub_classloader)) {
inject_class_loader_ = JNI_NewGlobalRef(env, my_cl); inject_class_loader_ = JNI_NewGlobalRef(env, my_cl);
} else { } else {
LOGE("InMemoryDexClassLoader creation failed!!!"); LOGE("InMemoryDexClassLoader creation failed!!!");
@ -74,8 +80,8 @@ namespace lspd {
void PatchLoader::InitArtHooker(JNIEnv* env, const InitInfo& initInfo) { void PatchLoader::InitArtHooker(JNIEnv* env, const InitInfo& initInfo) {
Context::InitArtHooker(env, initInfo); Context::InitArtHooker(env, initInfo);
handler = initInfo; handler = initInfo;
art::DisableInline(initInfo); art::ProfileSaver::DisableInline(initInfo);
art::DisableBackgroundVerification(initInfo); art::FileManager::DisableBackgroundVerification(initInfo);
} }
void PatchLoader::InitHooks(JNIEnv* env) { void PatchLoader::InitHooks(JNIEnv* env) {
@ -93,26 +99,23 @@ namespace lspd {
void PatchLoader::Load(JNIEnv* env) { void PatchLoader::Load(JNIEnv* env) {
/* InitSymbolCache(nullptr); */ /* InitSymbolCache(nullptr); */
lsplant::InitInfo initInfo{ lsplant::InitInfo initInfo{
.inline_hooker = [](auto t, auto r) { .inline_hooker =
[](auto t, auto r) {
void* bk = nullptr; void* bk = nullptr;
return HookFunction(t, r, &bk) == RS_SUCCESS ? bk : nullptr; return HookInline(t, r, &bk) == 0 ? bk : nullptr;
},
.inline_unhooker = [](auto t) {
return UnhookFunction(t) == RT_SUCCESS;
},
.art_symbol_resolver = [](auto symbol) {
return GetArt()->getSymbAddress<void*>(symbol);
},
.art_symbol_prefix_resolver = [](auto symbol) {
return GetArt()->getSymbPrefixFirstAddress(symbol);
}, },
.inline_unhooker = [](auto t) { return UnhookInline(t) == 0; },
.art_symbol_resolver = [](auto symbol) { return GetArt()->getSymbAddress(symbol); },
.art_symbol_prefix_resolver =
[](auto symbol) { return GetArt()->getSymbPrefixFirstAddress(symbol); },
}; };
auto stub = JNI_FindClass(env, "org/lsposed/lspatch/metaloader/LSPAppComponentFactoryStub"); auto stub = JNI_FindClass(env, "org/lsposed/lspatch/metaloader/LSPAppComponentFactoryStub");
auto dex_field = JNI_GetStaticFieldID(env, stub, "dex", "[B"); auto dex_field = JNI_GetStaticFieldID(env, stub, "dex", "[B");
ScopedLocalRef<jbyteArray> array = JNI_GetStaticObjectField(env, stub, dex_field); ScopedLocalRef<jbyteArray> array = JNI_GetStaticObjectField(env, stub, dex_field);
auto dex = PreloadedDex {env->GetByteArrayElements(array.get(), nullptr), static_cast<size_t>(JNI_GetArrayLength(env, array))}; auto dex = PreloadedDex{env->GetByteArrayElements(array.get(), nullptr),
static_cast<size_t>(JNI_GetArrayLength(env, array))};
InitArtHooker(env, initInfo); InitArtHooker(env, initInfo);
LoadDex(env, std::move(dex)); LoadDex(env, std::move(dex));

View File

@ -31,9 +31,10 @@ dependencyResolutionManagement {
rootProject.name = "LSPatch" rootProject.name = "LSPatch"
include( include(
":apache",
":apkzlib", ":apkzlib",
":core",
":axml", ":axml",
":core",
":hiddenapi:bridge", ":hiddenapi:bridge",
":hiddenapi:stubs", ":hiddenapi:stubs",
":jar", ":jar",
@ -48,8 +49,9 @@ include(
":share:java", ":share:java",
) )
project(":core").projectDir = file("core/core") project(":apache").projectDir = file("core/apache")
project(":axml").projectDir = file("core/axml") project(":axml").projectDir = file("core/axml")
project(":core").projectDir = file("core/core")
project(":hiddenapi:bridge").projectDir = file("core/hiddenapi/bridge") project(":hiddenapi:bridge").projectDir = file("core/hiddenapi/bridge")
project(":hiddenapi:stubs").projectDir = file("core/hiddenapi/stubs") project(":hiddenapi:stubs").projectDir = file("core/hiddenapi/stubs")
project(":services:daemon-service").projectDir = file("core/services/daemon-service") project(":services:daemon-service").projectDir = file("core/services/daemon-service")