Skip to content

Commit 2d03de2

Browse files
committed
fix off-by-one
1 parent b7ae0f3 commit 2d03de2

File tree

1 file changed

+49
-67
lines changed
  • FreeNotifications/src/main/java/de/binarynoise/freeNotifications

1 file changed

+49
-67
lines changed

FreeNotifications/src/main/java/de/binarynoise/freeNotifications/Hook.kt

Lines changed: 49 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -16,68 +16,6 @@ import de.robv.android.xposed.XC_MethodHook as MethodHook
1616
class Hook : IXposedHookLoadPackage {
1717

1818
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
19-
20-
fun hookVariable(
21-
clazz: Class<*>,
22-
variableName: String,
23-
setMethodName: String,
24-
getMethodName: String,
25-
value: Boolean,
26-
) {
27-
tryAndLog("${clazz.simpleName} after constructor $variableName") {
28-
val mVariable = clazz.findDeclaredField(variableName)
29-
XposedBridge.hookAllConstructors(clazz, object : MethodHook() {
30-
override fun afterHookedMethod(param: MethodHookParam) {
31-
mVariable.set(param.thisObject, value)
32-
}
33-
})
34-
}
35-
tryAndLog("${clazz.simpleName} $getMethodName") {
36-
XposedHelpers.findAndHookMethod(clazz, getMethodName, returnConstant(value))
37-
}
38-
tryAndLog("${clazz.simpleName} $setMethodName") {
39-
XposedHelpers.findAndHookMethod(clazz, setMethodName, Boolean::class.java, DO_NOTHING)
40-
}
41-
}
42-
43-
fun String.isCharUpperCase(index: Int): Boolean {
44-
return this[index] == this[index].uppercaseChar()
45-
}
46-
47-
/**
48-
* Remove prefix only if it is used in a CamelCase sentence,
49-
* only if the letter following the prefix is uppercase.
50-
*/
51-
fun String.removeCamelCasePrefix(prefix: String): String {
52-
if (!this.isCharUpperCase(prefix.length + 1)) return this.removePrefix(prefix)
53-
return this
54-
}
55-
56-
fun sanitizeVariableName(name: String): String {
57-
return name.removeCamelCasePrefix("m")
58-
.removeCamelCasePrefix("set")
59-
.removeCamelCasePrefix("is")
60-
.removeCamelCasePrefix("get")
61-
.replaceFirstChar { it.uppercaseChar() }
62-
}
63-
64-
fun hookVariable(clazz: Class<*>, variableName: String, functionName: String, value: Boolean) {
65-
val sanitizedVariableName = sanitizeVariableName(variableName)
66-
val sanitizedFunctionName = sanitizeVariableName(functionName)
67-
return hookVariable(
68-
clazz,
69-
"m$sanitizedVariableName",
70-
"set$sanitizedFunctionName",
71-
"is$sanitizedFunctionName",
72-
value,
73-
)
74-
}
75-
76-
fun hookVariable(clazz: Class<*>, name: String, value: Boolean) {
77-
return hookVariable(clazz, name, name, value)
78-
}
79-
80-
// AOSP
8119
hookVariable(
8220
NotificationChannel::class.java,
8321
"mBlockableSystem",
@@ -86,7 +24,6 @@ class Hook : IXposedHookLoadPackage {
8624
)
8725

8826
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
89-
// AOSP
9027
hookVariable(
9128
NotificationChannel::class.java,
9229
"mImportanceLockedDefaultApp",
@@ -96,7 +33,6 @@ class Hook : IXposedHookLoadPackage {
9633
}
9734

9835
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) {
99-
// AOSP
10036
hookVariable(
10137
NotificationChannel::class.java,
10238
"mImportanceLockedByOEM",
@@ -105,22 +41,68 @@ class Hook : IXposedHookLoadPackage {
10541
}
10642

10743
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
108-
// AOSP
10944
hookVariable(
11045
NotificationChannelGroup::class.java,
11146
"mBlocked",
11247
false,
11348
)
11449
}
11550
}
51+
52+
fun String.isCharUpperCase(index: Int): Boolean {
53+
return this[index].isUpperCase()
54+
}
55+
56+
/**
57+
* Remove prefix only if it is used in a CamelCase sentence,
58+
* only if the letter following the prefix is uppercase.
59+
*/
60+
fun String.removeCamelCasePrefix(prefix: String): String {
61+
if (this.isCharUpperCase(prefix.length)) return this.removePrefix(prefix)
62+
return this
63+
}
64+
65+
fun sanitizeVariableName(name: String): String {
66+
return name.removeCamelCasePrefix("m")
67+
.removeCamelCasePrefix("set")
68+
.removeCamelCasePrefix("is")
69+
.removeCamelCasePrefix("get")
70+
.replaceFirstChar { it.uppercaseChar() }
71+
}
72+
73+
fun hookVariable(clazz: Class<*>, variableName: String, setMethodName: String, getMethodName: String, value: Boolean) {
74+
tryAndLog("${clazz.simpleName} after constructor $variableName") {
75+
val mVariable = clazz.findDeclaredField(variableName)
76+
XposedBridge.hookAllConstructors(clazz, object : MethodHook() {
77+
override fun afterHookedMethod(param: MethodHookParam) {
78+
mVariable.set(param.thisObject, value)
79+
}
80+
})
81+
}
82+
tryAndLog("${clazz.simpleName} $getMethodName") {
83+
XposedHelpers.findAndHookMethod(clazz, getMethodName, returnConstant(value))
84+
}
85+
tryAndLog("${clazz.simpleName} $setMethodName") {
86+
XposedHelpers.findAndHookMethod(clazz, setMethodName, Boolean::class.java, DO_NOTHING)
87+
}
88+
}
89+
90+
fun hookVariable(clazz: Class<*>, variableName: String, functionName: String, value: Boolean) {
91+
val sanitizedVariableName = sanitizeVariableName(variableName)
92+
val sanitizedFunctionName = sanitizeVariableName(functionName)
93+
return hookVariable(clazz, "m$sanitizedVariableName", "set$sanitizedFunctionName", "is$sanitizedFunctionName", value)
94+
}
95+
96+
fun hookVariable(clazz: Class<*>, name: String, value: Boolean) {
97+
return hookVariable(clazz, name, name, value)
98+
}
11699
}
117100

118101
inline fun tryAndLog(message: String, block: () -> Unit) {
119-
return try {
102+
try {
120103
block()
121104
log("hook $message successful!")
122105
} catch (t: Throwable) {
123106
log("hook $message failed!", t)
124-
XposedBridge.log(t)
125107
}
126108
}

0 commit comments

Comments
 (0)