add: applyProxies method

Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
This commit is contained in:
oSumAtrIX 2022-04-19 19:47:35 +02:00
parent 6cb1fdf617
commit f58a498849
No known key found for this signature in database
GPG Key ID: A9B3094ACDB604B4
4 changed files with 29 additions and 13 deletions

View File

@ -70,16 +70,8 @@ class Patcher(
fun save(): Map<String, MemoryDataStore> {
val newDexFile = object : DexFile {
override fun getClasses(): Set<ClassDef> {
val classes = patcherData.classes
val internalClasses = classes.internalClasses
for (proxy in classes.proxies) {
if (!proxy.proxyUsed) continue
val index = internalClasses.indexOfFirst { it.type == proxy.immutableClass.type }
internalClasses[index] = proxy.mutatedClass
}
return ListBackedSet(internalClasses)
patcherData.classes.applyProxies()
return ListBackedSet(patcherData.classes.internalClasses)
}
override fun getOpcodes(): Opcodes {

View File

@ -72,10 +72,10 @@ internal inline fun <T> Iterable<T>.findIndexed(predicate: (T) -> Boolean): Pair
return null
}
fun PatcherData.proxy(classProxy: ClassDef): ClassProxy {
var proxy = this.classes.proxies.find { it.immutableClass.type == classProxy.type }
fun PatcherData.proxy(classDef: ClassDef): ClassProxy {
var proxy = this.classes.proxies.find { it.immutableClass.type == classDef.type }
if (proxy == null) {
proxy = ClassProxy(classProxy)
proxy = ClassProxy(classDef)
this.classes.proxies.add(proxy)
}
return proxy

View File

@ -16,6 +16,15 @@ class ClassProxy(
internal var proxyUsed = false
internal lateinit var mutatedClass: MutableClass
init {
// in the instance, that a [MutableClass] is being proxied,
// do not create an additional clone and reuse the [MutableClass] instance
if (immutableClass is MutableClass) {
mutatedClass = immutableClass
proxyUsed = true
}
}
/**
* Allocates and returns a mutable clone of the original class.
* A patch should always use the original immutable class reference

View File

@ -14,6 +14,21 @@ class ProxyBackedClassList(internal val internalClasses: MutableList<ClassDef>)
proxies.add(classProxy)
}
/**
* Apply all resolved classes into [internalClasses] and clear the [proxies] list.
*/
fun applyProxies() {
proxies.forEachIndexed { i, proxy ->
if (!proxy.proxyUsed) return@forEachIndexed
val index = internalClasses.indexOfFirst { it.type == proxy.immutableClass.type }
internalClasses[index] = proxy.mutatedClass
proxies.removeAt(i) // FIXME: check if this could cause issues when multiple patches use the same proxy
}
}
override val size get() = internalClasses.size
override fun contains(element: ClassDef) = internalClasses.contains(element)
override fun containsAll(elements: Collection<ClassDef>) = internalClasses.containsAll(elements)