mirror of
https://github.com/ReVanced/revanced-patcher.git
synced 2024-11-13 02:14:27 +01:00
feat: use of java.util.logging.Logger
This commit is contained in:
parent
3ee1c01430
commit
9c39c9efdb
2 changed files with 63 additions and 24 deletions
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue