From 9c39c9efdb5d48ddaffce7f711c275e732b0b2d9 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Wed, 22 Jun 2022 13:33:15 +0200 Subject: [PATCH] feat: use of `java.util.logging.Logger` --- .../kotlin/app/revanced/patcher/Patcher.kt | 40 +++++++++++++--- .../resolver/MethodSignatureResolver.kt | 47 ++++++++++++------- 2 files changed, 63 insertions(+), 24 deletions(-) diff --git a/src/main/kotlin/app/revanced/patcher/Patcher.kt b/src/main/kotlin/app/revanced/patcher/Patcher.kt index fc5668a..8e534f0 100644 --- a/src/main/kotlin/app/revanced/patcher/Patcher.kt +++ b/src/main/kotlin/app/revanced/patcher/Patcher.kt @@ -34,6 +34,7 @@ import org.jf.dexlib2.iface.DexFile import org.jf.dexlib2.writer.io.MemoryDataStore import java.io.File import java.nio.file.Files +import java.util.logging.Logger val NAMER = BasicDexFileNamer() @@ -42,14 +43,20 @@ val NAMER = BasicDexFileNamer() * @param options The options for the patcher. */ class Patcher(private val options: PatcherOptions) { + private val logger: Logger = Logger.getLogger(::Patcher.name) + val data: PatcherData private val opcodes: Opcodes init { val extInputFile = ExtFile(options.inputFile) val outDir = File(options.resourceCacheDirectory) - if (outDir.exists()) outDir.deleteRecursively() - outDir.mkdirs() + if (outDir.exists()){ + logger.info("Delete previous resource cache directory") + + outDir.deleteRecursively() + outDir.mkdirs() + } val androlib = Androlib(BuildOptions().also { it.setBuildOptions(options) }) val resourceTable = androlib.getResTable(extInputFile, true) @@ -57,6 +64,8 @@ class Patcher(private val options: PatcherOptions) { val packageMetadata = PackageMetadata() if (options.patchResources) { + logger.info("Decode resources") + // decode resources to cache directory androlib.decodeManifestWithResources(extInputFile, outDir, resourceTable) androlib.decodeResourcesFull(extInputFile, outDir, resourceTable) @@ -71,6 +80,8 @@ class Patcher(private val options: PatcherOptions) { } } else { + logger.warning("Resource patching is disabled. Falling back to manually decode AndroidManifest.xml") + // create decoder for the resource table val decoder = ResAttrDecoder() decoder.currentPackage = ResPackage(resourceTable, 0, null) @@ -93,6 +104,8 @@ class Patcher(private val options: PatcherOptions) { packageMetadata.metaInfo.versionInfo = resourceTable.versionInfo packageMetadata.metaInfo.sdkInfo = resourceTable.sdkInfo + logger.info("Read dex files") + // read dex files val dexFile = MultiDexIO.readDexFile(true, options.inputFile, NAMER, null, null) // get the opcodes @@ -115,17 +128,22 @@ class Patcher(private val options: PatcherOptions) { ) { for (file in files) { for (classDef in MultiDexIO.readDexFile(true, file, NAMER, null, null).classes) { - val e = data.bytecodeData.classes.internalClasses.findIndexed { it.type == classDef.type } + val type = classDef.type + val e = data.bytecodeData.classes.internalClasses.findIndexed { it.type == type } if (e != null) { if (throwOnDuplicates) { - throw Exception("Class ${classDef.type} has already been added to the patcher.") + throw Exception("Class $type has already been added to the patcher.") } val (_, idx) = e - if (allowedOverwrites.contains(classDef.type)) { + if (allowedOverwrites.contains(type)) { + logger.fine("Override $type") data.bytecodeData.classes.internalClasses[idx] = classDef + continue } + logger.fine("Skip $type") continue } + logger.finest("Add $type") data.bytecodeData.classes.internalClasses.add(classDef) } } @@ -173,6 +191,8 @@ class Patcher(private val options: PatcherOptions) { ) }.toTypedArray() + logger.info("Building resources. This takes some time") + androlibResources.aaptPackage( aaptFile, manifestFile, resDirectory, null, null, includedFiles @@ -192,6 +212,8 @@ class Patcher(private val options: PatcherOptions) { } } + logger.info("Write dex files") + // write dex modified files val dexFiles = mutableMapOf() MultiDexIO.writeDexFile( @@ -228,7 +250,11 @@ class Patcher(private val options: PatcherOptions) { val patchName = patch.patchName // if the patch has already applied silently skip it - if (appliedPatches.contains(patchName)) return PatchResultSuccess() + if (appliedPatches.contains(patchName)){ + logger.fine("Skip $patchName because it already has been applied") + + return PatchResultSuccess() + } appliedPatches.add(patchName) // recursively apply all dependency patches @@ -258,6 +284,8 @@ class Patcher(private val options: PatcherOptions) { data.bytecodeData } + logger.fine("Execute $patchName") + return try { patchInstance.execute(data) } catch (e: Exception) { diff --git a/src/main/kotlin/app/revanced/patcher/signature/implementation/method/resolver/MethodSignatureResolver.kt b/src/main/kotlin/app/revanced/patcher/signature/implementation/method/resolver/MethodSignatureResolver.kt index 5c1f804..d87a74e 100644 --- a/src/main/kotlin/app/revanced/patcher/signature/implementation/method/resolver/MethodSignatureResolver.kt +++ b/src/main/kotlin/app/revanced/patcher/signature/implementation/method/resolver/MethodSignatureResolver.kt @@ -3,6 +3,7 @@ package app.revanced.patcher.signature.implementation.method.resolver import app.revanced.patcher.data.PatcherData import app.revanced.patcher.data.implementation.proxy import app.revanced.patcher.extensions.MethodSignatureExtensions.fuzzyThreshold +import app.revanced.patcher.extensions.MethodSignatureExtensions.name import app.revanced.patcher.extensions.parametersEqual import app.revanced.patcher.signature.implementation.method.MethodSignature import org.jf.dexlib2.Opcode @@ -11,37 +12,25 @@ import org.jf.dexlib2.iface.Method import org.jf.dexlib2.iface.instruction.Instruction import org.jf.dexlib2.iface.instruction.formats.Instruction21c import org.jf.dexlib2.iface.reference.StringReference +import java.util.logging.Logger internal class MethodSignatureResolver( private val classes: List, private val methodSignatures: Iterable ) { - fun resolve(patcherData: PatcherData) { - for (signature in methodSignatures) { - for (classDef in classes) { - for (method in classDef.methods) { - val patternScanData = compareSignatureToMethod(signature, method) ?: continue - - // create class proxy, in case a patch needs mutability - val classProxy = patcherData.bytecodeData.proxy(classDef) - signature.result = SignatureResolverResult( - classProxy, - patternScanData, - method, - ) - } - } - } - } - // These functions do not require the constructor values, so they can be static. companion object { + private val LOGGER: Logger = Logger.getLogger(::MethodSignatureResolver.name) + fun resolveFromProxy( classProxy: app.revanced.patcher.util.proxy.ClassProxy, signature: MethodSignature ): SignatureResolverResult? { for (method in classProxy.immutableClass.methods) { val result = compareSignatureToMethod(signature, method) ?: continue + + LOGGER.fine("${signature.name} match to ${method.definingClass}->${method.name}") + return SignatureResolverResult( classProxy, result, @@ -156,6 +145,28 @@ internal class MethodSignatureResolver( } } } + + fun resolve(patcherData: PatcherData) { + for (signature in methodSignatures) { + val signatureName = signature.name + LOGGER.fine("Resolve $signatureName") + for (classDef in classes) { + for (method in classDef.methods) { + val patternScanData = compareSignatureToMethod(signature, method) ?: continue + + LOGGER.fine("$signatureName match to ${method.definingClass}->${method.name}") + + // create class proxy, in case a patch needs mutability + val classProxy = patcherData.bytecodeData.proxy(classDef) + signature.result = SignatureResolverResult( + classProxy, + patternScanData, + method, + ) + } + } + } + } } private operator fun ClassDef.component1() = this