Skip to content

Commit

Permalink
Fix hook may not work on debuggable runtime (LSPosed#1892)
Browse files Browse the repository at this point in the history
Co-authored-by: Wang Han <wanghan1995315@gmail.com>
  • Loading branch information
yujincheng08 and aviraxp authored Apr 26, 2022
1 parent 5991325 commit 177c2cd
Show file tree
Hide file tree
Showing 17 changed files with 84 additions and 315 deletions.
7 changes: 7 additions & 0 deletions core/src/main/java/org/lsposed/lspd/core/Startup.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,28 @@
import org.lsposed.lspd.hooker.CrashDumpHooker;
import org.lsposed.lspd.hooker.HandleSystemServerProcessHooker;
import org.lsposed.lspd.hooker.LoadedApkCtorHooker;
import org.lsposed.lspd.hooker.OpenDexFileHooker;
import org.lsposed.lspd.service.ILSPApplicationService;
import org.lsposed.lspd.util.Utils;

import dalvik.system.DexFile;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.XposedInit;

public class Startup {
@SuppressWarnings("deprecation")
private static void startBootstrapHook(boolean isSystem) {
Utils.logD("startBootstrapHook starts: isSystem = " + isSystem);
XposedHelpers.findAndHookMethod(Thread.class, "dispatchUncaughtException",
Throwable.class, new CrashDumpHooker());
if (isSystem) {
XposedBridge.hookAllMethods(ZygoteInit.class,
"handleSystemServerProcess", new HandleSystemServerProcessHooker());
} else {
var hooker = new OpenDexFileHooker();
XposedBridge.hookAllMethods(DexFile.class, "openDexFile", hooker);
XposedBridge.hookAllMethods(DexFile.class, "openInMemoryDexFile", hooker);
}
XposedHelpers.findAndHookConstructor(LoadedApk.class,
ActivityThread.class, ApplicationInfo.class, CompatibilityInfo.class,
Expand Down
31 changes: 31 additions & 0 deletions core/src/main/java/org/lsposed/lspd/hooker/OpenDexFileHooker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.lsposed.lspd.hooker;

import android.os.Build;

import org.lsposed.lspd.nativebridge.HookBridge;

import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;

public class OpenDexFileHooker extends XC_MethodHook {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
ClassLoader classLoader = null;
for (var arg : param.args) {
if (arg instanceof ClassLoader) {
classLoader = (ClassLoader) arg;
}
}
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.P && classLoader == null) {
classLoader = XposedHelpers.class.getClassLoader();
}
while (classLoader != null) {
if (classLoader == XposedHelpers.class.getClassLoader()) {
HookBridge.setTrusted(param.getResult());
return;
} else {
classLoader = classLoader.getParent();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,7 @@ public class HookBridge {

@FastNative
public static native boolean instanceOf(Object obj, Class<?> clazz);

@FastNative
public static native boolean setTrusted(Object cookie);
}
1 change: 1 addition & 0 deletions core/src/main/jni/include/ConfigBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class ConfigBridge {
virtual obfuscation_map_t& obfuscation_map() = 0;
virtual void obfuscation_map(obfuscation_map_t) = 0;

virtual ~ConfigBridge() = default;
protected:
inline static std::unique_ptr<ConfigBridge> instance_ = nullptr;
};
Expand Down
148 changes: 0 additions & 148 deletions core/src/main/jni/include/art/runtime/hidden_api.h

This file was deleted.

56 changes: 0 additions & 56 deletions core/src/main/jni/include/art/runtime/runtime.h

This file was deleted.

28 changes: 0 additions & 28 deletions core/src/main/jni/include/native_hook.h

This file was deleted.

2 changes: 1 addition & 1 deletion core/src/main/jni/include/native_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ inline int UnhookFunction(void *original) {
return DobbyDestroy(original);
}

static std::string GetNativeBridgeSignature() {
inline std::string GetNativeBridgeSignature() {
const auto &obfs_map = ConfigBridge::GetInstance()->obfuscation_map();
static auto signature = obfs_map.at("org.lsposed.lspd.nativebridge.");
return signature;
Expand Down
10 changes: 0 additions & 10 deletions core/src/main/jni/include/symbol_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,12 @@ namespace lspd {
struct SymbolCache {
std::atomic_flag initialized{};
void *do_dlopen;
void *openInMemoryDexFilesNative;
void *createCookieWithArray;
void *createCookieWithDirectBuffer;
void *openDexFileNative;
void *setTrusted;
void *setTableOverride;

SymbolCache() = default;

SymbolCache(const SymbolCache &other) :
do_dlopen(other.do_dlopen),
openInMemoryDexFilesNative(other.openInMemoryDexFilesNative),
createCookieWithArray(other.createCookieWithArray),
createCookieWithDirectBuffer(other.createCookieWithDirectBuffer),
openDexFileNative(other.openDexFileNative),
setTrusted(other.setTrusted),
setTableOverride(other.setTableOverride) {}

SymbolCache &operator=(const SymbolCache &other) {
Expand Down
34 changes: 31 additions & 3 deletions core/src/main/jni/src/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

#include "config.h"
#include "context.h"
#include "native_hook.h"
#include "native_util.h"
#include "jni/hook_bridge.h"
#include "jni/native_api.h"
Expand All @@ -48,11 +47,40 @@ namespace lspd {
if (*this) munmap(addr_, size_);
}

void Context::InitHooks(JNIEnv *env, const lsplant::InitInfo& initInfo) {
void Context::InitHooks(JNIEnv *env, const lsplant::InitInfo &initInfo) {
if (!lsplant::Init(env, initInfo)) {
LOGE("Failed to init lsplant");
return;
}

auto path_list = JNI_GetObjectFieldOf(env, inject_class_loader_, "pathList",
"Ldalvik/system/DexPathList;");
if (!path_list) {
LOGE("Failed to get path list");
return;
}
const auto elements = JNI_Cast<jobjectArray>(
JNI_GetObjectFieldOf(env, path_list, "dexElements",
"[Ldalvik/system/DexPathList$Element;"));
if (!elements) {
LOGE("Failed to get elements");
return;
}
for (const auto &element: elements) {
if (!element)
continue;
auto java_dex_file = JNI_GetObjectFieldOf(env, element, "dexFile",
"Ldalvik/system/DexFile;");
if (!java_dex_file) {
LOGE("Failed to get java dex file");
return;
}
auto cookie = JNI_GetObjectFieldOf(env, java_dex_file, "mCookie", "Ljava/lang/Object;");
if (!cookie) {
LOGE("Failed to get cookie");
return;
}
lsplant::MakeDexFileTrusted(env, cookie);
}
RegisterResourcesHook(env);
RegisterHookBridge(env);
RegisterNativeAPI(env);
Expand Down
Loading

0 comments on commit 177c2cd

Please sign in to comment.