feat: use of java.util.logging.Logger

This commit is contained in:
oSumAtrIX 2022-06-22 13:33:15 +02:00
parent 3ee1c01430
commit 9c39c9efdb
No known key found for this signature in database
GPG key ID: A9B3094ACDB604B4
2 changed files with 63 additions and 24 deletions

View file

@ -34,6 +34,7 @@ import org.jf.dexlib2.iface.DexFile
import org.jf.dexlib2.writer.io.MemoryDataStore import org.jf.dexlib2.writer.io.MemoryDataStore
import java.io.File import java.io.File
import java.nio.file.Files import java.nio.file.Files
import java.util.logging.Logger
val NAMER = BasicDexFileNamer() val NAMER = BasicDexFileNamer()
@ -42,14 +43,20 @@ val NAMER = BasicDexFileNamer()
* @param options The options for the patcher. * @param options The options for the patcher.
*/ */
class Patcher(private val options: PatcherOptions) { class Patcher(private val options: PatcherOptions) {
private val logger: Logger = Logger.getLogger(::Patcher.name)
val data: PatcherData val data: PatcherData
private val opcodes: Opcodes private val opcodes: Opcodes
init { init {
val extInputFile = ExtFile(options.inputFile) val extInputFile = ExtFile(options.inputFile)
val outDir = File(options.resourceCacheDirectory) val outDir = File(options.resourceCacheDirectory)
if (outDir.exists()) outDir.deleteRecursively() if (outDir.exists()){
outDir.mkdirs() logger.info("Delete previous resource cache directory")
outDir.deleteRecursively()
outDir.mkdirs()
}
val androlib = Androlib(BuildOptions().also { it.setBuildOptions(options) }) val androlib = Androlib(BuildOptions().also { it.setBuildOptions(options) })
val resourceTable = androlib.getResTable(extInputFile, true) val resourceTable = androlib.getResTable(extInputFile, true)
@ -57,6 +64,8 @@ class Patcher(private val options: PatcherOptions) {
val packageMetadata = PackageMetadata() val packageMetadata = PackageMetadata()
if (options.patchResources) { if (options.patchResources) {
logger.info("Decode resources")
// decode resources to cache directory // decode resources to cache directory
androlib.decodeManifestWithResources(extInputFile, outDir, resourceTable) androlib.decodeManifestWithResources(extInputFile, outDir, resourceTable)
androlib.decodeResourcesFull(extInputFile, outDir, resourceTable) androlib.decodeResourcesFull(extInputFile, outDir, resourceTable)
@ -71,6 +80,8 @@ class Patcher(private val options: PatcherOptions) {
} }
} else { } else {
logger.warning("Resource patching is disabled. Falling back to manually decode AndroidManifest.xml")
// create decoder for the resource table // create decoder for the resource table
val decoder = ResAttrDecoder() val decoder = ResAttrDecoder()
decoder.currentPackage = ResPackage(resourceTable, 0, null) decoder.currentPackage = ResPackage(resourceTable, 0, null)
@ -93,6 +104,8 @@ class Patcher(private val options: PatcherOptions) {
packageMetadata.metaInfo.versionInfo = resourceTable.versionInfo packageMetadata.metaInfo.versionInfo = resourceTable.versionInfo
packageMetadata.metaInfo.sdkInfo = resourceTable.sdkInfo packageMetadata.metaInfo.sdkInfo = resourceTable.sdkInfo
logger.info("Read dex files")
// read dex files // read dex files
val dexFile = MultiDexIO.readDexFile(true, options.inputFile, NAMER, null, null) val dexFile = MultiDexIO.readDexFile(true, options.inputFile, NAMER, null, null)
// get the opcodes // get the opcodes
@ -115,17 +128,22 @@ class Patcher(private val options: PatcherOptions) {
) { ) {
for (file in files) { for (file in files) {
for (classDef in MultiDexIO.readDexFile(true, file, NAMER, null, null).classes) { 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 (e != null) {
if (throwOnDuplicates) { 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 val (_, idx) = e
if (allowedOverwrites.contains(classDef.type)) { if (allowedOverwrites.contains(type)) {
logger.fine("Override $type")
data.bytecodeData.classes.internalClasses[idx] = classDef data.bytecodeData.classes.internalClasses[idx] = classDef
continue
} }
logger.fine("Skip $type")
continue continue
} }
logger.finest("Add $type")
data.bytecodeData.classes.internalClasses.add(classDef) data.bytecodeData.classes.internalClasses.add(classDef)
} }
} }
@ -173,6 +191,8 @@ class Patcher(private val options: PatcherOptions) {
) )
}.toTypedArray() }.toTypedArray()
logger.info("Building resources. This takes some time")
androlibResources.aaptPackage( androlibResources.aaptPackage(
aaptFile, manifestFile, resDirectory, null, aaptFile, manifestFile, resDirectory, null,
null, includedFiles null, includedFiles
@ -192,6 +212,8 @@ class Patcher(private val options: PatcherOptions) {
} }
} }
logger.info("Write dex files")
// write dex modified files // write dex modified files
val dexFiles = mutableMapOf<String, MemoryDataStore>() val dexFiles = mutableMapOf<String, MemoryDataStore>()
MultiDexIO.writeDexFile( MultiDexIO.writeDexFile(
@ -228,7 +250,11 @@ class Patcher(private val options: PatcherOptions) {
val patchName = patch.patchName val patchName = patch.patchName
// if the patch has already applied silently skip it // 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) appliedPatches.add(patchName)
// recursively apply all dependency patches // recursively apply all dependency patches
@ -258,6 +284,8 @@ class Patcher(private val options: PatcherOptions) {
data.bytecodeData data.bytecodeData
} }
logger.fine("Execute $patchName")
return try { return try {
patchInstance.execute(data) patchInstance.execute(data)
} catch (e: Exception) { } catch (e: Exception) {

View file

@ -3,6 +3,7 @@ package app.revanced.patcher.signature.implementation.method.resolver
import app.revanced.patcher.data.PatcherData import app.revanced.patcher.data.PatcherData
import app.revanced.patcher.data.implementation.proxy import app.revanced.patcher.data.implementation.proxy
import app.revanced.patcher.extensions.MethodSignatureExtensions.fuzzyThreshold import app.revanced.patcher.extensions.MethodSignatureExtensions.fuzzyThreshold
import app.revanced.patcher.extensions.MethodSignatureExtensions.name
import app.revanced.patcher.extensions.parametersEqual import app.revanced.patcher.extensions.parametersEqual
import app.revanced.patcher.signature.implementation.method.MethodSignature import app.revanced.patcher.signature.implementation.method.MethodSignature
import org.jf.dexlib2.Opcode 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.Instruction
import org.jf.dexlib2.iface.instruction.formats.Instruction21c import org.jf.dexlib2.iface.instruction.formats.Instruction21c
import org.jf.dexlib2.iface.reference.StringReference import org.jf.dexlib2.iface.reference.StringReference
import java.util.logging.Logger
internal class MethodSignatureResolver( internal class MethodSignatureResolver(
private val classes: List<ClassDef>, private val classes: List<ClassDef>,
private val methodSignatures: Iterable<MethodSignature> private val methodSignatures: Iterable<MethodSignature>
) { ) {
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. // These functions do not require the constructor values, so they can be static.
companion object { companion object {
private val LOGGER: Logger = Logger.getLogger(::MethodSignatureResolver.name)
fun resolveFromProxy( fun resolveFromProxy(
classProxy: app.revanced.patcher.util.proxy.ClassProxy, classProxy: app.revanced.patcher.util.proxy.ClassProxy,
signature: MethodSignature signature: MethodSignature
): SignatureResolverResult? { ): SignatureResolverResult? {
for (method in classProxy.immutableClass.methods) { for (method in classProxy.immutableClass.methods) {
val result = compareSignatureToMethod(signature, method) ?: continue val result = compareSignatureToMethod(signature, method) ?: continue
LOGGER.fine("${signature.name} match to ${method.definingClass}->${method.name}")
return SignatureResolverResult( return SignatureResolverResult(
classProxy, classProxy,
result, 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 private operator fun ClassDef.component1() = this