From 40082ce972a4bfaf8b7d69366649766ac9b02c38 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Fri, 6 Sep 2024 19:42:21 +0900 Subject: [PATCH] fix(BytecodeUtils): due to structural limitations of ReVanced Patcher, incorrect classes may be retrieved --- .../kotlin/app/revanced/util/BytecodeUtils.kt | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/app/revanced/util/BytecodeUtils.kt b/src/main/kotlin/app/revanced/util/BytecodeUtils.kt index e2c42f0ac..2c4f5d906 100644 --- a/src/main/kotlin/app/revanced/util/BytecodeUtils.kt +++ b/src/main/kotlin/app/revanced/util/BytecodeUtils.kt @@ -604,13 +604,35 @@ fun MutableMethod.getTargetIndexWithReferenceReversed(startIndex: Int, reference return -1 } -fun MethodFingerprintResult.getWalkerMethod(context: BytecodeContext, index: Int) = - mutableMethod.getWalkerMethod(context, index) +fun MethodFingerprintResult.getWalkerMethod(context: BytecodeContext, offset: Int) = + mutableMethod.getWalkerMethod(context, offset) -fun MutableMethod.getWalkerMethod(context: BytecodeContext, index: Int) = - context.toMethodWalker(this) - .nextMethod(index, true) - .getMethod() as MutableMethod +/** + * MethodWalker structural limitations cause incorrect class to be found + * + * MethodReference to find in YouTube 18.29.38: + * 'Lng;->d(Lou;)Z' + * + * Class found by MethodWalker in YouTube 18.29.38: + * 'Lcom/google/android/gms/maps/model/LatLng;' + * + * The reason this error occurs is because [BytecodeContext.findClass] checks whether className is included or not + * + * In ReVanced Patcher 19.3.1: + * fun findClass(className: String) = findClass { it.type.contains(className) } + * + * (Class 'Lcom/google/android/gms/maps/model/LatLng;' is returned because class 'Lcom/google/android/gms/maps/model/LatLng;' contains keyword 'Lng;') + * + * As a workaround, redefine MethodWalker here + */ +fun MutableMethod.getWalkerMethod(context: BytecodeContext, offset: Int): MutableMethod { + val newMethod = getInstruction(offset).reference as MethodReference + return context.findClass { classDef -> classDef.type == newMethod.definingClass } + ?.mutableClass + ?.methods + ?.first { method -> MethodUtil.methodSignaturesMatch(method, newMethod) } + ?: throw PatchException("This method can not be walked at offset $offset inside the method $name") +} fun MutableClass.addFieldAndInstructions( context: BytecodeContext,