Skip to content

Commit d8ee73f

Browse files
committed
Switch to finding DCL class and add settings name to BuildConfig
1 parent 00ef1cd commit d8ee73f

7 files changed

Lines changed: 57 additions & 47 deletions

File tree

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ val versionNameProvider by extra(providers.of(GitLatestTagValueSource::class.jav
6464
val injectedPackageName by extra("com.android.shell")
6565
val injectedPackageUid by extra(2000)
6666
val defaultManagerPackageName by extra("org.lsposed.manager")
67+
val grapheneSettingsPackageName by extra("com.android.settings")
6768

6869
val androidTargetSdkVersion by extra(36)
6970
val androidMinSdkVersion by extra(27)

daemon/build.gradle.kts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import java.io.PrintStream
44
import java.util.UUID
55

66
val defaultManagerPackageName: String by rootProject.extra
7+
val grapheneSettingsPackageName: String by rootProject.extra
78
val injectedPackageName: String by rootProject.extra
89
val injectedPackageUid: Int by rootProject.extra
910
val versionCodeProvider: Provider<String> by rootProject.extra
@@ -22,6 +23,11 @@ android {
2223
"DEFAULT_MANAGER_PACKAGE_NAME",
2324
""""$defaultManagerPackageName"""",
2425
)
26+
buildConfigField(
27+
"String",
28+
"GRAPHENE_SETTINGS_PACKAGE_NAME",
29+
""""$grapheneSettingsPackageName"""",
30+
)
2531
buildConfigField("String", "FRAMEWORK_NAME", """"${rootProject.name}"""")
2632
buildConfigField("String", "MANAGER_INJECTED_PKG_NAME", """"$injectedPackageName"""")
2733
buildConfigField("int", "MANAGER_INJECTED_UID", """$injectedPackageUid""")

daemon/src/main/kotlin/org/matrix/vector/daemon/VectorService.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ object VectorService : IDaemonService.Stub() {
6767
if (ApplicationService.hasRegister(uid, pid)) return null
6868

6969
val scope = ProcessScope(processName, uid)
70-
if (processName != "com.android.settings" && !ManagerService.tryRegisterManagerProcess(pid, uid, processName) &&
70+
if (processName != BuildConfig.GRAPHENE_SETTINGS_PACKAGE_NAME && !ManagerService.tryRegisterManagerProcess(pid, uid, processName) &&
7171
ConfigCache.shouldSkipProcess(scope)) {
7272
Log.d(TAG, "Skipped $processName/$uid")
7373
return null

hiddenapi/stubs/src/main/java/android/ext/settings/app/AswRestrictMemoryDynCodeLoading.java

Lines changed: 0 additions & 4 deletions
This file was deleted.

zygisk/build.gradle.kts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ val versionNameProvider: Provider<String> by rootProject.extra
1515
val injectedPackageName: String by rootProject.extra
1616
val injectedPackageUid: Int by rootProject.extra
1717
val defaultManagerPackageName: String by rootProject.extra
18+
val grapheneSettingsPackageName: String by rootProject.extra
1819

1920
android {
2021
namespace = "org.matrix.vector"
@@ -24,12 +25,14 @@ android {
2425
buildConfigField("int", "HostPackageUid", "${injectedPackageUid}")
2526
buildConfigField("String", "InjectedPackageName", """"${injectedPackageName}"""")
2627
buildConfigField("String", "ManagerPackageName", """"${defaultManagerPackageName}"""")
28+
buildConfigField("String", "GrapheneSettingsPackageName", """"${grapheneSettingsPackageName}"""")
2729

2830
val flags =
2931
listOf(
3032
"-DINJECTED_PACKAGE_NAME='\"${injectedPackageName}\"'",
3133
"-DINJECTED_PACKAGE_UID=${injectedPackageUid}",
3234
"-DMANAGER_PACKAGE_NAME='\"${defaultManagerPackageName}\"'",
35+
"-DGRAPHENE_SETTINGS_PACKAGE_NAME='\"${grapheneSettingsPackageName}\"'",
3336
)
3437

3538
externalNativeBuild {

zygisk/src/main/kotlin/org/matrix/vector/ParasiticManagerHooker.kt

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,50 @@ object ParasiticManagerHooker {
441441
}
442442
}
443443

444+
@JvmStatic
445+
fun patchGrapheneDCLRestriction() {
446+
try {
447+
// Force GrapheneOS to allow changing the restriction on Dynamic Code Loading, and
448+
// force-disable it for the settings app and the shell
449+
XposedBridge.hookAllMethods(
450+
XposedHelpers.findClass(
451+
"android.ext.settings.app.AswRestrictMemoryDynCodeLoading",
452+
this.javaClass.classLoader
453+
),
454+
"getImmutableValue",
455+
object : XC_MethodReplacement() {
456+
override fun replaceHookedMethod(param: MethodHookParam<*>?): Any? {
457+
val appInfo = param?.args[2] as? ApplicationInfo?
458+
459+
// Settings has to always be allowed so that it can be patched as well.
460+
// The parasitic host package is also allowed so that the manager functions correctly.
461+
if (appInfo != null && listOf(
462+
BuildConfig.GrapheneSettingsPackageName,
463+
BuildConfig.InjectedPackageName
464+
).contains(appInfo.packageName)
465+
) {
466+
return false
467+
}
468+
469+
// All system apps are configurable (null)
470+
if (appInfo != null && (appInfo.flags and ApplicationInfo.FLAG_SYSTEM) != 0) {
471+
return null
472+
}
473+
474+
// Defer to original implementation for other apps
475+
return XposedBridge.invokeOriginalMethod(
476+
param?.method, param?.thisObject, param?.args
477+
)
478+
}
479+
}
480+
)
481+
} catch (_: XposedHelpers.ClassNotFoundError) {
482+
// Ignore, assuming we are not on GrapheneOS
483+
} catch (e: Exception) {
484+
Utils.logE("Unknown error patching Graphene DCL", e)
485+
}
486+
}
487+
444488
/** Entry point. Checks if the current process should host the parasitic manager. */
445489
@JvmStatic
446490
fun start(): Boolean {

zygisk/src/main/kotlin/org/matrix/vector/core/Main.kt

Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
package org.matrix.vector.core
22

3-
import android.content.pm.ApplicationInfo
4-
import android.ext.settings.app.AswRestrictMemoryDynCodeLoading
53
import android.os.IBinder
64
import android.os.Process
7-
import de.robv.android.xposed.XC_MethodReplacement
8-
import de.robv.android.xposed.XposedBridge
9-
import de.robv.android.xposed.XposedHelpers
105
import org.lsposed.lspd.service.ILSPApplicationService
116
import org.lsposed.lspd.util.Utils
127
import org.matrix.vector.BuildConfig
@@ -40,43 +35,8 @@ object Main {
4035
ParasiticManagerSystemHooker.start()
4136
}
4237

43-
if (niceName == "system" || niceName == "com.android.settings") {
44-
try {
45-
// Force GrapheneOS to allow changing the restriction on Dynamic Code Loading, and
46-
// force-disable it for the settings app and the shell
47-
XposedBridge.hookAllMethods(
48-
AswRestrictMemoryDynCodeLoading::class.java,
49-
"getImmutableValue",
50-
object : XC_MethodReplacement() {
51-
override fun replaceHookedMethod(param: MethodHookParam<*>?): Any? {
52-
val appInfo = param?.args[2] as? ApplicationInfo?
53-
54-
// Settings has to always be allowed so that it can be patched as well.
55-
if (appInfo != null && listOf(
56-
"com.android.settings",
57-
"com.android.shell"
58-
).contains(appInfo.packageName)
59-
) {
60-
return false
61-
}
62-
63-
// All system apps are configurable (null)
64-
if (appInfo != null && (appInfo.flags and ApplicationInfo.FLAG_SYSTEM) != 0) {
65-
return null
66-
}
67-
68-
// Defer to original implementation for other apps
69-
return XposedBridge.invokeOriginalMethod(
70-
param?.method, param?.thisObject, param?.args
71-
)
72-
}
73-
}
74-
)
75-
} catch (e: XposedHelpers.ClassNotFoundError) {
76-
// Ignore, assuming we are not on GrapheneOS
77-
} catch (e: Exception) {
78-
Utils.logE("Unknown error patching Graphene", e)
79-
}
38+
if (isSystem || niceName == BuildConfig.GrapheneSettingsPackageName) {
39+
ParasiticManagerHooker.patchGrapheneDCLRestriction()
8040
}
8141

8242
// Initialize Xposed bridge components

0 commit comments

Comments
 (0)