diff --git a/api/revanced-patches.api b/api/revanced-patches.api index 27fedbe324..a325060843 100644 --- a/api/revanced-patches.api +++ b/api/revanced-patches.api @@ -16,6 +16,14 @@ public final class app/revanced/patches/all/connectivity/wifi/spoof/SpoofWifiPat public fun transform (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Lkotlin/Triple;)V } +public final class app/revanced/patches/all/directory/ChangeDataDirectoryLocationPatch : app/revanced/patches/all/misc/transformation/BaseTransformInstructionsPatch { + public static final field INSTANCE Lapp/revanced/patches/all/directory/ChangeDataDirectoryLocationPatch; + public fun filterMap (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;I)Ljava/lang/Integer; + public synthetic fun filterMap (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;I)Ljava/lang/Object; + public fun transform (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;I)V + public synthetic fun transform (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Ljava/lang/Object;)V +} + public final class app/revanced/patches/all/interaction/gestures/PredictiveBackGesturePatch : app/revanced/patcher/patch/ResourcePatch { public static final field INSTANCE Lapp/revanced/patches/all/interaction/gestures/PredictiveBackGesturePatch; public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V diff --git a/src/main/kotlin/app/revanced/patches/all/directory/ChangeDataDirectoryLocationPatch.kt b/src/main/kotlin/app/revanced/patches/all/directory/ChangeDataDirectoryLocationPatch.kt new file mode 100644 index 0000000000..42d48f7d2a --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/all/directory/ChangeDataDirectoryLocationPatch.kt @@ -0,0 +1,73 @@ +package app.revanced.patches.all.directory + +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import app.revanced.patches.all.misc.transformation.BaseTransformInstructionsPatch +import app.revanced.util.getReference +import com.android.tools.smali.dexlib2.iface.ClassDef +import com.android.tools.smali.dexlib2.iface.Method +import com.android.tools.smali.dexlib2.iface.instruction.Instruction +import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c +import com.android.tools.smali.dexlib2.iface.reference.MethodReference +import com.android.tools.smali.dexlib2.immutable.reference.ImmutableMethodReference +import com.android.tools.smali.dexlib2.util.MethodUtil + +@Patch( + name = "Change data directory location", + description = "Changes the data directory in the application from " + + "the app internal storage directory to /sdcard/android/data accessible by root-less devices." + + "Using this patch can cause unexpected issues with some apps.", + use = false, +) +@Suppress("unused") +object ChangeDataDirectoryLocationPatch : BaseTransformInstructionsPatch() { + override fun filterMap( + classDef: ClassDef, + method: Method, + instruction: Instruction, + instructionIndex: Int, + ): Int? { + val reference = instruction.getReference() ?: return null + + if (!MethodUtil.methodSignaturesMatch(reference, MethodCall.GetDir.reference)) { + return null + } + + return instructionIndex + } + + override fun transform( + mutableMethod: MutableMethod, + entry: Int, + ) = transformMethodCall(entry, mutableMethod) + + private fun transformMethodCall( + instructionIndex: Int, + mutableMethod: MutableMethod, + ) { + val getDirInstruction = mutableMethod.getInstruction(instructionIndex) + val contextRegister = getDirInstruction.registerC + val dataRegister = getDirInstruction.registerD + + mutableMethod.replaceInstruction( + instructionIndex, + "invoke-virtual { v$contextRegister, v$dataRegister }, " + + "Landroid/content/Context;->getExternalFilesDir(Ljava/lang/String;)Ljava/io/File;", + ) + } + + private enum class MethodCall( + val reference: MethodReference, + ) { + GetDir( + ImmutableMethodReference( + "Landroid/content/Context;", + "getDir", + listOf("Ljava/lang/String;", "I"), + "Ljava/io/File;", + ), + ), + } +}