mirror of
https://github.com/ReVanced/revanced-patcher.git
synced 2026-01-11 13:56:16 +00:00
more or less finish composite api
This commit is contained in:
@@ -5,7 +5,6 @@ android-compileSdk = "36"
|
|||||||
android-minSdk = "26"
|
android-minSdk = "26"
|
||||||
kotlin = "2.3.0"
|
kotlin = "2.3.0"
|
||||||
apktool-lib = "2.10.1.1"
|
apktool-lib = "2.10.1.1"
|
||||||
kotlinx-coroutines-core = "1.10.2"
|
|
||||||
mockk = "1.14.7"
|
mockk = "1.14.7"
|
||||||
multidexlib2 = "3.0.3.r3"
|
multidexlib2 = "3.0.3.r3"
|
||||||
# Tracking https://github.com/google/smali/issues/64.
|
# Tracking https://github.com/google/smali/issues/64.
|
||||||
@@ -17,7 +16,6 @@ vanniktechMavenPublish = "0.35.0"
|
|||||||
[libraries]
|
[libraries]
|
||||||
apktool-lib = { module = "app.revanced:apktool-lib", version.ref = "apktool-lib" }
|
apktool-lib = { module = "app.revanced:apktool-lib", version.ref = "apktool-lib" }
|
||||||
kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" }
|
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" }
|
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
|
||||||
mockk = { module = "io.mockk:mockk", version.ref = "mockk" }
|
mockk = { module = "io.mockk:mockk", version.ref = "mockk" }
|
||||||
multidexlib2 = { module = "app.revanced:multidexlib2", version.ref = "multidexlib2" }
|
multidexlib2 = { module = "app.revanced:multidexlib2", version.ref = "multidexlib2" }
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ kotlin {
|
|||||||
commonMain.dependencies {
|
commonMain.dependencies {
|
||||||
implementation(libs.apktool.lib)
|
implementation(libs.apktool.lib)
|
||||||
implementation(libs.kotlin.reflect)
|
implementation(libs.kotlin.reflect)
|
||||||
implementation(libs.kotlinx.coroutines.core)
|
|
||||||
implementation(libs.multidexlib2)
|
implementation(libs.multidexlib2)
|
||||||
implementation(libs.smali)
|
implementation(libs.smali)
|
||||||
implementation(libs.xpp3)
|
implementation(libs.xpp3)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,5 @@
|
|||||||
package app.revanced.patcher.extensions
|
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.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.builder.BuilderInstruction
|
import com.android.tools.smali.dexlib2.builder.BuilderInstruction
|
||||||
import com.android.tools.smali.dexlib2.builder.BuilderOffsetInstruction
|
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.Method
|
||||||
import com.android.tools.smali.dexlib2.iface.MethodImplementation
|
import com.android.tools.smali.dexlib2.iface.MethodImplementation
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
|
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
|
||||||
|
import com.android.tools.smali.dexlib2.mutable.MutableMethod
|
||||||
|
|
||||||
fun Method.accessFlags(vararg flags: AccessFlags) =
|
fun Method.accessFlags(vararg flags: AccessFlags) =
|
||||||
accessFlags.and(flags.map { it.ordinal }.reduce { acc, i -> acc or i }) != 0
|
accessFlags.and(flags.map { it.ordinal }.reduce { acc, i -> acc or i }) != 0
|
||||||
|
|||||||
@@ -2,14 +2,13 @@ package app.revanced.patcher.patch
|
|||||||
|
|
||||||
import app.revanced.patcher.PatchesResult
|
import app.revanced.patcher.PatchesResult
|
||||||
import app.revanced.patcher.extensions.instructionsOrNull
|
import app.revanced.patcher.extensions.instructionsOrNull
|
||||||
|
import app.revanced.patcher.extensions.string
|
||||||
import app.revanced.patcher.util.ClassMerger.merge
|
import app.revanced.patcher.util.ClassMerger.merge
|
||||||
import app.revanced.patcher.util.MethodNavigator
|
import app.revanced.patcher.util.MethodNavigator
|
||||||
import com.android.tools.smali.dexlib2.iface.ClassDef
|
import com.android.tools.smali.dexlib2.iface.ClassDef
|
||||||
import com.android.tools.smali.dexlib2.iface.DexFile
|
import com.android.tools.smali.dexlib2.iface.DexFile
|
||||||
import com.android.tools.smali.dexlib2.iface.Method
|
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.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
|
||||||
import com.android.tools.smali.dexlib2.mutable.MutableClassDef.Companion.toMutable
|
import com.android.tools.smali.dexlib2.mutable.MutableClassDef.Companion.toMutable
|
||||||
import lanchon.multidexlib2.BasicDexFileNamer
|
import lanchon.multidexlib2.BasicDexFileNamer
|
||||||
@@ -141,13 +140,8 @@ class BytecodePatchContext internal constructor(
|
|||||||
private fun ClassDef.forEachString(action: (Method, String) -> Unit) {
|
private fun ClassDef.forEachString(action: (Method, String) -> Unit) {
|
||||||
methods.asSequence().forEach { method ->
|
methods.asSequence().forEach { method ->
|
||||||
method.instructionsOrNull?.asSequence()
|
method.instructionsOrNull?.asSequence()
|
||||||
?.filterIsInstance<ReferenceInstruction>()
|
?.mapNotNull { it.string }
|
||||||
?.map { it.reference }
|
?.forEach { string -> action(method, string) }
|
||||||
?.filterIsInstance<StringReference>()
|
|
||||||
?.map { it.string }
|
|
||||||
?.forEach { string ->
|
|
||||||
action(method, string)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
package app.revanced.patcher
|
package app.revanced.patcher
|
||||||
|
|
||||||
|
import app.revanced.patcher.BytecodePatchContextMethodMatching.firstMethod
|
||||||
|
import app.revanced.patcher.BytecodePatchContextMethodMatching.firstMethodDeclarativelyOrNull
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
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.Assertions
|
||||||
import org.junit.jupiter.api.BeforeAll
|
import org.junit.jupiter.api.BeforeAll
|
||||||
import org.junit.jupiter.api.TestInstance
|
import org.junit.jupiter.api.TestInstance
|
||||||
@@ -13,13 +16,13 @@ import kotlin.test.assertFalse
|
|||||||
import kotlin.test.assertNotNull
|
import kotlin.test.assertNotNull
|
||||||
|
|
||||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
object MatchingTest : PatcherTestBase() {
|
class MatchingTest : PatcherTestBase() {
|
||||||
@BeforeAll
|
@BeforeAll
|
||||||
fun setup() = setupMock()
|
fun setup() = setupMock()
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `finds via builder api`() {
|
fun `finds via builder api`() {
|
||||||
fun firstMethodBuilder(fail: Boolean = false) = firstMethodBuilder {
|
fun firstMethodComposite(fail: Boolean = false) = firstMethodComposite {
|
||||||
name("method")
|
name("method")
|
||||||
definingClass("class")
|
definingClass("class")
|
||||||
|
|
||||||
@@ -36,19 +39,20 @@ object MatchingTest : PatcherTestBase() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
bytecodePatch {
|
with(bytecodePatchContext) {
|
||||||
apply {
|
assertNotNull(firstMethodComposite().methodOrNull) { "Expected to find a method" }
|
||||||
assertNotNull(firstMethodBuilder().methodOrNull) { "Expected to find a method" }
|
Assertions.assertNull(firstMethodComposite(fail = true).immutableMethodOrNull) { "Expected to not find a method" }
|
||||||
Assertions.assertNull(firstMethodBuilder(fail = true).methodOrNull) { "Expected to not find a method" }
|
Assertions.assertNotNull(
|
||||||
}
|
firstMethodComposite().match(classDefs.first()).methodOrNull
|
||||||
}()
|
) { "Expected to find a method matching in a specific class" }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `finds via declarative api`() {
|
fun `finds via declarative api`() {
|
||||||
bytecodePatch {
|
bytecodePatch {
|
||||||
apply {
|
apply {
|
||||||
val method = firstMethodByDeclarativePredicateOrNull {
|
val method = firstMethodDeclarativelyOrNull {
|
||||||
anyOf {
|
anyOf {
|
||||||
predicate { name == "method" }
|
predicate { name == "method" }
|
||||||
add { false }
|
add { false }
|
||||||
@@ -78,7 +82,7 @@ object MatchingTest : PatcherTestBase() {
|
|||||||
val matcher = indexedMatcher<Int>()
|
val matcher = indexedMatcher<Int>()
|
||||||
|
|
||||||
matcher.apply {
|
matcher.apply {
|
||||||
+head { this > 5 }
|
+head<Int> { this > 5 }
|
||||||
}
|
}
|
||||||
assertFalse(
|
assertFalse(
|
||||||
matcher(iterable),
|
matcher(iterable),
|
||||||
@@ -86,7 +90,7 @@ object MatchingTest : PatcherTestBase() {
|
|||||||
)
|
)
|
||||||
matcher.clear()
|
matcher.clear()
|
||||||
|
|
||||||
matcher.apply { +head { this == 1 } }(iterable)
|
matcher.apply { +head<Int> { this == 1 } }(iterable)
|
||||||
assertEquals(
|
assertEquals(
|
||||||
listOf(0),
|
listOf(0),
|
||||||
matcher.indices,
|
matcher.indices,
|
||||||
@@ -107,7 +111,7 @@ object MatchingTest : PatcherTestBase() {
|
|||||||
matcher.clear()
|
matcher.clear()
|
||||||
|
|
||||||
matcher.apply {
|
matcher.apply {
|
||||||
+head { this == 1 }
|
+head<Int> { this == 1 }
|
||||||
add { _, _ -> this == 2 }
|
add { _, _ -> this == 2 }
|
||||||
add { _, _ -> this == 4 }
|
add { _, _ -> this == 4 }
|
||||||
}(iterable)
|
}(iterable)
|
||||||
@@ -147,7 +151,7 @@ object MatchingTest : PatcherTestBase() {
|
|||||||
matcher.clear()
|
matcher.clear()
|
||||||
|
|
||||||
matcher.apply {
|
matcher.apply {
|
||||||
+head { this == 1 }
|
+head<Int> { this == 1 }
|
||||||
+after(2..5) { this == 4 }
|
+after(2..5) { this == 4 }
|
||||||
add { _, _ -> this == 8 }
|
add { _, _ -> this == 8 }
|
||||||
add { _, _ -> this == 9 }
|
add { _, _ -> this == 9 }
|
||||||
|
|||||||
Reference in New Issue
Block a user