Compare commits

..

12 Commits

Author SHA1 Message Date
semantic-release-bot
3c8d3edff4 chore(release): 2.10.0 [skip ci]
# [2.10.0](https://github.com/revanced/revanced-patches/compare/v2.9.4...v2.10.0) (2022-07-07)

### Features

* implement `wide-searchbar` Patch ([#130](https://github.com/revanced/revanced-patches/issues/130)) ([c35734b](c35734bec2))
2022-07-07 23:42:01 +00:00
TheJeterLP
c35734bec2 feat: implement wide-searchbar Patch (#130) 2022-07-08 01:40:12 +02:00
semantic-release-bot
e2b634053b chore(release): 2.9.4 [skip ci]
## [2.9.4](https://github.com/revanced/revanced-patches/compare/v2.9.3...v2.9.4) (2022-07-06)

### Bug Fixes

* add 17.25.34 as supported version for swipe-controls patch ([3e6df0c](3e6df0c96d))
2022-07-06 18:34:04 +00:00
TheJeterLP
3e6df0c96d fix: add 17.25.34 as supported version for swipe-controls patch 2022-07-06 20:31:59 +02:00
semantic-release-bot
7a2ea95e55 chore(release): 2.9.3 [skip ci]
## [2.9.3](https://github.com/revanced/revanced-patches/compare/v2.9.2...v2.9.3) (2022-07-06)

### Bug Fixes

* Readd `swipe-controls` patch ([#123](https://github.com/revanced/revanced-patches/issues/123)) ([add3058](add3058d24))
2022-07-06 18:29:29 +00:00
TheJeterLP
add3058d24 fix: Readd swipe-controls patch (#123) 2022-07-06 20:27:28 +02:00
semantic-release-bot
ef888f6b59 chore(release): 2.9.2 [skip ci]
## [2.9.2](https://github.com/revanced/revanced-patches/compare/v2.9.1...v2.9.2) (2022-07-05)

### Bug Fixes

* revert `swipe-controls` patch  ([9b077d6](9b077d6ada))
2022-07-05 21:26:17 +00:00
oSumAtrIX
9b077d6ada fix: revert swipe-controls patch
This reverts commit cd66ee4e57.
2022-07-05 23:24:10 +02:00
semantic-release-bot
93d4cee16e chore(release): 2.9.1 [skip ci]
## [2.9.1](https://github.com/revanced/revanced-patches/compare/v2.9.0...v2.9.1) (2022-07-05)

### Bug Fixes

* make `minimized-playback-manager-fingerprint` unique ([#120](https://github.com/revanced/revanced-patches/issues/120)) ([bc3b654](bc3b654357))
2022-07-05 20:24:42 +00:00
bogadana
bc3b654357 fix: make minimized-playback-manager-fingerprint unique (#120) 2022-07-05 22:23:00 +02:00
semantic-release-bot
64b4c92ca0 chore(release): 2.9.0 [skip ci]
# [2.9.0](https://github.com/revanced/revanced-patches/compare/v2.8.2...v2.9.0) (2022-07-05)

### Features

* `swipe-controls` patch ([#115](https://github.com/revanced/revanced-patches/issues/115)) ([cd66ee4](cd66ee4e57))
2022-07-05 20:04:45 +00:00
Chris
cd66ee4e57 feat: swipe-controls patch (#115) 2022-07-05 22:03:07 +02:00
15 changed files with 640 additions and 10 deletions

View File

@@ -1,3 +1,45 @@
# [2.10.0](https://github.com/revanced/revanced-patches/compare/v2.9.4...v2.10.0) (2022-07-07)
### Features
* implement `wide-searchbar` Patch ([#130](https://github.com/revanced/revanced-patches/issues/130)) ([332f4d1](https://github.com/revanced/revanced-patches/commit/332f4d12d06316d65db252a280fe1f263e65c3a8))
## [2.9.4](https://github.com/revanced/revanced-patches/compare/v2.9.3...v2.9.4) (2022-07-06)
### Bug Fixes
* add 17.25.34 as supported version for swipe-controls patch ([4d84c19](https://github.com/revanced/revanced-patches/commit/4d84c1914f8ecf51cee25667219bc6cf635a6c1c))
## [2.9.3](https://github.com/revanced/revanced-patches/compare/v2.9.2...v2.9.3) (2022-07-06)
### Bug Fixes
* Readd `swipe-controls` patch ([#123](https://github.com/revanced/revanced-patches/issues/123)) ([7f2a2b2](https://github.com/revanced/revanced-patches/commit/7f2a2b2ee4e6045d53aba4e7705431b643981107))
## [2.9.2](https://github.com/revanced/revanced-patches/compare/v2.9.1...v2.9.2) (2022-07-05)
### Bug Fixes
* revert `swipe-controls` patch ([66e1f33](https://github.com/revanced/revanced-patches/commit/66e1f3384a58361737ba889d946be875b23f3163))
## [2.9.1](https://github.com/revanced/revanced-patches/compare/v2.9.0...v2.9.1) (2022-07-05)
### Bug Fixes
* make `minimized-playback-manager-fingerprint` unique ([#120](https://github.com/revanced/revanced-patches/issues/120)) ([cd5e911](https://github.com/revanced/revanced-patches/commit/cd5e911f4ed9ad95b02c13c30cd9466d250e8904))
# [2.9.0](https://github.com/revanced/revanced-patches/compare/v2.8.2...v2.9.0) (2022-07-05)
### Features
* `swipe-controls` patch ([#115](https://github.com/revanced/revanced-patches/issues/115)) ([1d0a7dc](https://github.com/revanced/revanced-patches/commit/1d0a7dcc0cc3ea2bcd8ce0221d5e2f53d6eb0ae5))
## [2.8.2](https://github.com/revanced/revanced-patches/compare/v2.8.1...v2.8.2) (2022-07-05) ## [2.8.2](https://github.com/revanced/revanced-patches/compare/v2.8.1...v2.8.2) (2022-07-05)

View File

@@ -1 +1,2 @@
Repo for all ReVanced patches Repo for all ReVanced patches

View File

@@ -1,2 +1,2 @@
kotlin.code.style = official kotlin.code.style = official
version = 2.8.2 version = 2.10.0

View File

@@ -1,7 +1,18 @@
package app.revanced.extensions package app.revanced.extensions
import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.smali.toInstruction import app.revanced.patcher.util.smali.toInstruction
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.builder.MutableMethodImplementation import org.jf.dexlib2.builder.MutableMethodImplementation
import org.jf.dexlib2.builder.instruction.BuilderInstruction11n
import org.jf.dexlib2.builder.instruction.BuilderInstruction11x
import org.jf.dexlib2.builder.instruction.BuilderInstruction21t
import org.jf.dexlib2.builder.instruction.BuilderInstruction35c
import org.jf.dexlib2.immutable.reference.ImmutableMethodReference
import org.w3c.dom.Node import org.w3c.dom.Node
internal fun MutableMethodImplementation.injectHideCall( internal fun MutableMethodImplementation.injectHideCall(
@@ -14,6 +25,115 @@ internal fun MutableMethodImplementation.injectHideCall(
) )
} }
/**
* Insert an event hook at the top of the method. If the hook returns true, the event is consumed and the method will return with true
*
* the hook method MUST return a boolean and MUST take two parameters, like so:
* fun hook(thisRef: Object, eventData: Object): Boolean {}
*
* The final injected code will resemble the following logic:
* if( YouHook(this, event) ) { return true; }
* ...
*
* @param hookRef reference to the hook method
*/
internal fun MutableMethod.injectConsumableEventHook(hookRef: ImmutableMethodReference) {
val isStaticMethod = AccessFlags.STATIC.isSet(this.accessFlags)
this.implementation?.let { impl ->
// create label to index 0 to continue to the normal program flow
val lblContinueNormalFlow = impl.newLabelForIndex(0)
// define registers
/** V0 */
val regV0 = 0
/** this */
val regP0 = impl.registerCount - this.parameters.size - (if (isStaticMethod) 0 else 1)
/** motionEvent */
val regP1 = regP0 + 1
// insert instructions at the start of the method:
// if( Hook(this, event) ) { return true; }
impl.addInstructions(
0, listOf(
// invoke-static { p0, p1 } <hook>
BuilderInstruction35c(
Opcode.INVOKE_STATIC,
2,
regP0,
regP1,
0, 0, 0,
hookRef
),
// move-result v0
BuilderInstruction11x(
Opcode.MOVE_RESULT,
regV0
),
// if-eqz v0, :continue_normal_flow
BuilderInstruction21t(
Opcode.IF_EQZ,
regV0,
lblContinueNormalFlow
),
// const/4 v0, 0x1
BuilderInstruction11n(
Opcode.CONST_4,
regV0,
0x1
),
// return v0
BuilderInstruction11x(
Opcode.RETURN,
regV0
)
// :continue_normal_flow
)
)
}
}
/**
* Insert instructions into a named method
*
* @param targetClass the name of the class of which the method is a member
* @param targetMethod the name of the method to insert into
* @param index index to insert the instructions at. If the index is negative, it is used as an offset to the last method (so -1 inserts at the end of the method)
* @param instructions the smali instructions to insert (they'll be compiled by MutableMethod.addInstructions)
*/
internal fun BytecodeData.injectIntoNamedMethod(
targetClass: String,
targetMethod: String,
index: Int,
instructions: String
) {
var injections = 0
this.classes.filter { it.type.endsWith("$targetClass;") }.forEach { classDef ->
this.proxy(classDef).resolve().methods.filter { it.name == targetMethod }.forEach { methodDef ->
// if index is negative, interpret as an offset from the back
var insertIndex = index
if (insertIndex < 0) {
insertIndex += methodDef.implementation!!.instructions.size
}
// insert instructions
methodDef.addInstructions(insertIndex, instructions)
injections++
}
}
// fail if nothing was injected
if (injections <= 0) {
throw PatchResultError("failed to inject into $targetClass.$targetMethod: no targets were found")
}
}
internal fun Node.doRecursively(action: (Node) -> Unit) { internal fun Node.doRecursively(action: (Node) -> Unit) {
action(this) action(this)
for (i in 0 until this.childNodes.length) this.childNodes.item(i).doRecursively(action) for (i in 0 until this.childNodes.length) this.childNodes.item(i).doRecursively(action)

View File

@@ -0,0 +1,13 @@
package app.revanced.patches.youtube.interaction.fenster.annotation
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.youtube", arrayOf("17.24.34", "17.25.34")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class FensterCompatibility

View File

@@ -0,0 +1,45 @@
package app.revanced.patches.youtube.interaction.fenster.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.interaction.fenster.annotation.FensterCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("update-player-type-fingerprint")
@MatchingMethod(
"LYoutubePlayerOverlaysLayout;",
"nM"
)
@FuzzyPatternScanMethod(2)
@FensterCompatibility
@Version("0.0.1")
object UpdatePlayerTypeFingerprint : MethodFingerprint(
"V",
AccessFlags.PUBLIC or AccessFlags.FINAL,
null,
listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.IF_NE,
Opcode.RETURN_VOID,
Opcode.IPUT_OBJECT,
Opcode.INVOKE_DIRECT,
Opcode.INVOKE_VIRTUAL,
Opcode.INVOKE_VIRTUAL,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ,
Opcode.CONST_4,
Opcode.INVOKE_STATIC,
Opcode.RETURN_VOID,
Opcode.CONST_4,
Opcode.INVOKE_STATIC,
Opcode.INVOKE_VIRTUAL,
Opcode.RETURN_VOID
)
)

View File

@@ -0,0 +1,121 @@
package app.revanced.patches.youtube.interaction.fenster.patch
import app.revanced.extensions.injectConsumableEventHook
import app.revanced.extensions.injectIntoNamedMethod
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.interaction.fenster.annotation.FensterCompatibility
import app.revanced.patches.youtube.interaction.fenster.fingerprints.UpdatePlayerTypeFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import org.jf.dexlib2.immutable.reference.ImmutableMethodReference
@Patch
@Name("fenster-swipe-controls")
@Description("volume and brightness swipe controls")
@FensterCompatibility
@Version("0.0.1")
@Dependencies(dependencies = [IntegrationsPatch::class])
class FensterPatch : BytecodePatch(
listOf(
UpdatePlayerTypeFingerprint
)
) {
override fun execute(data: BytecodeData): PatchResult {
// hook WatchWhileActivity.onStart (main activity lifecycle hook)
data.injectIntoNamedMethod(
"com/google/android/apps/youtube/app/watchwhile/WatchWhileActivity",
"onStart",
0,
"invoke-static { p0 }, Lapp/revanced/integrations/patches/FensterSwipePatch;->WatchWhileActivity_onStartHookEX(Ljava/lang/Object;)V"
)
// hook YoutubePlayerOverlaysLayout.onFinishInflate (player overlays init hook)
data.injectIntoNamedMethod(
"com/google/android/apps/youtube/app/common/player/overlay/YouTubePlayerOverlaysLayout",
"onFinishInflate",
-2,
"invoke-static { p0 }, Lapp/revanced/integrations/patches/FensterSwipePatch;->YouTubePlayerOverlaysLayout_onFinishInflateHookEX(Ljava/lang/Object;)V"
)
// hook YoutubePlayerOverlaysLayout.UpdatePlayerType
injectUpdatePlayerTypeHook(
UpdatePlayerTypeFingerprint.result!!,
"com/google/android/apps/youtube/app/common/player/overlay/YouTubePlayerOverlaysLayout"
)
// hook NextGenWatchLayout.onTouchEvent and NextGenWatchLayout.onInterceptTouchEvent (player touch event hook)
injectWatchLayoutTouchHooks(
data,
"com/google/android/apps/youtube/app/watch/nextgenwatch/ui/NextGenWatchLayout"
)
return PatchResultSuccess()
}
@Suppress("SameParameterValue")
private fun injectUpdatePlayerTypeHook(fingerPrintResult: MethodFingerprintResult, targetClass: String) {
// validate fingerprint found the right class
if (!fingerPrintResult.classDef.type.endsWith("$targetClass;")) {
throw PatchResultError("$targetClass.UpdatePlayerType fingerprint could not be validated")
}
// insert the hook
fingerPrintResult.mutableMethod.addInstruction(
0,
"invoke-static { p1 }, Lapp/revanced/integrations/patches/FensterSwipePatch;->YouTubePlayerOverlaysLayout_updatePlayerTypeHookEX(Ljava/lang/Object;)V"
)
}
/**
* Inject onTouch event hooks into the watch layout class
*
* @param data bytecode data
* @param targetClass watch layout class name
*/
@Suppress("SameParameterValue")
private fun injectWatchLayoutTouchHooks(data: BytecodeData, targetClass: String) {
var touchHooksCount = 0
data.classes.filter { it.type.endsWith("$targetClass;") }.forEach { classDef ->
// hook onTouchEvent
data.proxy(classDef).resolve().methods.filter { it.name == "onTouchEvent" }.forEach { methodDef ->
touchHooksCount++
methodDef.injectConsumableEventHook(
ImmutableMethodReference(
"Lapp/revanced/integrations/patches/FensterSwipePatch;",
"NextGenWatchLayout_onTouchEventHookEX",
listOf("Ljava/lang/Object;", "Ljava/lang/Object;"),
"Z"
)
)
}
// hook onInterceptTouchEvent
data.proxy(classDef).resolve().methods.filter { it.name == "onInterceptTouchEvent" }.forEach { methodDef ->
touchHooksCount++
methodDef.injectConsumableEventHook(
ImmutableMethodReference(
"Lapp/revanced/integrations/patches/FensterSwipePatch;",
"NextGenWatchLayout_onInterceptTouchEventHookEX",
listOf("Ljava/lang/Object;", "Ljava/lang/Object;"),
"Z"
)
)
}
}
// fail if no touch hooks were inserted
if (touchHooksCount <= 0) {
throw PatchResultError("failed to inject onTouchEvent hook into NextGenWatchLayout: none found")
}
}
}

View File

@@ -29,12 +29,9 @@ object MinimizedPlaybackSettingsFingerprint : MethodFingerprint(
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT, Opcode.MOVE_RESULT,
Opcode.IF_EQZ, Opcode.IF_EQZ,
Opcode.IF_NEZ,
Opcode.GOTO,
Opcode.IGET_OBJECT,
Opcode.CHECK_CAST
), ),
customFingerprint = {
it.implementation!!.instructions.any {
(it as? WideLiteralInstruction)?.wideLiteral == resourceId
}
}
) )
val resourceId = ResourceIdMappingProviderResourcePatch.resourceMappings.first { it.type == "string" && it.name == "pref_background_category" }.id

View File

@@ -8,7 +8,6 @@ import app.revanced.patcher.data.impl.toMethodWalker
import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
@@ -21,7 +20,6 @@ import org.jf.dexlib2.iface.reference.MethodReference
@Patch @Patch
@Dependencies(dependencies = [ResourceIdMappingProviderResourcePatch::class])
@Name("minimized-playback") @Name("minimized-playback")
@Description("Enable minimized and background playback.") @Description("Enable minimized and background playback.")
@MinimizedPlaybackCompatibility @MinimizedPlaybackCompatibility

View File

@@ -0,0 +1,13 @@
package app.revanced.patches.youtube.layout.widesearchbar.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.youtube", arrayOf("17.25.34")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class WideSearchbarCompatibility

View File

@@ -0,0 +1,47 @@
package app.revanced.patches.youtube.layout.widesearchbar.fingerprints.methodone
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.reels.annotations.HideReelsCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("wide-searchbar-methodone-fingerprint")
@MatchingMethod(
"Ljkg;", "i"
)
@DirectPatternScanMethod
@HideReelsCompatibility
@Version("0.0.1")
/*
This finds the following method:
public final View i(akrl akrlVar, adpd adpdVar) {
}
Method we search for is located in smali now.
See:
.method public final i(Lakrl;Ladpd;)Landroid/view/View;
iget-object v0, p0, Ljkg;->a:Landroid/app/Activity;
invoke-static {v0}, Landroid/view/LayoutInflater;->from(Landroid/content/Context;)Landroid/view/LayoutInflater;
move-result-object v0
iget-object v1, p0, Ljkg;->g:Ljis;
const/4 v2, 0x0
invoke-interface {v1, v2}, Ljis;->h(Z)V
iget-object p1, p1, Lakrl;->f:Lahnq;
if-nez p1, :cond_12
sget-object p1, Lahnq;->a:Lahnq;
:cond_12
iget-object v1, p0, Ljkg;->x:Ltxm;
invoke-static {v1}, Lfbn;->aF(Ltxm;)Z //THIS IS WHAT WE SEARCH FOR (Method fbn.aF)
move-result v1
*/
object WideSearchbarOneFingerprint : MethodFingerprint(
"L", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L", "L"), listOf(Opcode.IF_NEZ, Opcode.SGET_OBJECT, Opcode.IGET_OBJECT, Opcode.INVOKE_STATIC),
null, null
)

View File

@@ -0,0 +1,46 @@
package app.revanced.patches.youtube.layout.widesearchbar.fingerprints.methodone
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.youtube.layout.reels.annotations.HideReelsCompatibility
import org.jf.dexlib2.AccessFlags
@Name("wide-searchbar-methodone-parent-fingerprint")
@MatchingMethod(
"Ljkg;", "l"
)
@FuzzyPatternScanMethod(3)
@HideReelsCompatibility
@Version("0.0.1")
/*
* This finds the following method:
private final void l(PaneDescriptor paneDescriptor) {
Class cls = null;
ahat f = paneDescriptor != null ? paneDescriptor.f() : null;
if (paneDescriptor != null) {
cls = paneDescriptor.a;
}
ftu k = k();
if ((k == null || !k.bk()) && ((!frx.k(f) && !((Boolean) aqer.S(this.n).X(new fac(this, f, 19)).K(irx.i).aH(false)).booleanValue()) || (f != null && f.qA(ReelWatchEndpointOuterClass$ReelWatchEndpoint.reelWatchEndpoint)))) {
String j = frx.j(f);
if ((j != null && ("FEhistory".equals(j) || "FEmy_videos".equals(j) || "FEpurchases".equals(j) || j.startsWith("VL"))) || cls == this.I.E() || cls == this.G.a) {
this.F = 3;
return;
} else {
this.F = 2;
return;
}
}
this.F = 1;
}
*/
object WideSearchbarOneParentFingerprint : MethodFingerprint(
"V", AccessFlags.PRIVATE or AccessFlags.FINAL, listOf("L"), null,
listOf("FEhistory", "FEmy_videos", "FEpurchases")
)

View File

@@ -0,0 +1,48 @@
package app.revanced.patches.youtube.layout.widesearchbar.fingerprints.methodtwo
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.reels.annotations.HideReelsCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("wide-searchbar-methodtwo-fingerprint")
@MatchingMethod(
"Lkrf;", "h"
)
@DirectPatternScanMethod
@HideReelsCompatibility
@Version("0.0.1")
/*
public static jis h(Context context, txm txmVar, uag uagVar, txp txpVar) {
return fbn.aB(txmVar) ? new jhx(context, txmVar, uagVar, txpVar) : jis.d;
}
Method we search for is located in smali now.
See:
.method public static h(Landroid/content/Context;Ltxm;Luag;Ltxp;)Ljis;
invoke-static {p1}, Lfbn;->aB(Ltxm;)Z //this is the method we want to change. fbn.aB
move-result v0
if-eqz v0, :cond_c
new-instance v0, Ljhx;
invoke-direct {v0, p0, p1, p2, p3}, Ljhx;-><init>(Landroid/content/Context;Ltxm;Luag;Ltxp;)V
goto :goto_e
:cond_c
sget-object v0, Ljis;->d:Ljis;
:goto_e
return-object v0
.end method
*/
object WideSearchbarTwoFingerprint : MethodFingerprint(
"L", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L", "L", "L", "L"), listOf(
Opcode.INVOKE_STATIC, Opcode.MOVE_RESULT, Opcode.IF_EQZ, Opcode.NEW_INSTANCE
),
null, null
)

View File

@@ -0,0 +1,34 @@
package app.revanced.patches.youtube.layout.widesearchbar.fingerprints.methodtwo
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.youtube.layout.reels.annotations.HideReelsCompatibility
import org.jf.dexlib2.AccessFlags
@Name("wide-searchbar-methodtwo-parent-fingerprint")
@MatchingMethod(
"Lkrf;", "i"
)
@FuzzyPatternScanMethod(3)
@HideReelsCompatibility
@Version("0.0.1")
/*
This finds following method:
public static ies i(br brVar) {
bp f = brVar.getSupportFragmentManager().f("VIDEO_QUALITIES_QUICK_MENU_BOTTOM_SHEET_FRAGMENT");
if (f != null) {
return (kga) f;
}
return new kga();
}
*/
object WideSearchbarTwoParentFingerprint : MethodFingerprint(
"L", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L"), null,
listOf("VIDEO_QUALITIES_QUICK_MENU_BOTTOM_SHEET_FRAGMENT")
)

View File

@@ -0,0 +1,105 @@
package app.revanced.patches.youtube.layout.widesearchbar.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.data.impl.toMethodWalker
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.youtube.layout.widesearchbar.annotations.WideSearchbarCompatibility
import app.revanced.patches.youtube.layout.widesearchbar.fingerprints.methodone.WideSearchbarOneFingerprint
import app.revanced.patches.youtube.layout.widesearchbar.fingerprints.methodone.WideSearchbarOneParentFingerprint
import app.revanced.patches.youtube.layout.widesearchbar.fingerprints.methodtwo.WideSearchbarTwoFingerprint
import app.revanced.patches.youtube.layout.widesearchbar.fingerprints.methodtwo.WideSearchbarTwoParentFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
@Patch(include = false)
@Dependencies(dependencies = [IntegrationsPatch::class])
@Name("enable-wide-searchbar")
@Description("Replaces the search-icon with a wide searchbar. This will hide the youtube logo when this is active.")
@WideSearchbarCompatibility
@Version("0.0.1")
class WideSearchbarPatch : BytecodePatch(
listOf(
WideSearchbarOneParentFingerprint, WideSearchbarTwoParentFingerprint
)
) {
override fun execute(data: BytecodeData): PatchResult {
WideSearchbarOneFingerprint.resolve(data, WideSearchbarOneParentFingerprint.result!!.classDef)
WideSearchbarTwoFingerprint.resolve(data, WideSearchbarTwoParentFingerprint.result!!.classDef)
val resultOne = WideSearchbarOneFingerprint.result
//This should be the method aF in class fbn
val targetMethodOne =
data.toMethodWalker(resultOne!!.method).nextMethod(resultOne!!.patternScanResult!!.endIndex, true).getMethod() as MutableMethod
//Since both methods have the same smali code, inject instructions using a method.
addInstructions(targetMethodOne)
val resultTwo = WideSearchbarTwoFingerprint.result
//This should be the method aB in class fbn
val targetMethodTwo =
data.toMethodWalker(resultTwo!!.method).nextMethod(resultTwo!!.patternScanResult!!.startIndex, true).getMethod() as MutableMethod
//Since both methods have the same smali code, inject instructions using a method.
addInstructions(targetMethodTwo)
return PatchResultSuccess()
}
private fun addInstructions(method: MutableMethod) {
val index = method.implementation!!.instructions.size - 1
method.addInstructions(
index, """
invoke-static {}, Lapp/revanced/integrations/patches/NewActionbarPatch;->getNewActionBar()Z
move-result p0
"""
)
}
//targetMethodOne: in class fbn
/*
.method public static aF(Ltxm;)Z
invoke-virtual {p0}, Ltxm;->b()Lahah;
move-result-object p0
iget-object p0, p0, Lahah;->e:Lakfd;
if-nez p0, :cond_a
sget-object p0, Lakfd;->a:Lakfd;
:cond_a
iget-boolean p0, p0, Lakfd;->V:Z
//added code here:
invoke-static {}, app/revanced/integrations/patches/NewActionbarPatch;->getNewActionBar()Z
move-result p0
//original code here:
return p0
.end method
*/
//targetMethodTwo: in class fbn
/*
.method public static aB(Ltxm;)Z
invoke-virtual {p0}, Ltxm;->b()Lahah;
move-result-object p0
iget-object p0, p0, Lahah;->e:Lakfd;
if-nez p0, :cond_a
sget-object p0, Lakfd;->a:Lakfd;
:cond_a
iget-boolean p0, p0, Lakfd;->y:Z
//added code here:
invoke-static {}, app/revanced/integrations/patches/NewActionbarPatch;->getNewActionBar()Z
move-result p0
//original code here:
return p0
.end method
*/
}