Skip to content

Commit 6c6f5ae

Browse files
committed
Add dexlib2 dependency and block certain DEX imports
Added the dexlib2 library to project dependencies and implemented logic in Config.kt to block loading of DEX files containing references to specific packages (e.g., KsuNative). This enhances security by preventing the import of potentially unsafe classes.
1 parent f092a63 commit 6c6f5ae

File tree

3 files changed

+42
-0
lines changed

3 files changed

+42
-0
lines changed

gradle/libs.versions.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
[versions]
2+
dexlib2 = "2.5.2"
23
mmrl = "f45678111a"
34
adaptiveAndroid = "1.1.0-rc01"
45
androidGradlePlugin = "8.9.1"
@@ -63,6 +64,7 @@ soraEditor = "0.23.6"
6364
[libraries]
6465
composedestinations-ksp = { module = "io.github.raamcosta.compose-destinations:ksp", version.ref = "composedestinations" }
6566
composedestinations-core = { module = "io.github.raamcosta.compose-destinations:core", version.ref = "composedestinations" }
67+
dexlib2 = { module = "org.smali:dexlib2", version.ref = "dexlib2" }
6668
mmrl-platform = { group = "com.github.MMRLApp.MMRL", name = "platform", version.ref = "mmrl" }
6769
mmrl-hiddenApi = { group = "com.github.MMRLApp.MMRL", name = "hidden-api", version.ref = "mmrl" }
6870
mmrl-ui = { group = "com.github.MMRLApp.MMRL", name = "ui", version.ref = "mmrl" }

webui/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,5 +80,6 @@ dependencies {
8080
implementation(libs.androidx.foundation)
8181
implementation(libs.androidx.material3.android)
8282
implementation(libs.androidx.swiperefreshlayout)
83+
implementation(libs.dexlib2)
8384
ksp(libs.square.moshi.kotlin)
8485
}

webui/src/main/kotlin/com/dergoogler/mmrl/webui/model/Config.kt

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import com.dergoogler.mmrl.ext.toIntOrNull
1616
import com.dergoogler.mmrl.ext.toStringOrNull
1717
import com.dergoogler.mmrl.platform.PlatformManager
1818
import com.dergoogler.mmrl.platform.file.SuFile
19+
import com.dergoogler.mmrl.platform.file.SuFileInputStream
1920
import com.dergoogler.mmrl.platform.file.config.ConfigFile
2021
import com.dergoogler.mmrl.platform.file.config.JSONArray
2122
import com.dergoogler.mmrl.platform.file.config.JSONCollection
@@ -31,12 +32,17 @@ import com.dergoogler.mmrl.webui.R
3132
import com.dergoogler.mmrl.webui.__webui__adapters__
3233
import com.dergoogler.mmrl.webui.activity.WXActivity
3334
import com.dergoogler.mmrl.webui.interfaces.WXInterface
35+
import com.dergoogler.mmrl.webui.view.WebUIView
3436
import com.squareup.moshi.Json
3537
import com.squareup.moshi.JsonClass
3638
import dalvik.system.BaseDexClassLoader
3739
import dalvik.system.DexClassLoader
3840
import dalvik.system.InMemoryDexClassLoader
3941
import kotlinx.coroutines.flow.StateFlow
42+
import org.jf.dexlib2.dexbacked.DexBackedDexFile
43+
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
44+
import java.io.InputStream
45+
import java.lang.System.console
4046
import java.nio.ByteBuffer
4147
import java.util.concurrent.ConcurrentHashMap
4248
import java.util.regex.Pattern
@@ -195,9 +201,42 @@ open class WebUIConfigBaseLoader() {
195201

196202
// Using InMemoryDexClassLoader is efficient if DEX files are not excessively large.
197203
val dexFileBytes = file.readBytes()
204+
val str = SuFileInputStream(file).use { it.buffered() }
205+
if (isBlocked(str)) {
206+
return null
207+
}
208+
198209
return InMemoryDexClassLoader(ByteBuffer.wrap(dexFileBytes), context.classLoader)
199210
}
200211

212+
@Throws(Exception::class)
213+
fun isBlocked(stream: InputStream): Boolean {
214+
val blockedPackages = listOf(
215+
"(Lcom/dergoogler/mmrl/platform/)?(.+)?/?KsuNative"
216+
)
217+
218+
val dexFile = DexBackedDexFile.fromInputStream(null, stream)
219+
220+
for (classDef in dexFile.classes) {
221+
for (method in classDef.methods) {
222+
if (method.implementation?.instructions == null) return false
223+
for (instr in method.implementation!!.instructions) {
224+
if (instr is ReferenceInstruction) {
225+
val ref = instr.reference.toString()
226+
for (pkg in blockedPackages) {
227+
if (Regex(pkg).containsMatchIn(ref)) {
228+
Log.wtf(TAG, "Blocked import detected: $ref")
229+
return true
230+
}
231+
}
232+
}
233+
}
234+
}
235+
}
236+
237+
return false
238+
}
239+
201240
/**
202241
* Creates a ClassLoader for a class within an installed APK.
203242
*/

0 commit comments

Comments
 (0)