fix(spoof-wifi-connection): use updated instruction indices (#2199)

Co-authored-by: Linus789 <Linus789@users.noreply.github.com>
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
This commit is contained in:
Linus 2023-05-30 21:51:43 +00:00 committed by GitHub
parent 41b4eef72c
commit 76fb700884
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -21,39 +21,44 @@ internal abstract class AbstractTransformInstructionsPatch<T> : BytecodePatch()
abstract fun transform(mutableMethod: MutableMethod, entry: T) abstract fun transform(mutableMethod: MutableMethod, entry: T)
// Returns the patch indices as a Sequence, which will execute lazily.
private fun findPatchIndices(classDef: ClassDef, method: Method): Sequence<T>? {
return method.implementation?.instructions?.asSequence()?.withIndex()?.mapNotNull { (index, instruction) ->
filterMap(classDef, method, instruction, index)
}
}
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
// Find all instructions // Find all methods to patch
buildMap { buildMap {
context.classes.forEach { classDef -> context.classes.forEach { classDef ->
classDef.methods.let { methods -> val methods = buildList {
buildMap methodList@{ classDef.methods.forEach { method ->
methods.forEach methods@{ method -> // Since the Sequence executes lazily,
with(method.implementation?.instructions ?: return@methods) { // using any() results in only calling
ArrayDeque<T>().also { patchIndices -> // filterMap until the first index has been found.
this.forEachIndexed { index, instruction -> val patchIndices = findPatchIndices(classDef, method)
val result = filterMap(classDef, method, instruction, index)
if (result != null) { if (patchIndices?.any() == true) {
patchIndices.add(result) add(method)
}
}
}.also { if (it.isEmpty()) return@methods }.let { patches ->
put(method, patches)
}
}
} }
} }
}.also { if (it.isEmpty()) return@forEach }.let { methodPatches -> }
put(classDef, methodPatches)
if (methods.isNotEmpty()) {
put(classDef, methods)
} }
} }
}.forEach { (classDef, methods) -> }.forEach { (classDef, methods) ->
// And finally transform the instructions... // And finally transform the methods...
with(context.proxy(classDef).mutableClass) { val mutableClass = context.proxy(classDef).mutableClass
methods.forEach { (method, patches) ->
val mutableMethod = findMutableMethodOf(method) methods.map(mutableClass::findMutableMethodOf).forEach methods@{ mutableMethod ->
while (!patches.isEmpty()) { val patchIndices = findPatchIndices(mutableClass, mutableMethod)?.toCollection(ArrayDeque())
transform(mutableMethod, patches.removeLast()) ?: return@methods
}
while (!patchIndices.isEmpty()) {
transform(mutableMethod, patchIndices.removeLast())
} }
} }
} }