mirror of
https://github.com/revanced/revanced-patcher.git
synced 2025-05-01 05:44:24 +02:00
docs: Document important parts of the code
This commit is contained in:
parent
1dd3394ea3
commit
650bf71124
@ -5,17 +5,24 @@ import app.revanced.patcher.patch.Patch
|
||||
import app.revanced.patcher.resolver.SignatureResolver
|
||||
import app.revanced.patcher.signature.MethodSignature
|
||||
import lanchon.multidexlib2.BasicDexFileNamer
|
||||
import lanchon.multidexlib2.DexIO
|
||||
import lanchon.multidexlib2.MultiDexIO
|
||||
import org.jf.dexlib2.Opcodes
|
||||
import org.jf.dexlib2.iface.ClassDef
|
||||
import org.jf.dexlib2.iface.DexFile
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* ReVanced Patcher.
|
||||
* @param input The input file (an apk or any other multi dex container).
|
||||
* @param output The output folder.
|
||||
* @param signatures An array of method signatures for the patches
|
||||
*
|
||||
*/
|
||||
class Patcher(
|
||||
input: File,
|
||||
private val output: File,
|
||||
signatures: Array<MethodSignature>,
|
||||
|
||||
) {
|
||||
private val cache: Cache
|
||||
private val patches = mutableSetOf<Patch>()
|
||||
@ -25,6 +32,9 @@ class Patcher(
|
||||
cache = Cache(dexFile.classes, SignatureResolver(dexFile.classes, signatures).resolve())
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the patched dex file.
|
||||
*/
|
||||
fun save() {
|
||||
val newDexFile = object : DexFile {
|
||||
override fun getClasses(): Set<ClassDef> {
|
||||
@ -45,13 +55,21 @@ class Patcher(
|
||||
}
|
||||
|
||||
// TODO: we should use the multithreading capable overload for writeDexFile
|
||||
MultiDexIO.writeDexFile(true, output, BasicDexFileNamer(), newDexFile, 50000, null)
|
||||
MultiDexIO.writeDexFile(true, output, BasicDexFileNamer(), newDexFile, DexIO.DEFAULT_MAX_DEX_POOL_SIZE, null)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a patch to the patcher.
|
||||
* @param patches The patches to add.
|
||||
*/
|
||||
fun addPatches(vararg patches: Patch) {
|
||||
this.patches.addAll(patches)
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply patches loaded into the patcher.
|
||||
* @param stopOnError If true, the patches will stop on the first error.
|
||||
*/
|
||||
fun applyPatches(stopOnError: Boolean = false): Map<String, Result<Nothing?>> {
|
||||
return buildMap {
|
||||
// TODO: after each patch execution we could clear left overs like proxied classes to safe memory
|
||||
|
@ -13,6 +13,10 @@ class Cache(
|
||||
// if the class proxy already exists in the cached proxy list below
|
||||
internal val classProxy = mutableSetOf<ClassProxy>()
|
||||
|
||||
/**
|
||||
* Find a class by a given predicate
|
||||
* @return A proxy for the first class that matches the predicate
|
||||
*/
|
||||
fun findClass(predicate: (ClassDef) -> Boolean): ClassProxy? {
|
||||
// if we already proxied the class matching the predicate,
|
||||
val proxiedClass = classProxy.singleOrNull { classProxy -> predicate(classProxy.immutableClass) }
|
||||
|
@ -3,6 +3,13 @@ package app.revanced.patcher.proxy
|
||||
import app.revanced.patcher.proxy.mutableTypes.MutableClass
|
||||
import org.jf.dexlib2.iface.ClassDef
|
||||
|
||||
/**
|
||||
* A proxy class for a [ClassDef]
|
||||
* A class proxy simply holds a reference to the original class
|
||||
* and creates a mutable clone for the original class if needed.
|
||||
* @param immutableClass The class to proxy
|
||||
* @param originalIndex The original index of the class in the list of classes
|
||||
*/
|
||||
class ClassProxy(
|
||||
val immutableClass: ClassDef,
|
||||
val originalIndex: Int,
|
||||
@ -10,6 +17,10 @@ class ClassProxy(
|
||||
internal var proxyUsed = false
|
||||
internal lateinit var mutatedClass: MutableClass
|
||||
|
||||
/**
|
||||
* Creates and returns a mutable clone of the original class
|
||||
* A patch should always use the original immutable class reference to avoid unnucessary allocations for the mutable class
|
||||
*/
|
||||
fun resolve(): MutableClass {
|
||||
if (!proxyUsed) {
|
||||
proxyUsed = true
|
||||
|
@ -2,6 +2,14 @@ package app.revanced.patcher.signature
|
||||
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
/**
|
||||
* Represents a method signature.
|
||||
* @param name A suggestive name for the method which the signature was created for.
|
||||
* @param returnType The return type of the method.
|
||||
* @param methodParameters The parameters of the method.
|
||||
* @param opcodes A list of opcodes of the method.
|
||||
* @param accessFlags The access flags of the method.
|
||||
*/
|
||||
@Suppress("ArrayInDataClass")
|
||||
data class MethodSignature(
|
||||
val name: String,
|
||||
|
@ -3,6 +3,12 @@ package app.revanced.patcher.signature
|
||||
import app.revanced.patcher.proxy.ClassProxy
|
||||
import app.revanced.patcher.resolver.SignatureResolver
|
||||
|
||||
/**
|
||||
* Represents the result of a [SignatureResolver].
|
||||
* @param definingClassProxy The [ClassProxy] that the matching method was found in.
|
||||
* @param resolvedMethodName The name of the actual matching method.
|
||||
* @param scanData OpCodes pattern scan result.
|
||||
*/
|
||||
data class SignatureResolverResult(
|
||||
val definingClassProxy: ClassProxy,
|
||||
val resolvedMethodName: String,
|
||||
|
Loading…
x
Reference in New Issue
Block a user