diff --git a/app/build.gradle b/app/build.gradle index 459ed25..ebdce92 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -67,8 +67,8 @@ android { applicationId "com.lu.wxmask" minSdk 24 targetSdk 34 - versionCode 22 - versionName "1.21-bug" + versionCode 23 + versionName "1.22-bug" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/java/com/lu/wxmask/Constrant.kt b/app/src/main/java/com/lu/wxmask/Constrant.kt index c9dd267..453146a 100644 --- a/app/src/main/java/com/lu/wxmask/Constrant.kt +++ b/app/src/main/java/com/lu/wxmask/Constrant.kt @@ -3,6 +3,7 @@ package com.lu.wxmask class Constrant { companion object { const val ONE_YEAR_MILLS = 1000L * 60 * 60 * 24 * 365L + const val ONE_DAY_MILLS = 1000L * 60 * 60 * 24L //intent key, 标记来源是 Mask App const val KEY_INTENT_FROM_MASK = "KEY_INTENT_FROM_MASK" @@ -45,6 +46,7 @@ class Constrant { const val WX_CODE_8_0_41 = 2441 const val WX_CODE_8_0_42 = 2460 const val WX_CODE_8_0_43 = 2480 + const val WX_CODE_8_0_44 = 2502 } } \ No newline at end of file diff --git a/app/src/main/java/com/lu/wxmask/plugin/CommonPlugin.kt b/app/src/main/java/com/lu/wxmask/plugin/CommonPlugin.kt index 726e494..5144561 100644 --- a/app/src/main/java/com/lu/wxmask/plugin/CommonPlugin.kt +++ b/app/src/main/java/com/lu/wxmask/plugin/CommonPlugin.kt @@ -4,6 +4,8 @@ import android.content.Context import android.view.MotionEvent import android.view.View import android.view.ViewGroup +import android.widget.ListAdapter +import android.widget.ListView import com.lu.lposed.api2.XC_MethodHook2 import com.lu.lposed.api2.XposedHelpers2 import com.lu.lposed.plugin.IPlugin @@ -12,24 +14,31 @@ import com.lu.magic.util.view.ChildDeepCheck import com.lu.magic.util.view.SelfDeepCheck import com.lu.magic.util.view.ViewUtil import com.lu.wxmask.BuildConfig +import com.lu.wxmask.util.AppVersionUtil import de.robv.android.xposed.callbacks.XC_LoadPackage class CommonPlugin : IPlugin { - override fun handleHook(context: Context?, lpparam: XC_LoadPackage.LoadPackageParam?) { + override fun handleHook(context: Context, lpparam: XC_LoadPackage.LoadPackageParam) { // if (!BuildConfig.DEBUG) { // return // } -// XposedHelpers2.findAndHookMethod( -// View::class.java, -// "onTouchEvent", -// MotionEvent::class.java, +// LogUtil.w("WeChat MainUI not found Adapter for ListView, guess start.") +// val setAdapterMethod = XposedHelpers2.findMethodExactIfExists( +// ListView::class.java.name, +// context.classLoader, +// "setAdapter", +// ListAdapter::class.java +// ) +// if (setAdapterMethod == null) { +// LogUtil.w( "setAdapterMethod is null") +// return +// } +// XposedHelpers2.hookMethod( +// setAdapterMethod, // object : XC_MethodHook2() { -// override fun beforeHookedMethod(param: MethodHookParam) { -// val view = param.thisObject -// LogUtil.w("touch view is ", view) -// ChildDeepCheck().each(view as View?) { child -> -// LogUtil.w("---> child is ", child) -// } +// override fun afterHookedMethod(param: MethodHookParam) { +// val adapter = param.args[0] ?: return +// LogUtil.i("hook List adapter ", adapter) // } // } // ) diff --git a/app/src/main/java/com/lu/wxmask/plugin/part/EmptySingChatHistoryGalleryPluginPart.kt b/app/src/main/java/com/lu/wxmask/plugin/part/EmptySingChatHistoryGalleryPluginPart.kt index e6ed65a..b216ffe 100644 --- a/app/src/main/java/com/lu/wxmask/plugin/part/EmptySingChatHistoryGalleryPluginPart.kt +++ b/app/src/main/java/com/lu/wxmask/plugin/part/EmptySingChatHistoryGalleryPluginPart.kt @@ -4,8 +4,13 @@ import android.app.Activity import android.content.Context import android.os.Bundle import android.view.LayoutInflater +import android.view.View import android.view.ViewGroup +import android.widget.TextView +import androidx.core.view.isVisible +import androidx.core.view.postDelayed import com.lu.lposed.api2.XC_MethodHook2 +import com.lu.lposed.api2.XC_MethodReplacement2 import com.lu.lposed.api2.XposedHelpers2 import com.lu.lposed.plugin.IPlugin import com.lu.magic.util.log.LogUtil @@ -21,6 +26,7 @@ import java.lang.reflect.Method * 置空单聊页面菜单的“查找聊天记录”搜索结果 */ class EmptySingChatHistoryGalleryPluginPart : IPlugin { + val MediaHistoryGalleryUI = "com.tencent.mm.ui.chatting.gallery.MediaHistoryGalleryUI" override fun handleHook(context: Context, lpparam: XC_LoadPackage.LoadPackageParam?) { setEmptyDetailHistoryUI(context, lpparam) setEmptyActionBarTabPageUI(context, lpparam) @@ -28,13 +34,14 @@ class EmptySingChatHistoryGalleryPluginPart : IPlugin { private fun setEmptyDetailHistoryUI(context: Context, lpparam: XC_LoadPackage.LoadPackageParam?) { setEmptyDetailHistoryUIForMedia(context, lpparam) - setEmptyDetailHistoryUIForGallery(context, lpparam) + setEmptyDetailHistoryUIForGalleryCompat(context, lpparam) } private fun setEmptyDetailHistoryUIForMedia(context: Context, lpparam: XC_LoadPackage.LoadPackageParam?) { var mediaMethodName = when (AppVersionUtil.getVersionCode()) { in Constrant.WX_CODE_8_0_32..Constrant.WX_CODE_8_0_35 -> "k" - in Constrant.WX_CODE_8_0_35..Constrant.WX_CODE_8_0_41 -> "l" + in Constrant.WX_CODE_8_0_35..Constrant.WX_CODE_8_0_43 -> "l" + in Constrant.WX_CODE_8_0_43..Constrant.WX_CODE_8_0_44 -> "z" else -> "l" } val MediaHistoryListUI = "com.tencent.mm.ui.chatting.gallery.MediaHistoryListUI" @@ -78,8 +85,20 @@ class EmptySingChatHistoryGalleryPluginPart : IPlugin { }) } + + /** + * 置空图片/视频搜索结果 + */ + private fun setEmptyDetailHistoryUIForGalleryCompat(context: Context, lpparam: XC_LoadPackage.LoadPackageParam?) { + if (AppVersionUtil.getVersionCode() > Constrant.WX_CODE_8_0_43) { + setEmptyDetailHistoryUIForGallery8044(context, lpparam) + return + } else { + setEmptyDetailHistoryUIForGallery(context, lpparam) + } + } + private fun setEmptyDetailHistoryUIForGallery(context: Context, lpparam: XC_LoadPackage.LoadPackageParam?) { - val MediaHistoryGalleryUI = "com.tencent.mm.ui.chatting.gallery.MediaHistoryGalleryUI" val methodName = when (AppVersionUtil.getVersionCode()) { in Constrant.WX_CODE_8_0_22..Constrant.WX_CODE_8_0_35 -> "k" in Constrant.WX_CODE_8_0_35..Constrant.WX_CODE_8_0_43 -> "l" @@ -107,7 +126,6 @@ class EmptySingChatHistoryGalleryPluginPart : IPlugin { } LogUtil.w(AppVersionUtil.getSmartVersionName(), "guess MediaHistoryGalleryUI empty method is ", galleryMethod) } - XposedHelpers2.hookMethod( galleryMethod, object : XC_MethodHook2() { @@ -125,6 +143,60 @@ class EmptySingChatHistoryGalleryPluginPart : IPlugin { } } }) + } + + private fun setEmptyDetailHistoryUIForGallery8044(context: Context, lpparam: XC_LoadPackage.LoadPackageParam?) { + //k1 run a1 -> a1 run z0 加载图片完成 + var methods = XposedHelpers2.findMethodsByExactParameters( + ClazzN.from("com.tencent.mm.ui.chatting.presenter.k1"), + Void.TYPE, + java.lang.Boolean.TYPE, + Integer.TYPE, + ) + if (methods.isNotEmpty()) { + XposedHelpers2.hookMethod(methods[0], + object : XC_MethodHook2() { + override fun beforeHookedMethod(param: MethodHookParam) { + super.beforeHookedMethod(param) +// val activity: Activity = param.thisObject as Activity + +// + + var fields = XposedHelpers2.findFieldsByExactPredicate(param.thisObject::class.java) { + var v = it.get(param.thisObject) + + if (v.javaClass.name.equals(MediaHistoryGalleryUI)) { + return@findFieldsByExactPredicate true + } + return@findFieldsByExactPredicate false + } + var activity: Activity? = null + if (!fields.isEmpty()) { + activity = fields[0].get(param.thisObject) as Activity + } + if (activity == null) { + LogUtil.w("can not find DetailHistoryUIForGallery8044") + return + } + val intent = activity.intent + val userName = intent.getStringExtra("kintent_talker") + if (userName.isNullOrBlank()) { + LogUtil.w("MediaHistoryListUI‘s user is empty", userName) + return + } + if (WXMaskPlugin.containChatUser(userName)) { + param.args[1] = 0 + LogUtil.i("empty MediaHistoryGalleryUI data") + } + param.args[0] = false +// XposedHelpers2.findFirstFieldByExactType(this::class.java) + } + } + ) + } else { + LogUtil.w("can not find presenter for setEmptyDetailHistoryUIForGallery8044") + + } } @@ -145,8 +217,9 @@ class EmptySingChatHistoryGalleryPluginPart : IPlugin { Constrant.WX_CODE_8_0_35 -> "P" Constrant.WX_CODE_8_0_37 -> "Q" Constrant.WX_CODE_8_0_38 -> "R" - in Constrant.WX_CODE_8_0_40..Constrant.WX_CODE_8_0_41, Constrant.WX_CODE_8_0_43-> "Q" - in Constrant.WX_CODE_8_0_41 .. Constrant.WX_CODE_8_0_42 -> "R" + Constrant.WX_CODE_8_0_44 -> "D" + in Constrant.WX_CODE_8_0_40..Constrant.WX_CODE_8_0_41, Constrant.WX_CODE_8_0_43 -> "Q" + in Constrant.WX_CODE_8_0_41..Constrant.WX_CODE_8_0_42 -> "R" else -> null } LogUtil.d("setEmptyActionBarTabPageUI method is :", commonHookMethodName) @@ -222,7 +295,7 @@ class EmptySingChatHistoryGalleryPluginPart : IPlugin { Bundle::class.java, object : XC_MethodHook2() { - override fun beforeHookedMethod(param: MethodHookParam) { + override fun afterHookedMethod(param: MethodHookParam) { debugLog(param) if (isHitMaskId(param.thisObject)) { val inflater = param.args[0] as LayoutInflater diff --git a/app/src/main/java/com/lu/wxmask/plugin/part/EnterChattingUIPluginPart.kt b/app/src/main/java/com/lu/wxmask/plugin/part/EnterChattingUIPluginPart.kt index 38ec88d..ae7a093 100644 --- a/app/src/main/java/com/lu/wxmask/plugin/part/EnterChattingUIPluginPart.kt +++ b/app/src/main/java/com/lu/wxmask/plugin/part/EnterChattingUIPluginPart.kt @@ -73,6 +73,7 @@ class EnterChattingUIPluginPart() : IPlugin { Constrant.WX_CODE_8_0_38 -> "M" in Constrant.WX_CODE_8_0_40..Constrant.WX_CODE_8_0_41 -> "K" in Constrant.WX_CODE_8_0_41..Constrant.WX_CODE_8_0_42 -> "M" + Constrant.WX_CODE_8_0_44 -> "z" else -> null } var dispatchMethod: Method? = null @@ -161,7 +162,7 @@ class EnterChattingHookAction( if (listView == null) { listView = runCatching { val mmListViewId = - if (AppVersionUtil.getVersionCode() in Constrant.WX_CODE_8_0_42..Constrant.WX_CODE_8_0_43) { + if (AppVersionUtil.getVersionCode() in Constrant.WX_CODE_8_0_42..Constrant.WX_CODE_8_0_44) { ResUtil.getViewId("bm6") } else { ResUtil.getViewId("b5n") diff --git a/app/src/main/java/com/lu/wxmask/plugin/part/HideMainUIListPluginPart.kt b/app/src/main/java/com/lu/wxmask/plugin/part/HideMainUIListPluginPart.kt index 67d7cd3..c9fe7bd 100644 --- a/app/src/main/java/com/lu/wxmask/plugin/part/HideMainUIListPluginPart.kt +++ b/app/src/main/java/com/lu/wxmask/plugin/part/HideMainUIListPluginPart.kt @@ -207,7 +207,8 @@ class HideMainUIListPluginPart : IPlugin { //listAdapter getItem方法被重命名了 var getItemMethodName = when (AppVersionUtil.getVersionCode()) { Constrant.WX_CODE_8_0_22 -> "aCW" - else -> "k" + in Constrant.WX_CODE_8_0_22 .. Constrant.WX_CODE_8_0_43 -> "k" + else -> "m" } //8.0.32-8.0.34 com.tencent.mm.ui.y //8.0.35-8.0.37  com.tencent.mm.ui.z @@ -217,6 +218,7 @@ class HideMainUIListPluginPart : IPlugin { in Constrant.WX_CODE_8_0_32..Constrant.WX_CODE_8_0_34 -> "com.tencent.mm.ui.y" in Constrant.WX_CODE_8_0_35..Constrant.WX_CODE_8_0_38 -> "com.tencent.mm.ui.z" in Constrant.WX_CODE_8_0_40..Constrant.WX_CODE_8_0_43 -> "com.tencent.mm.ui.b0" + in Constrant.WX_CODE_8_0_43 .. Constrant.WX_CODE_8_0_44 -> "com.tencent.mm.ui.h3" else -> null } var getItemMethod = if (adapterClazzName != null && getItemMethodName != null) { @@ -264,6 +266,8 @@ class HideMainUIListPluginPart : IPlugin { } private fun hookListViewGetItem(getItemMethod: Method) { + LogUtil.d(">>>>>>>>>>.", getItemMethod) + XposedHelpers2.hookMethod( getItemMethod, object : XC_MethodHook2() { diff --git a/app/src/main/java/com/lu/wxmask/plugin/part/HideSearchListUIPluginPart.kt b/app/src/main/java/com/lu/wxmask/plugin/part/HideSearchListUIPluginPart.kt index a4c3000..8f89517 100644 --- a/app/src/main/java/com/lu/wxmask/plugin/part/HideSearchListUIPluginPart.kt +++ b/app/src/main/java/com/lu/wxmask/plugin/part/HideSearchListUIPluginPart.kt @@ -2,10 +2,12 @@ package com.lu.wxmask.plugin.part import android.content.Context import android.util.LruCache +import android.util.SparseArray import com.lu.lposed.api2.XC_MethodHook2 import com.lu.lposed.api2.XposedHelpers2 import com.lu.lposed.plugin.IPlugin import com.lu.lposed.plugin.PluginProviders +import com.lu.magic.util.AppUtil import com.lu.magic.util.GsonUtil import com.lu.magic.util.ReflectUtil import com.lu.magic.util.log.LogUtil @@ -27,8 +29,31 @@ class HideSearchListUIPluginPart : IPlugin { private val jsonResultLruCache = LruCache(16) override fun handleHook(context: Context, lpparam: XC_LoadPackage.LoadPackageParam) { - handleGlobalSearch(context, lpparam) - handleDetailSearch(context, lpparam) +// handleGlobalSearch(context, lpparam) +// handleDetailSearch(context, lpparam) + + //hook getItem --> rename to h + XposedHelpers2.findAndHookMethod(" com.tencent.mm.plugin.fts.ui.a0", + context.classLoader, + "h", + java.lang.Integer.TYPE, + object : XC_MethodHook2(){ + override fun afterHookedMethod(param: MethodHookParam) { + super.afterHookedMethod(param) + if (needHideUserName2(param, param.result)) { + LogUtil.d(param.result) +// param.result = try { +// //将命中的用户数据抹除掉 +// param.result::class.java.newInstance() +// } catch (e: Throwable) { +// LogUtil.d("error new Instance, return null") +// null +// } + var f: SparseArray<*> = XposedHelpers2.getObjectField(param.thisObject, "f") + param.result = f.get(0) + } + } + }); // hook adapter getView,因视图复用容易出问题。存在某个item,需要滑动后才消失,原因暂时不明 // XposedHelpers2.findAndHookMethod(