more or less finish composite api

This commit is contained in:
oSumAtrIX
2026-01-06 04:06:37 +01:00
parent 18570656cc
commit d2461f92aa
7 changed files with 1727 additions and 286 deletions

View File

@@ -5,7 +5,6 @@ android-compileSdk = "36"
android-minSdk = "26"
kotlin = "2.3.0"
apktool-lib = "2.10.1.1"
kotlinx-coroutines-core = "1.10.2"
mockk = "1.14.7"
multidexlib2 = "3.0.3.r3"
# Tracking https://github.com/google/smali/issues/64.
@@ -17,7 +16,6 @@ vanniktechMavenPublish = "0.35.0"
[libraries]
apktool-lib = { module = "app.revanced:apktool-lib", version.ref = "apktool-lib" }
kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" }
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines-core" }
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
mockk = { module = "io.mockk:mockk", version.ref = "mockk" }
multidexlib2 = { module = "app.revanced:multidexlib2", version.ref = "multidexlib2" }

View File

@@ -41,7 +41,6 @@ kotlin {
commonMain.dependencies {
implementation(libs.apktool.lib)
implementation(libs.kotlin.reflect)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.multidexlib2)
implementation(libs.smali)
implementation(libs.xpp3)

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,5 @@
package app.revanced.patcher.extensions
import com.android.tools.smali.dexlib2.mutable.MutableMethod
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.builder.BuilderInstruction
import com.android.tools.smali.dexlib2.builder.BuilderOffsetInstruction
@@ -10,6 +9,7 @@ import com.android.tools.smali.dexlib2.builder.instruction.*
import com.android.tools.smali.dexlib2.iface.Method
import com.android.tools.smali.dexlib2.iface.MethodImplementation
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
import com.android.tools.smali.dexlib2.mutable.MutableMethod
fun Method.accessFlags(vararg flags: AccessFlags) =
accessFlags.and(flags.map { it.ordinal }.reduce { acc, i -> acc or i }) != 0

View File

@@ -2,14 +2,13 @@ package app.revanced.patcher.patch
import app.revanced.patcher.PatchesResult
import app.revanced.patcher.extensions.instructionsOrNull
import app.revanced.patcher.extensions.string
import app.revanced.patcher.util.ClassMerger.merge
import app.revanced.patcher.util.MethodNavigator
import com.android.tools.smali.dexlib2.iface.ClassDef
import com.android.tools.smali.dexlib2.iface.DexFile
import com.android.tools.smali.dexlib2.iface.Method
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import com.android.tools.smali.dexlib2.iface.reference.StringReference
import com.android.tools.smali.dexlib2.mutable.MutableClassDef
import com.android.tools.smali.dexlib2.mutable.MutableClassDef.Companion.toMutable
import lanchon.multidexlib2.BasicDexFileNamer
@@ -141,13 +140,8 @@ class BytecodePatchContext internal constructor(
private fun ClassDef.forEachString(action: (Method, String) -> Unit) {
methods.asSequence().forEach { method ->
method.instructionsOrNull?.asSequence()
?.filterIsInstance<ReferenceInstruction>()
?.map { it.reference }
?.filterIsInstance<StringReference>()
?.map { it.string }
?.forEach { string ->
action(method, string)
}
?.mapNotNull { it.string }
?.forEach { string -> action(method, string) }
}
}

View File

@@ -1,8 +1,11 @@
package app.revanced.patcher
import app.revanced.patcher.BytecodePatchContextMethodMatching.firstMethod
import app.revanced.patcher.BytecodePatchContextMethodMatching.firstMethodDeclarativelyOrNull
import app.revanced.patcher.patch.bytecodePatch
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.immutable.ImmutableClassDef
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.TestInstance
@@ -13,13 +16,13 @@ import kotlin.test.assertFalse
import kotlin.test.assertNotNull
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
object MatchingTest : PatcherTestBase() {
class MatchingTest : PatcherTestBase() {
@BeforeAll
fun setup() = setupMock()
@Test
fun `finds via builder api`() {
fun firstMethodBuilder(fail: Boolean = false) = firstMethodBuilder {
fun firstMethodComposite(fail: Boolean = false) = firstMethodComposite {
name("method")
definingClass("class")
@@ -36,19 +39,20 @@ object MatchingTest : PatcherTestBase() {
)
}
bytecodePatch {
apply {
assertNotNull(firstMethodBuilder().methodOrNull) { "Expected to find a method" }
Assertions.assertNull(firstMethodBuilder(fail = true).methodOrNull) { "Expected to not find a method" }
}
}()
with(bytecodePatchContext) {
assertNotNull(firstMethodComposite().methodOrNull) { "Expected to find a method" }
Assertions.assertNull(firstMethodComposite(fail = true).immutableMethodOrNull) { "Expected to not find a method" }
Assertions.assertNotNull(
firstMethodComposite().match(classDefs.first()).methodOrNull
) { "Expected to find a method matching in a specific class" }
}
}
@Test
fun `finds via declarative api`() {
bytecodePatch {
apply {
val method = firstMethodByDeclarativePredicateOrNull {
val method = firstMethodDeclarativelyOrNull {
anyOf {
predicate { name == "method" }
add { false }
@@ -78,7 +82,7 @@ object MatchingTest : PatcherTestBase() {
val matcher = indexedMatcher<Int>()
matcher.apply {
+head { this > 5 }
+head<Int> { this > 5 }
}
assertFalse(
matcher(iterable),
@@ -86,7 +90,7 @@ object MatchingTest : PatcherTestBase() {
)
matcher.clear()
matcher.apply { +head { this == 1 } }(iterable)
matcher.apply { +head<Int> { this == 1 } }(iterable)
assertEquals(
listOf(0),
matcher.indices,
@@ -107,7 +111,7 @@ object MatchingTest : PatcherTestBase() {
matcher.clear()
matcher.apply {
+head { this == 1 }
+head<Int> { this == 1 }
add { _, _ -> this == 2 }
add { _, _ -> this == 4 }
}(iterable)
@@ -147,7 +151,7 @@ object MatchingTest : PatcherTestBase() {
matcher.clear()
matcher.apply {
+head { this == 1 }
+head<Int> { this == 1 }
+after(2..5) { this == 4 }
add { _, _ -> this == 8 }
add { _, _ -> this == 9 }