Skip to content

Commit

Permalink
Merge pull request #41 from Mingyueyixi/v1.21/dev
Browse files Browse the repository at this point in the history
V1.21/dev
  • Loading branch information
Mingyueyixi authored Dec 10, 2023
2 parents 1eaab46 + bf55ece commit 47e4d9f
Show file tree
Hide file tree
Showing 12 changed files with 221 additions and 35 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ v1.13版本开始,默认隐藏App在桌面的图标。隐藏以后,打开模
8.0.40 (2420) 2023-07-20
8.0.40 (2420) 2023-07-20
8.0.41 (2441) 2023-09-06
8.0.42 (2460) 2023-09-22
8.0.43 (2480) 2023-11-06

**PS.**
- 仅支持上述版本,所有其他版本号以及32位版本未经测试,预计百分之九十九不可用
Expand Down Expand Up @@ -123,6 +125,14 @@ SHA1: BCCA3CCACE5F40184A42FEFB06190C7279024985
8.0.41(2441):[https://dldir1.qq.com/weixin/android/weixin8041android2441_arm64_1.apk](https://dldir1.qq.com/weixin/android/weixin8041android2441_arm64_1.apk)
SHA1: 51D3E1C9594723FE8A69B68780C4B561964C7718

8.0.42(2460):[https://dldir1.qq.com/weixin/android/weixin8042android2460_arm64.apk](https://dldir1.qq.com/weixin/android/weixin8042android2460_arm64.apk)
SHA1: 227E395C67A2C0B0BCC750E1A3C52F642B433441

8.0.43(2480):[https://dldir1.qq.com/weixin/android/weixin8043android2480_0x28002b35_arm64.apk](https://dldir1.qq.com/weixin/android/weixin8043android2480_0x28002b35_arm64.apk)
SHA1: C46C85AF05130EDABCDBA8D487A5373ECE4AE6D0



推荐适配的最后两个版本,因为其他版本,作者自己不再使用

**问题4:是否支持Google Play版本?**
Expand Down
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ android {
applicationId "com.lu.wxmask"
minSdk 24
targetSdk 34
versionCode 21
versionName "1.20-bug"
versionCode 22
versionName "1.21-bug"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

Expand Down
44 changes: 44 additions & 0 deletions app/src/main/java/com/lu/wxmask/App.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.lu.wxmask;

import android.app.Application;

import androidx.lifecycle.ViewModelStore;
import androidx.lifecycle.ViewModelStoreOwner;

import com.lu.wxmask.ui.JsonMenuManager;

import org.jetbrains.annotations.NotNull;

public final class App extends Application implements ViewModelStoreOwner {
public static final Companion Companion = new Companion();
public static App instance;

public void onCreate() {
super.onCreate();
Companion.setInstance(this);
JsonMenuManager.Companion.updateMenuListFromRemote(this);
}

@Override
public ViewModelStore getViewModelStore() {
return new ViewModelStore();
}

public static final class Companion {
private Companion() {
}

public final App getInstance() {
App app = instance;
if (app != null) {
return app;
}
return null;
}

public final void setInstance(@NotNull App app) {
instance = app;
}

}
}
21 changes: 0 additions & 21 deletions app/src/main/java/com/lu/wxmask/App.kt

This file was deleted.

5 changes: 5 additions & 0 deletions app/src/main/java/com/lu/wxmask/Constrant.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package com.lu.wxmask

class Constrant {
companion object {
const val ONE_YEAR_MILLS = 1000L * 60 * 60 * 24 * 365L

//intent key, 标记来源是 Mask App
const val KEY_INTENT_FROM_MASK = "KEY_INTENT_FROM_MASK"

Expand Down Expand Up @@ -33,13 +35,16 @@ class Constrant {
const val WX_CODE_8_0_32 = 2300
const val WX_CODE_8_0_33 = 2320
const val WX_CODE_8_0_34 = 2340

//不知道为毛8.0.35找到一个和版本号与8.0.34重复的版本
//const val WX_CODE_8_0_35 = 2340
const val WX_CODE_8_0_35 = 2360
const val WX_CODE_8_0_37 = 2380
const val WX_CODE_8_0_38 = 2400
const val WX_CODE_8_0_40 = 2420
const val WX_CODE_8_0_41 = 2441
const val WX_CODE_8_0_42 = 2460
const val WX_CODE_8_0_43 = 2480
}

}
2 changes: 1 addition & 1 deletion app/src/main/java/com/lu/wxmask/plugin/WXConfigPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ private void onEntryWechatUI(Activity activity, Intent intent) {
boolean isFromMaskPlugin = intent.getBooleanExtra(Constrant.KEY_INTENT_FROM_MASK, false);
pluginMode = intent.getIntExtra(Constrant.KEY_INTENT_PLUGIN_MODE, -1);
if (!isFromMaskPlugin) {
LogUtil.i("ignore not from mask");
LogUtil.d("ignore not from mask");
return;
}
if (!AppVersionUtil.isSupportWechat()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class EmptySingChatHistoryGalleryPluginPart : IPlugin {
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_41 -> "l"
in Constrant.WX_CODE_8_0_35..Constrant.WX_CODE_8_0_43 -> "l"
else -> null
}
var galleryMethod: Method? = null
Expand Down Expand Up @@ -145,7 +145,8 @@ 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 -> "Q"
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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class EnterChattingUIPluginPart() : IPlugin {
"onEnterBegin"
)
if (onEnterBeginMethod == null) {
LogUtil.i("onEnterBegin function == null, maybe change")
LogUtil.d("onEnterBegin function == null, maybe change")
} else {
//8.0.22
LogUtil.d("hook onEnterBegin")
Expand All @@ -69,9 +69,10 @@ class EnterChattingUIPluginPart() : IPlugin {
}

Constrant.WX_CODE_8_0_35 -> "J"
Constrant.WX_CODE_8_0_37 -> "K"
Constrant.WX_CODE_8_0_37, Constrant.WX_CODE_8_0_43 -> "K"
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"
else -> null
}
var dispatchMethod: Method? = null
Expand Down Expand Up @@ -159,7 +160,12 @@ class EnterChattingHookAction(
}.getOrNull()
if (listView == null) {
listView = runCatching {
val mmListViewId = ResUtil.getViewId("b5n")
val mmListViewId =
if (AppVersionUtil.getVersionCode() in Constrant.WX_CODE_8_0_42..Constrant.WX_CODE_8_0_43) {
ResUtil.getViewId("bm6")
} else {
ResUtil.getViewId("b5n")
}
XposedHelpers2.callMethod(fragmentObj, "findViewById", mmListViewId) as View
}.getOrNull()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class HideMainUIListPluginPart : IPlugin {
LogUtil.w("hide mainUI listview fail, try to old function.")
handleMainUIChattingListView(context, lpparam)
}

}

//隐藏指定用户的主页的消息
Expand Down Expand Up @@ -215,7 +216,7 @@ class HideMainUIListPluginPart : IPlugin {
Constrant.WX_CODE_8_0_22 -> "com.tencent.mm.ui.g"
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_41 -> "com.tencent.mm.ui.b0"
in Constrant.WX_CODE_8_0_40..Constrant.WX_CODE_8_0_43 -> "com.tencent.mm.ui.b0"
else -> null
}
var getItemMethod = if (adapterClazzName != null && getItemMethodName != null) {
Expand Down Expand Up @@ -276,6 +277,19 @@ class HideMainUIListPluginPart : IPlugin {
XposedHelpers2.setObjectField(itemData, "field_unReadCount", 0)
XposedHelpers2.setObjectField(itemData, "field_UnReadInvite", 0)
XposedHelpers2.setObjectField(itemData, "field_unReadMuteCount", 0)
//文本消息
XposedHelpers2.setObjectField(itemData, "field_msgType", "1")

// try {
// var cTime = XposedHelpers2.getObjectField<Long>(itemData, "field_conversationTime")
// if (cTime != null) {
// val cTime2 = cTime - Constrant.ONE_YEAR_MILLS
// XposedHelpers2.setObjectField(itemData, "field_flag", cTime2)
// XposedHelpers2.setObjectField(itemData, "field_conversationTime", cTime2)
// }
// } catch (e: Exception) {
// }

}

}
Expand All @@ -284,4 +298,5 @@ class HideMainUIListPluginPart : IPlugin {
)
}


}
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package com.lu.wxmask.plugin.part

import android.content.Context
import android.util.LruCache
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.GsonUtil
import com.lu.magic.util.ReflectUtil
import com.lu.magic.util.log.LogUtil
import com.lu.wxmask.BuildConfig
import com.lu.wxmask.Constrant
Expand All @@ -12,11 +16,16 @@ import com.lu.wxmask.util.AppVersionUtil
import com.lu.wxmask.util.dev.DebugUtil
import de.robv.android.xposed.XC_MethodHook
import de.robv.android.xposed.callbacks.XC_LoadPackage
import java.lang.reflect.Field
import java.sql.Ref

/**
* 隐藏搜索列表
*/
class HideSearchListUIPluginPart : IPlugin {
private val hideFieldInfoCache = HashMap<String, HashSet<Field>>()
private val jsonResultLruCache = LruCache<String, CharSequence>(16)

override fun handleHook(context: Context, lpparam: XC_LoadPackage.LoadPackageParam) {
handleGlobalSearch(context, lpparam)
handleDetailSearch(context, lpparam)
Expand Down Expand Up @@ -72,7 +81,7 @@ class HideSearchListUIPluginPart : IPlugin {

private fun handleDetailSearch(context: Context, lpparam: XC_LoadPackage.LoadPackageParam) {
var hookClazzName = when (AppVersionUtil.getVersionCode()) {
in Constrant.WX_CODE_8_0_38.. Constrant.WX_CODE_8_0_41 -> "com.tencent.mm.plugin.fts.ui.x"
in Constrant.WX_CODE_8_0_38..Constrant.WX_CODE_8_0_41 -> "com.tencent.mm.plugin.fts.ui.x"
else -> "com.tencent.mm.plugin.fts.ui.y"
}
//全局搜索详情置空
Expand All @@ -83,18 +92,19 @@ class HideSearchListUIPluginPart : IPlugin {
Integer.TYPE,
object : XC_MethodHook2() {
override fun afterHookedMethod(param: MethodHookParam) {
if (needHideUserName(param, param.result)) {
if (needHideUserName2(param, param.result)) {
LogUtil.d(param.result)
param.result = try {
//将命中的用户数据抹除掉
param.result::class.java.newInstance()
} catch (e: Throwable) {
LogUtil.w("error new Instance, return null")
LogUtil.d("error new Instance, return null")
null
}
}

}

}
)
}
Expand All @@ -103,7 +113,7 @@ class HideSearchListUIPluginPart : IPlugin {
// val wxVersionCode = AppVersionUtil.getVersionCode()
// 理论上 hook com.tencent.mm.plugin.fts.ui.z#getItem 也是一样的,但是被覆盖重命名了
var hookClazzName = when (AppVersionUtil.getVersionCode()) {
in Constrant.WX_CODE_8_0_38 .. Constrant.WX_CODE_8_0_41 -> "com.tencent.mm.plugin.fts.ui.y"
in Constrant.WX_CODE_8_0_38..Constrant.WX_CODE_8_0_43 -> "com.tencent.mm.plugin.fts.ui.y"
else -> "com.tencent.mm.plugin.fts.ui.z"
}
//全局搜索首页
Expand Down Expand Up @@ -222,4 +232,89 @@ class HideSearchListUIPluginPart : IPlugin {

}


private fun needHideUserName2(param: XC_MethodHook.MethodHookParam, itemData: Any?): Boolean {
if (itemData == null) {
return false
}
var clazz: Class<*>? = itemData.javaClass ?: return false
if (hideFieldInfoCache[clazz!!.name] != null) {
for (field in hideFieldInfoCache[clazz.name]!!) {
if (checkFieldNeedHide(itemData, field)) {
LogUtil.d("hide field from cache: ", field.type.name, field.name, field.get(itemData))
return true
}
}
return false
}
while (clazz != null) {
for (field in clazz.declaredFields) {
field.isAccessible = true
try {
if (checkFieldNeedHide(itemData, field)) {
LogUtil.d("hide field: ", field.type.name, field.name, field.get(itemData))
return true
}
} catch (e: Exception) {
continue
}
}
clazz = try {
clazz.superclass
} catch (e: Exception) {
break
}
}
return false
}

private fun checkFieldNeedHide(itemData: Any, field: Field): Boolean {
var fieldValue: Any? = field.get(itemData) ?: return false
var clazzName = field.type.name
if (field.type.isAssignableFrom(Number::class.java)
|| field.type.isAssignableFrom(Byte::class.java)
|| clazzName.startsWith("android")
) {
return false
}

var jsonKey = fieldValue.toString().hashCode().toString()

var compareText = if (fieldValue is CharSequence) {
fieldValue
} else {
if (jsonResultLruCache[jsonKey] == null){
GsonUtil.toJson(fieldValue)
}else{
jsonResultLruCache[jsonKey]
}
}
if (compareText.isBlank()) {
return false
}
jsonResultLruCache.put(jsonKey, compareText)

for (wxid in PluginProviders.from(WXMaskPlugin::class.java).maskIdList) {
if (wxid == null) {
continue
}
if (compareText.contains(wxid)) {
putField2Cache(itemData::class.java.name, field)
LogUtil.d("hit wxid compareText: ", compareText)
return true
}
}
return false

}

private fun putField2Cache(itemClassName: String, field: Field) {
var pool = hideFieldInfoCache[itemClassName]
if (pool == null) {
pool = hashSetOf(field)
hideFieldInfoCache[itemClassName] = pool
} else {
pool.add(field)
}
}
}
Loading

0 comments on commit 47e4d9f

Please sign in to comment.