Skip to content

Commit

Permalink
[add] 暴力隐藏-dev
Browse files Browse the repository at this point in the history
# Conflicts:
#	README.md
  • Loading branch information
vitvm committed Feb 12, 2024
1 parent 35fdbf0 commit 8950373
Show file tree
Hide file tree
Showing 9 changed files with 351 additions and 19 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ v1.13版本开始,默认隐藏App在桌面的图标。隐藏以后,打开模
8.0.41 (2441) 2023-09-06
8.0.42 (2460) 2023-09-22
8.0.43 (2480) 2023-11-06
8.0.44 (2502) 2023-12-04
8.0.45 (2521) 2024-01-02


**PS.**
- 仅支持上述版本,所有其他版本号以及32位版本未经测试,预计百分之九十九不可用
Expand Down Expand Up @@ -131,6 +134,13 @@ 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

8.0.44(2502):[https://dldir1.qq.com/weixin/android/weixin8044android2502_0x28002c36_arm64.apk](https://dldir1.qq.com/weixin/android/weixin8044android2502_0x28002c36_arm64.apk)
SHA1: 38525994D6D69106CDB3D6F9F62B045CFF9CC4D5

8.0.45(2521):[https://dldir1.qq.com/weixin/android/weixin8045android2521_0x28002d34_arm64_1.apk](https://dldir1.qq.com/weixin/android/weixin8045android2521_0x28002d34_arm64_1.apk)
SHA1: F44F35663E2A2C3BF9EA671270D65902AB5727DA




推荐适配的最后两个版本,因为其他版本,作者自己不再使用
Expand Down
20 changes: 20 additions & 0 deletions app/src/main/java/com/lu/wxmask/bean/PointBean.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.lu.wxmask.bean

import androidx.annotation.Keep
import org.json.JSONObject

@Keep
class PointBean(
var featId: String,
var clazz: String,
var method: String
) {
companion object {
fun fromJson(value: JSONObject): PointBean {
val featId = value.optString("featId", null)
val clazz = value.optString("clazz", null)
val method = value.optString("method", null)
return PointBean(featId, clazz, method)
}
}
}
16 changes: 3 additions & 13 deletions app/src/main/java/com/lu/wxmask/plugin/CommonPlugin.kt
Original file line number Diff line number Diff line change
@@ -1,20 +1,8 @@
package com.lu.wxmask.plugin

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
import com.lu.magic.util.log.LogUtil
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 com.lu.wxmask.util.HookPointManager
import de.robv.android.xposed.callbacks.XC_LoadPackage

class CommonPlugin : IPlugin {
Expand Down Expand Up @@ -42,5 +30,7 @@ class CommonPlugin : IPlugin {
// }
// }
// )

HookPointManager.INSTANCE.init(context, lpparam)
}
}
4 changes: 2 additions & 2 deletions app/src/main/java/com/lu/wxmask/plugin/WXMaskPlugin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import java.util.concurrent.CopyOnWriteArraySet

class WXMaskPlugin : IPlugin, ConfigSetObserver {
lateinit var maskIdList: Array<String?>
private val hideSearchListPluginPart = HideSearchListUIPluginPart()
val hideSearchListPluginPart = HideSearchListUIPluginPart()
private val enterChattingUIPluginPart = EnterChattingUIPluginPart()
private val hideMainUIListPluginPart = HideMainUIListPluginPart()
private val emptySingChatHistoryGalleryPluginPart = EmptySingChatHistoryGalleryPluginPart()
Expand Down Expand Up @@ -55,7 +55,7 @@ class WXMaskPlugin : IPlugin, ConfigSetObserver {
maskIdList = loadMaskIdList()
hideMainUIListPluginPart.handleHook(context, lpparam)
enterChattingUIPluginPart.handleHook(context, lpparam)
hideSearchListPluginPart.handleHook(context, lpparam)
// hideSearchListPluginPart.handleHook(context, lpparam)
emptySingChatHistoryGalleryPluginPart.handleHook(context, lpparam)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class HideSearchListUIPluginPart : IPlugin {
//hook getItem --> rename to h
XposedHelpers2.findAndHookMethod("com.tencent.mm.plugin.fts.ui.a0",
context.classLoader,
getItemMethod ,
getItemMethod,
java.lang.Integer.TYPE,
object : XC_MethodHook2() {
override fun afterHookedMethod(param: MethodHookParam) {
Expand Down Expand Up @@ -265,7 +265,7 @@ class HideSearchListUIPluginPart : IPlugin {
}


private fun needHideUserName2(param: XC_MethodHook.MethodHookParam, itemData: Any?): Boolean {
fun needHideUserName2(param: XC_MethodHook.MethodHookParam, itemData: Any?): Boolean {
if (itemData == null) {
return false
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.lu.wxmask.plugin.point;

import android.content.Context;

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.log.LogUtil;
import com.lu.wxmask.ClazzN;
import com.lu.wxmask.bean.PointBean;
import com.lu.wxmask.plugin.WXMaskPlugin;
import com.lu.wxmask.plugin.part.HideSearchListUIPluginPart;

import org.jetbrains.annotations.NotNull;

import java.lang.reflect.Method;

import de.robv.android.xposed.callbacks.XC_LoadPackage;

public class HideSearchListPoint implements IPlugin {
private PointBean mPointBean;

public HideSearchListPoint(@NotNull PointBean it) {
mPointBean = it;
}

@Override
public void handleHook(Context context, XC_LoadPackage.LoadPackageParam lpparam) {
if (mPointBean == null) {
return;
}
Method method = XposedHelpers2.findMethodExactIfExists(ClazzN.from(mPointBean.getClazz()), mPointBean.getMethod(), Integer.TYPE);
if (method == null) {
return;
}
XposedHelpers2.hookMethod(method, new XC_MethodHook2() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
WXMaskPlugin wxMaskPlugin = PluginProviders.from(WXMaskPlugin.class);
HideSearchListUIPluginPart pluginPart = wxMaskPlugin.getHideSearchListPluginPart();

if (pluginPart.needHideUserName2(param, param.getResult())) {
LogUtil.d("hide hahah", param.getResult());
param.setResult(null);
}
}

});
}
}
6 changes: 4 additions & 2 deletions app/src/main/java/com/lu/wxmask/util/AppVersionUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,10 @@ class AppVersionUtil {
Constrant.WX_CODE_8_0_38,
Constrant.WX_CODE_8_0_40,
Constrant.WX_CODE_8_0_41,
Constrant.WX_CODE_8_0_42 -> true

Constrant.WX_CODE_8_0_42,
Constrant.WX_CODE_8_0_43,
Constrant.WX_CODE_8_0_44,
Constrant.WX_CODE_8_0_45 -> true
else -> false
}
}
Expand Down
162 changes: 162 additions & 0 deletions app/src/main/java/com/lu/wxmask/util/CodeUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
package com.lu.wxmask.util;

import android.content.Context;

import com.lu.magic.util.ReflectUtil;
import com.lu.magic.util.function.Consumer;
import com.lu.magic.util.function.Predicate;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import dalvik.system.DexFile;

public class CodeUtil {
/**
* 获取应用程序下的所有Dex文件
*
* @param packageCodePath 包路径
* @return Set<DexFile>
*/
private static List<DexFile> getDexFileList(String packageCodePath) {
List<DexFile> dexFiles = new ArrayList<>();
File dir = new File(packageCodePath).getParentFile();
File[] files = dir.listFiles();
for (File file : files) {
try {
String absolutePath = file.getAbsolutePath();
if (!absolutePath.contains(".")) continue;
String suffix = absolutePath.substring(absolutePath.lastIndexOf("."));
if (!suffix.equals(".apk")) continue;
DexFile dexFile = getDexFile(file.getAbsolutePath());
if (dexFile == null) continue;
dexFiles.add(dexFile);
} catch (Exception e) {
e.printStackTrace();
}
}
return dexFiles;
}

/**
* 获取DexFile文件
*
* @param path 路径
* @return DexFile
*/
public static DexFile getDexFile(String path) {
try {
return new DexFile(path);
} catch (IOException e) {
return null;
}
}


public static List<String> filterClass(Context context, Predicate<String> func) {
List<DexFile> dexFiles = getDexFileListNewApi(context.getClassLoader());
if (dexFiles.isEmpty()) {
//老方法需要重新读取,耗时大
dexFiles = getDexFileList(context.getApplicationContext().getPackageCodePath());
}
return filterClassInternal(dexFiles.iterator(), func);
}

public static void eachClass(Context context, Consumer<String> consumer) {
List<DexFile> dexFiles = getDexFileListNewApi(context.getClassLoader());
if (dexFiles.isEmpty()) {
//老方法需要重新读取,耗时大
dexFiles = getDexFileList(context.getApplicationContext().getPackageCodePath());
}
eachClassInternal(dexFiles.iterator(), consumer);
}

/**
* 读取类路径下的所有类
*
* @param context 上下文
* @param pkgName 包名
* @return List<String>
*/
public static List<String> filterClass(Context context, String pkgName, boolean includeChildDir) {
List<DexFile> dexFiles = getDexFileListNewApi(context.getClassLoader());
if (dexFiles.isEmpty()) {
//老方法需要重新读取,耗时大
dexFiles = getDexFileList(context.getApplicationContext().getPackageCodePath());
}

return filterClassInternal(dexFiles.iterator(), currentClassPath -> {
if (!currentClassPath.startsWith(pkgName)) {
return false;
}
if (includeChildDir) {
return true;
} else {
return '.' == currentClassPath.charAt(pkgName.length());
}
});
}


public static List<DexFile> getDexFileListNewApi(ClassLoader classLoader) {
List<DexFile> result = new ArrayList<>();
try {
Object pathList = ReflectUtil.getFieldValue(classLoader, classLoader.getClass().getSuperclass(), "pathList");
Object[] dexElements = (Object[]) ReflectUtil.getFieldValue(pathList, "dexElements");
for (Object dexElement : dexElements) {
DexFile dexFile = (DexFile) ReflectUtil.getFieldValue(dexElement, "dexFile");
result.add(dexFile);
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}


private static void eachClassInternal(Iterator<DexFile> dexFiles, Consumer<String> func) {

while (dexFiles.hasNext()) {
DexFile dexFile = dexFiles.next();
if (dexFile == null) continue;

Enumeration<String> entries = dexFile.entries();
while (entries.hasMoreElements()) {
try {
String currentClassPath = entries.nextElement();
if (currentClassPath == null || currentClassPath.isEmpty()) {
continue;
}
func.accept(currentClassPath);
} catch (Exception e) {
e.printStackTrace();
}
}
}

}

private static List<String> filterClassInternal(Iterator<DexFile> dexFiles, Predicate<String> predicateFunc) {
HashSet<String> result = new HashSet<>();
eachClassInternal(dexFiles, s -> {
if (predicateFunc.test(s)) {
result.add(s);
}
});
return new ArrayList<>(result);
}


public static String getPackageName(String typeName) {
int index = typeName.lastIndexOf(".");
if (index == -1) {
return null;
}
return typeName.substring(0, index);
}
}
Loading

0 comments on commit 8950373

Please sign in to comment.