mirror of
https://github.com/LSPosed/LSPlant.git
synced 2025-05-04 20:42:02 +08:00
Support SetRuntimeDebugState (#24)
This commit is contained in:
parent
2bd37aaba9
commit
7c5457a699
@ -2,5 +2,5 @@ val androidTargetSdkVersion by extra(33)
|
||||
val androidMinSdkVersion by extra(21)
|
||||
val androidBuildToolsVersion by extra("33.0.0")
|
||||
val androidCompileSdkVersion by extra(33)
|
||||
val androidNdkVersion by extra("24.0.8215888")
|
||||
val androidNdkVersion by extra("25.1.8937393")
|
||||
val androidCmakeVersion by extra("3.22.1+")
|
||||
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
@ -114,7 +114,7 @@ publishing {
|
||||
register<MavenPublication>("lsplant") {
|
||||
group = "org.lsposed.lsplant"
|
||||
artifactId = "lsplant"
|
||||
version = "4.1"
|
||||
version = "4.2"
|
||||
afterEvaluate {
|
||||
from(components.getByName("release"))
|
||||
artifact(symbolsTask)
|
||||
|
@ -24,19 +24,46 @@
|
||||
namespace lsplant::art {
|
||||
|
||||
class Runtime {
|
||||
public:
|
||||
enum class RuntimeDebugState {
|
||||
// This doesn't support any debug features / method tracing. This is the expected state
|
||||
// usually.
|
||||
kNonJavaDebuggable,
|
||||
// This supports method tracing and a restricted set of debug features (for ex: redefinition
|
||||
// isn't supported). We transition to this state when method tracing has started or when the
|
||||
// debugger was attached and transition back to NonDebuggable once the tracing has stopped /
|
||||
// the debugger agent has detached..
|
||||
kJavaDebuggable,
|
||||
// The runtime was started as a debuggable runtime. This allows us to support the extended
|
||||
// set
|
||||
// of debug features (for ex: redefinition). We never transition out of this state.
|
||||
kJavaDebuggableAtInit
|
||||
};
|
||||
|
||||
private:
|
||||
inline static Runtime *instance_;
|
||||
|
||||
CREATE_MEM_FUNC_SYMBOL_ENTRY(void, SetJavaDebuggable, void *thiz, bool value) {
|
||||
if (SetJavaDebuggableSym) [[likely]] {
|
||||
SetJavaDebuggableSym(thiz, value);
|
||||
}
|
||||
SetJavaDebuggableSym(thiz, value);
|
||||
}
|
||||
|
||||
CREATE_MEM_FUNC_SYMBOL_ENTRY(void, SetRuntimeDebugState, void *thiz, RuntimeDebugState value) {
|
||||
SetRuntimeDebugStateSym(thiz, value);
|
||||
}
|
||||
|
||||
inline static size_t debug_state_offset = 0U;
|
||||
|
||||
public:
|
||||
inline static Runtime *Current() { return instance_; }
|
||||
|
||||
void SetJavaDebuggable(bool value) { SetJavaDebuggable(this, value); }
|
||||
void SetJavaDebuggable(RuntimeDebugState value) {
|
||||
if (SetJavaDebuggableSym) {
|
||||
SetJavaDebuggable(this, value != RuntimeDebugState::kNonJavaDebuggable);
|
||||
} else if (debug_state_offset > 0) {
|
||||
*reinterpret_cast<RuntimeDebugState *>(reinterpret_cast<uintptr_t>(instance_) +
|
||||
debug_state_offset) = value;
|
||||
}
|
||||
}
|
||||
|
||||
static bool Init(const HookHandler &handler) {
|
||||
int sdk_int = GetAndroidApiLevel();
|
||||
@ -48,7 +75,32 @@ public:
|
||||
LOGD("runtime instance = %p", instance_);
|
||||
if (sdk_int >= __ANDROID_API_O__) {
|
||||
if (!RETRIEVE_MEM_FUNC_SYMBOL(SetJavaDebuggable,
|
||||
"_ZN3art7Runtime17SetJavaDebuggableEb")) {
|
||||
"_ZN3art7Runtime17SetJavaDebuggableEb") &&
|
||||
!RETRIEVE_MEM_FUNC_SYMBOL(
|
||||
SetRuntimeDebugState,
|
||||
"_ZN3art7Runtime20SetRuntimeDebugStateENS0_17RuntimeDebugStateE")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (SetRuntimeDebugStateSym) {
|
||||
static constexpr size_t kLargeEnoughSizeForRuntime = 4096;
|
||||
std::array<uint8_t, kLargeEnoughSizeForRuntime> code;
|
||||
static_assert(static_cast<int>(RuntimeDebugState::kJavaDebuggable) != 0);
|
||||
static_assert(static_cast<int>(RuntimeDebugState::kJavaDebuggableAtInit) != 0);
|
||||
code.fill(uint8_t{0});
|
||||
auto *const fake_runtime = reinterpret_cast<Runtime *>(code.data());
|
||||
SetRuntimeDebugState(fake_runtime, RuntimeDebugState::kJavaDebuggable);
|
||||
for (size_t i = 0; i < kLargeEnoughSizeForRuntime; ++i) {
|
||||
if (*reinterpret_cast<RuntimeDebugState *>(
|
||||
reinterpret_cast<uintptr_t>(fake_runtime) + i) ==
|
||||
RuntimeDebugState::kJavaDebuggable) {
|
||||
LOGD("found debug_state at offset %zu", i);
|
||||
debug_state_offset = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (debug_state_offset == 0) {
|
||||
LOGE("failed to find debug_state");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -274,7 +274,7 @@ bool InitNative(JNIEnv *env, const HookHandler &handler) {
|
||||
if (IsJavaDebuggable(env)) {
|
||||
// Make the runtime non-debuggable as a workaround
|
||||
// when ShouldUseInterpreterEntrypoint inlined
|
||||
Runtime::Current()->SetJavaDebuggable(false);
|
||||
Runtime::Current()->SetJavaDebuggable(Runtime::RuntimeDebugState::kNonJavaDebuggable);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -735,8 +735,13 @@ using ::lsplant::IsHooked;
|
||||
|
||||
[[maybe_unused]] bool MakeDexFileTrusted(JNIEnv *env, jobject cookie) {
|
||||
struct Guard {
|
||||
Guard() { Runtime::Current()->SetJavaDebuggable(true); }
|
||||
~Guard() { Runtime::Current()->SetJavaDebuggable(false); }
|
||||
Guard() {
|
||||
Runtime::Current()->SetJavaDebuggable(
|
||||
Runtime::RuntimeDebugState::kJavaDebuggableAtInit);
|
||||
}
|
||||
~Guard() {
|
||||
Runtime::Current()->SetJavaDebuggable(Runtime::RuntimeDebugState::kNonJavaDebuggable);
|
||||
}
|
||||
} guard;
|
||||
if (!cookie) return false;
|
||||
return DexFile::SetTrusted(env, cookie);
|
||||
|
@ -5,8 +5,8 @@ pluginManagement {
|
||||
mavenCentral()
|
||||
}
|
||||
plugins {
|
||||
id("com.android.application") version "7.2.1"
|
||||
id("com.android.library") version "7.2.1"
|
||||
id("com.android.application") version "7.2.2"
|
||||
id("com.android.library") version "7.2.2"
|
||||
}
|
||||
}
|
||||
dependencyResolutionManagement {
|
||||
|
Loading…
x
Reference in New Issue
Block a user