From d170489b106dab05aea7a3e3d7d641f57f02e4c1 Mon Sep 17 00:00:00 2001 From: ACh Sulfate Date: Mon, 24 Jul 2023 20:03:10 +0800 Subject: [PATCH] fix: FileShareExtHook on NT 4288 --- .../cc/ioctl/hook/msg/FileShareExtHook.java | 59 +++++++++++++++---- .../github/qauxv/util/dexkit/DexKitTarget.kt | 14 +++++ 2 files changed, 62 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/cc/ioctl/hook/msg/FileShareExtHook.java b/app/src/main/java/cc/ioctl/hook/msg/FileShareExtHook.java index 8ede3a02f3..eec08b9cdd 100644 --- a/app/src/main/java/cc/ioctl/hook/msg/FileShareExtHook.java +++ b/app/src/main/java/cc/ioctl/hook/msg/FileShareExtHook.java @@ -49,11 +49,17 @@ import io.github.qauxv.util.Log; import io.github.qauxv.util.SyncUtils; import io.github.qauxv.util.Toasts; +import io.github.qauxv.util.dexkit.DefaultFileModel; +import io.github.qauxv.util.dexkit.DexKit; +import io.github.qauxv.util.dexkit.DexKitTarget; +import io.github.qauxv.util.dexkit.FileBrowserActivity_InnerClass_onItemClick; import java.io.File; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.List; +import kotlin.collections.ArraysKt; @FunctionHookEntry @UiItemAgentEntry @@ -62,7 +68,10 @@ public class FileShareExtHook extends CommonSwitchFunctionHook { public static final FileShareExtHook INSTANCE = new FileShareExtHook(); private FileShareExtHook() { - super(SyncUtils.PROC_MAIN); + super(SyncUtils.PROC_MAIN, new DexKitTarget[]{ + FileBrowserActivity_InnerClass_onItemClick.INSTANCE, + DefaultFileModel.INSTANCE + }); } @NonNull @@ -98,11 +107,7 @@ protected boolean initOnce() throws Exception { Class kiShareActionSheet = Initiator.loadClass("com.tencent.mobileqq.widget.share.ShareActionSheet"); // args Class kFileBrowserModelBase = Initiator.loadClass("com.tencent.mobileqq.filemanager.fileviewer.model.FileBrowserModelBase"); - Class kDefaultFileModel = Initiator.loadClassEither( - "com.tencent.mobileqq.filemanager.fileviewer.model.DefaultFileModel", - // QQ 8.9.0(3060) - "com.tencent.mobileqq.filemanager.fileviewer.model.b" - ); + Class kDefaultFileModel = DexKit.requireClassFromCache(DefaultFileModel.INSTANCE); Class kIFileViewerAdapter = Initiator.loadClassEither( "com.tencent.mobileqq.filemanager.fileviewer.IFileViewerAdapter", // QQ 8.9.0(3060) @@ -118,20 +123,32 @@ protected boolean initOnce() throws Exception { fieldDefaultFileModel_IFileViewerAdapter.setAccessible(true); fieldFileBrowserManager_FileBrowserModelBase.setAccessible(true); Method getFilePath = kIFileViewerAdapter.getDeclaredMethod("getFilePath"); - Method getShareSheetItemLists = Reflex.findSingleMethod(kFileBrowserManager, ArrayList[].class, false); + Method getShareSheetItemLists1 = Reflex.findSingleMethod(kFileBrowserManager, ArrayList[].class, false); + List getShareSheetItemLists2List = ArraysKt.filter(kDefaultFileModel.getDeclaredMethods(), it -> { + return it.getParameterTypes().length == 0 && it.getReturnType() == ArrayList[].class; + }); Method onItemClick = Initiator.loadClassEither( "com.tencent.mobileqq.filemanager.fileviewer.FileBrowserManager$2", // QQ 8.9.0(3060) "com.tencent.mobileqq.filemanager.fileviewer.a$b" ).getDeclaredMethod("onItemClick", kActionSheetItem, kiShareActionSheet); XposedBridge.hookMethod(onItemClick, mItemClickHandler); - HookUtils.hookAfterIfEnabled(this, getShareSheetItemLists, param -> { + Method mFileBrowserActivity_InnerClass_onItemClick = DexKit.loadMethodFromCache(FileBrowserActivity_InnerClass_onItemClick.INSTANCE); + if (mFileBrowserActivity_InnerClass_onItemClick != null) { + XposedBridge.hookMethod(mFileBrowserActivity_InnerClass_onItemClick, mItemClickHandler); + } + XC_MethodHook getShareSheetItemListsHook = HookUtils.afterIfEnabled(this, param -> { ArrayList[] results = (ArrayList[]) param.getResult(); if (results == null || results.length != 2) { Log.e("FileShareExtHook: getShareSheetItemLists result is null or length is not 2"); return; } - Object fileBrowserModel = fieldFileBrowserManager_FileBrowserModelBase.get(param.thisObject); + Object fileBrowserModel; + if (kFileBrowserManager.isInstance(param.thisObject)) { + fileBrowserModel = fieldFileBrowserManager_FileBrowserModelBase.get(param.thisObject); + } else { + fileBrowserModel = kFileBrowserModelBase.cast(param.thisObject); + } if (fileBrowserModel == null) { return; } @@ -154,6 +171,10 @@ protected boolean initOnce() throws Exception { Reflex.setInstanceObject(item, "argus", String.class, filePath); row2.add(item); }); + XposedBridge.hookMethod(getShareSheetItemLists1, getShareSheetItemListsHook); + for (Method method : getShareSheetItemLists2List) { + XposedBridge.hookMethod(method, getShareSheetItemListsHook); + } return true; } @@ -161,8 +182,24 @@ protected boolean initOnce() throws Exception { Object item = param.args[0]; int id = (int) Reflex.getInstanceObject(item, "id", int.class); if (id == R.id.ShareActionSheet_shareFileWithExtApp) { - Object fileBrowserManager = Reflex.getFirstByType(param.thisObject, kFileBrowserManager); - Context ctx = Reflex.getFirstByType(fileBrowserManager, Activity.class); + Context ctx = null; + // case 1 + Object fileBrowserManager = Reflex.getFirstByTypeOrNull(param.thisObject, kFileBrowserManager); + if (fileBrowserManager != null) { + ctx = Reflex.getFirstByType(fileBrowserManager, Activity.class); + } + // case 2 + Class kFileBrowserActivity = Initiator.load("com.tencent.mobileqq.filebrowser.FileBrowserActivity"); + if (kFileBrowserActivity != null) { + Activity activity = (Activity) Reflex.getFirstByTypeOrNull(param.thisObject, kFileBrowserActivity); + if (activity != null) { + ctx = activity; + } + } + if (ctx == null) { + Toasts.error(null, "unable to get activity"); + return; + } assert ctx != null; String picPath = (String) Reflex.getInstanceObject(item, "argus", String.class); if (TextUtils.isEmpty(picPath)) { diff --git a/app/src/main/java/io/github/qauxv/util/dexkit/DexKitTarget.kt b/app/src/main/java/io/github/qauxv/util/dexkit/DexKitTarget.kt index 9baca3fa8a..3c68bb4c24 100644 --- a/app/src/main/java/io/github/qauxv/util/dexkit/DexKitTarget.kt +++ b/app/src/main/java/io/github/qauxv/util/dexkit/DexKitTarget.kt @@ -749,3 +749,17 @@ data object NQZMoment_EntranceEnabled : DexKitTarget.UsingStr() { override val declaringClass = "" override val filter = DexKitFilter.strInClsName("com/qzone/reborn/qzmoment/util") } + +data object DefaultFileModel : DexKitTarget.UsingStr() { + override val findMethod: Boolean = false + override val traitString = arrayOf("onVideoPlayerError : file entity is null") + override val declaringClass = "com.tencent.mobileqq.filemanager.fileviewer.model.DefaultFileModel" + override val filter = DexKitFilter.strInClsName("com.tencent.mobileqq.filemanager.fileviewer.model") +} + +data object FileBrowserActivity_InnerClass_onItemClick : DexKitTarget.UsingStringVector() { + override val findMethod: Boolean = true + override val traitStringVectors: Array> = arrayOf(arrayOf("GeneralFileBrowserActivity", "reportShareActionSheetClick")) + override val declaringClass = "" + override val filter = DexKitFilter.strInClsName("FileBrowserActivity") +}