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:
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
uses: seanmiddleditch/gha-setup-ninja@master
with:

2
core

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

View File

@ -10,47 +10,49 @@
using namespace lsplant;
namespace art {
CREATE_MEM_HOOK_STUB_ENTRY(
"_ZN3art12ProfileSaver20ProcessProfilingInfoEbPt",
bool, ProcessProfilingInfo, (void * thiz, bool, uint16_t *), {
class ProfileSaver {
private:
inline static MemberHooker<"_ZN3art12ProfileSaver20ProcessProfilingInfoEbPt", ProfileSaver,
bool(bool, uint16_t *)>
ProcessProfilingInfo_ = +[](ProfileSaver *thiz, bool a, uint16_t *b) {
LOGD("skipped profile saving");
return true;
});
};
CREATE_MEM_HOOK_STUB_ENTRY(
"_ZN3art12ProfileSaver20ProcessProfilingInfoEbbPt",
bool, ProcessProfilingInfoWithBool, (void * thiz, bool, bool, uint16_t *), {
inline static MemberHooker<"_ZN3art12ProfileSaver20ProcessProfilingInfoEbbPt", ProfileSaver,
bool(bool, bool, uint16_t *)>
ProcessProfilingInfoWithBool_ = +[](ProfileSaver *thiz, bool, bool, uint16_t *) {
LOGD("skipped profile saving");
return true;
});
};
CREATE_HOOK_STUB_ENTRY(
"execve",
int, execve, (const char *pathname, const char *argv[], char *const envp[]), {
inline static Hooker<"execve",
int(const char *pathname, const char *argv[], char *const envp[])>
execve_ = +[](const char *pathname, const char *argv[], char *const envp[]) {
if (strstr(pathname, "dex2oat")) {
size_t count = 0;
while (argv[count++] != nullptr);
std::unique_ptr<const char *[]> new_args = std::make_unique<const char *[]>(
count + 1);
for (size_t i = 0; i < count - 1; ++i)
new_args[i] = argv[i];
std::unique_ptr<const char *[]> new_args =
std::make_unique<const char *[]>(count + 1);
for (size_t i = 0; i < count - 1; ++i) new_args[i] = argv[i];
new_args[count - 1] = "--inline-max-code-units=0";
new_args[count] = nullptr;
LOGD("dex2oat by disable inline!");
int ret = backup(pathname, new_args.get(), envp);
int ret = execve_(pathname, new_args.get(), envp);
return ret;
}
int ret = backup(pathname, argv, envp);
int ret = execve_(pathname, argv, envp);
return ret;
});
};
public:
static void DisableInline(const HookHandler &handler) {
HookSyms(handler, ProcessProfilingInfo, ProcessProfilingInfoWithBool);
HookSymNoHandle(handler, reinterpret_cast<void*>(&::execve), execve);
handler.hook(ProcessProfilingInfo_);
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;
namespace art {
CREATE_MEM_HOOK_STUB_ENTRY(
"_ZN3art14OatFileManager25RunBackgroundVerificationERKNSt3__16vectorIPKNS_7DexFileENS1_9allocatorIS5_EEEEP8_jobjectPKc",
void, RunBackgroundVerificationWithContext,
(void * thiz, const std::vector<const void *> &dex_files,
jobject class_loader,
const char *class_loader_context), {
class FileManager {
public:
inline static MemberHooker<
"_ZN3art14OatFileManager25RunBackgroundVerificationERKNSt3__"
"16vectorIPKNS_7DexFileENS1_9allocatorIS5_EEEEP8_jobjectPKc",
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) {
LOGD("Disabled background verification");
return;
}
backup(thiz, dex_files, class_loader, class_loader_context);
});
RunBackgroundVerificationWithContext_(thiz, dex_files, class_loader,
class_loader_context);
};
CREATE_MEM_HOOK_STUB_ENTRY(
"_ZN3art14OatFileManager25RunBackgroundVerificationERKNSt3__16vectorIPKNS_7DexFileENS1_9allocatorIS5_EEEEP8_jobject",
void, RunBackgroundVerification,
(void * thiz, const std::vector<const void *> &dex_files,
jobject class_loader), {
inline static MemberHooker<
"_ZN3art14OatFileManager25RunBackgroundVerificationERKNSt3__"
"16vectorIPKNS_7DexFileENS1_9allocatorIS5_EEEEP8_jobject",
FileManager, void(const std::vector<const void *> &, jobject)>
RunBackgroundVerification_ =
+[](FileManager *thiz, const std::vector<const void *> &dex_files,
jobject class_loader) {
if (lspd::Context::GetInstance()->GetCurrentClassLoader() == nullptr) {
LOGD("Disabled background verification");
return;
}
backup(thiz, dex_files, class_loader);
});
RunBackgroundVerification_(thiz, dex_files, class_loader);
};
public:
static void DisableBackgroundVerification(const lsplant::HookHandler &handler) {
const int api_level = lspd::GetAndroidApiLevel();
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.
//
#include "../src/native_api.h"
#include "bypass_sig.h"
#include "elf_util.h"
#include "logging.h"
@ -12,23 +13,31 @@
namespace lspd {
std::string apkPath;
std::string redirectPath;
std::string apkPath;
std::string redirectPath;
CREATE_HOOK_STUB_ENTRY(
"__openat",
int, __openat,
(int fd, const char* pathname, int flag, int mode), {
inline static lsplant::Hooker<"__openat", int(int, const char*, int flag, int)> __openat_ =
+[](int fd, const char* pathname, int flag, int mode) {
if (pathname == apkPath) {
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) {
auto sym_openat = SandHook::ElfImg("libc.so").getSymbAddress<void *>("__openat");
auto r = HookSymNoHandle(handler, sym_openat, __openat);
bool HookOpenat(const lsplant::HookHandler& handler) { return handler.hook(__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) {
LOGE("Hook __openat fail");
return;
@ -39,13 +48,11 @@ namespace lspd {
redirectPath = str2.get();
LOGD("apkPath %s", apkPath.c_str());
LOGD("redirectPath %s", redirectPath.c_str());
}
static JNINativeMethod gMethods[] = {
LSP_NATIVE_METHOD(SigBypass, enableOpenatHook, "(Ljava/lang/String;Ljava/lang/String;)V")
};
void RegisterBypass(JNIEnv* env) {
REGISTER_LSP_NATIVE_METHODS(SigBypass);
}
}
static JNINativeMethod gMethods[] = {
LSP_NATIVE_METHOD(SigBypass, enableOpenatHook, "(Ljava/lang/String;Ljava/lang/String;)V")};
void RegisterBypass(JNIEnv* env) { REGISTER_LSP_NATIVE_METHODS(SigBypass); }
} // namespace lspd

View File

@ -21,12 +21,13 @@
// 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/oat_file_manager.h"
#include "elf_util.h"
#include "jni/bypass_sig.h"
#include "native_util.h"
#include "patch_loader.h"
#include "symbol_cache.h"
#include "utils/jni_helper.hpp"
@ -34,19 +35,23 @@ using namespace lsplant;
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_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 mid_current_activity_thread = JNI_GetStaticMethodID(env, class_activity_thread, "currentActivityThread",
"()Landroid/app/ActivityThread;");
auto mid_get_classloader = JNI_GetMethodID(env, class_loaded_apk, "getClassLoader", "()Ljava/lang/ClassLoader;");
auto mid_current_activity_thread = JNI_GetStaticMethodID(
env, class_activity_thread, "currentActivityThread", "()Landroid/app/ActivityThread;");
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",
"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 info = JNI_GetObjectField(env, m_bound_application, fid_info);
auto stub_classloader = JNI_CallObjectMethod(env, info, mid_get_classloader);
@ -61,7 +66,8 @@ namespace lspd {
"(Ljava/nio/ByteBuffer;Ljava/lang/ClassLoader;)V");
auto byte_buffer_class = JNI_FindClass(env, "java/nio/ByteBuffer");
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);
} else {
LOGE("InMemoryDexClassLoader creation failed!!!");
@ -69,50 +75,47 @@ namespace lspd {
}
env->DeleteLocalRef(dex_buffer);
}
}
void PatchLoader::InitArtHooker(JNIEnv* env, const InitInfo& initInfo) {
void PatchLoader::InitArtHooker(JNIEnv* env, const InitInfo& initInfo) {
Context::InitArtHooker(env, initInfo);
handler = initInfo;
art::DisableInline(initInfo);
art::DisableBackgroundVerification(initInfo);
}
art::ProfileSaver::DisableInline(initInfo);
art::FileManager::DisableBackgroundVerification(initInfo);
}
void PatchLoader::InitHooks(JNIEnv* env) {
void PatchLoader::InitHooks(JNIEnv* env) {
Context::InitHooks(env);
RegisterBypass(env);
}
}
void PatchLoader::SetupEntryClass(JNIEnv* env) {
void PatchLoader::SetupEntryClass(JNIEnv* env) {
if (auto entry_class = FindClassFromLoader(env, GetCurrentClassLoader(),
"org.lsposed.lspatch.loader.LSPApplication")) {
entry_class_ = JNI_NewGlobalRef(env, entry_class);
}
}
}
void PatchLoader::Load(JNIEnv* env) {
void PatchLoader::Load(JNIEnv* env) {
/* InitSymbolCache(nullptr); */
lsplant::InitInfo initInfo {
.inline_hooker = [](auto t, auto r) {
lsplant::InitInfo initInfo{
.inline_hooker =
[](auto t, auto r) {
void* bk = nullptr;
return HookFunction(t, r, &bk) == RS_SUCCESS ? 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);
return HookInline(t, r, &bk) == 0 ? bk : nullptr;
},
.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 dex_field = JNI_GetStaticFieldID(env, stub, "dex", "[B");
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);
LoadDex(env, std::move(dex));
@ -122,5 +125,5 @@ namespace lspd {
SetupEntryClass(env);
FindAndCall(env, "onLoad", "()V");
}
}
} // namespace lspd

View File

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