Introduce DynamicClassLoader
This commit is contained in:
parent
41134466ed
commit
010e4de4e1
@ -9,10 +9,10 @@ import com.topjohnwu.magisk.model.entity.internal.Configuration.APK.Restore
|
||||
import com.topjohnwu.magisk.model.entity.internal.Configuration.APK.Upgrade
|
||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
||||
import com.topjohnwu.magisk.ui.SplashActivity
|
||||
import com.topjohnwu.magisk.utils.DynamicClassLoader
|
||||
import com.topjohnwu.magisk.utils.PatchAPK
|
||||
import com.topjohnwu.magisk.utils.RootUtils
|
||||
import com.topjohnwu.superuser.Shell
|
||||
import dalvik.system.DexClassLoader
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
|
||||
@ -27,7 +27,7 @@ private fun RemoteFileService.patchPackage(apk: File, id: Int): File {
|
||||
val patched = File(apk.parent, "patched.apk")
|
||||
try {
|
||||
// Try using the new APK to patch itself
|
||||
val loader = DexClassLoader(apk.path, apk.parent, null, ClassLoader.getSystemClassLoader())
|
||||
val loader = DynamicClassLoader(apk)
|
||||
loader.loadClass("a.a")
|
||||
.getMethod("patchAPK", String::class.java, String::class.java, String::class.java)
|
||||
.invoke(null, apk.path, patched.path, packageName)
|
||||
|
@ -18,10 +18,10 @@ import com.topjohnwu.magisk.model.events.*
|
||||
import com.topjohnwu.magisk.ui.base.MagiskActivity
|
||||
import com.topjohnwu.magisk.ui.base.MagiskFragment
|
||||
import com.topjohnwu.magisk.utils.ISafetyNetHelper
|
||||
import com.topjohnwu.magisk.utils.DynamicClassLoader
|
||||
import com.topjohnwu.magisk.view.MarkDownWindow
|
||||
import com.topjohnwu.magisk.view.dialogs.*
|
||||
import com.topjohnwu.superuser.Shell
|
||||
import dalvik.system.DexClassLoader
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
import java.io.File
|
||||
|
||||
@ -97,8 +97,7 @@ class HomeFragment : MagiskFragment<HomeViewModel, FragmentMagiskBinding>(),
|
||||
|
||||
private fun updateSafetyNet(dieOnError: Boolean) {
|
||||
try {
|
||||
val loader = DexClassLoader(EXT_APK.path, EXT_APK.parent, null,
|
||||
ISafetyNetHelper::class.java.classLoader)
|
||||
val loader = DynamicClassLoader(EXT_APK)
|
||||
val clazz = loader.loadClass("com.topjohnwu.snet.Snet")
|
||||
val helper = clazz.getMethod("newHelper",
|
||||
Class::class.java, String::class.java, Activity::class.java, Any::class.java)
|
||||
|
@ -0,0 +1,61 @@
|
||||
package com.topjohnwu.magisk.utils
|
||||
|
||||
import dalvik.system.DexClassLoader
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.net.URL
|
||||
import java.util.*
|
||||
|
||||
@Suppress("FunctionName")
|
||||
inline fun <reified T> T.DynamicClassLoader(apk: File) = DynamicClassLoader(apk, T::class.java.classLoader)
|
||||
|
||||
class DynamicClassLoader(apk: File, parent: ClassLoader?)
|
||||
: DexClassLoader(apk.path, apk.parent, null, parent) {
|
||||
|
||||
private val base by lazy { Any::class.java.classLoader!! }
|
||||
|
||||
@Throws(ClassNotFoundException::class)
|
||||
override fun loadClass(name: String, resolve: Boolean) : Class<*>
|
||||
= findLoadedClass(name) ?: runCatching {
|
||||
base.loadClass(name)
|
||||
}.getOrElse {
|
||||
runCatching {
|
||||
findClass(name)
|
||||
}.getOrElse { err ->
|
||||
runCatching {
|
||||
parent.loadClass(name)
|
||||
}.getOrElse { throw err }
|
||||
}
|
||||
}
|
||||
|
||||
override fun getResource(name: String) = base.getResource(name)
|
||||
?: findResource(name)
|
||||
?: parent?.getResource(name)
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun getResources(name: String): Enumeration<URL> {
|
||||
val resources = mutableListOf(
|
||||
base.getResources(name),
|
||||
findResources(name), parent.getResources(name))
|
||||
return object : Enumeration<URL> {
|
||||
override fun hasMoreElements(): Boolean {
|
||||
while (true) {
|
||||
if (resources.isEmpty())
|
||||
return false
|
||||
if (!resources[0].hasMoreElements()) {
|
||||
resources.removeAt(0)
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun nextElement(): URL {
|
||||
if (!hasMoreElements())
|
||||
throw NoSuchElementException()
|
||||
return resources[0].nextElement()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user