From df5b9b073301f09b8c13391823df8aaa5ef9cb63 Mon Sep 17 00:00:00 2001 From: Shatyuka <958182453@qq.com> Date: Sat, 9 Mar 2024 21:19:31 +0800 Subject: [PATCH] Fix module update check --- .../java/com/shatyuka/zhiliao/Helper.java | 35 ++++++++++++ .../java/com/shatyuka/zhiliao/MainHook.java | 38 ++----------- .../java/com/shatyuka/zhiliao/hooks/Tag.java | 5 +- .../zhiliao/hooks/ZhihuPreference.java | 55 ++++++++++--------- app/src/main/res/xml/preferences_zhihu.xml | 2 +- 5 files changed, 72 insertions(+), 63 deletions(-) diff --git a/app/src/main/java/com/shatyuka/zhiliao/Helper.java b/app/src/main/java/com/shatyuka/zhiliao/Helper.java index b3c90cd..e158bfb 100644 --- a/app/src/main/java/com/shatyuka/zhiliao/Helper.java +++ b/app/src/main/java/com/shatyuka/zhiliao/Helper.java @@ -8,6 +8,7 @@ import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.content.pm.Signature; import android.content.res.AssetManager; import android.content.res.Configuration; import android.content.res.Resources; @@ -17,6 +18,7 @@ import java.io.File; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.security.MessageDigest; import java.util.Arrays; import java.util.Comparator; import java.util.Optional; @@ -48,6 +50,11 @@ public class Helper { public static Object settingsView; + public static boolean officialZhihu = true; + + public final static String hookPackage = "com.zhihu.android"; + private final static byte[] signature = new byte[]{(byte) 0xB6, (byte) 0xF9, (byte) 0x97, (byte) 0xE3, (byte) 0x82, 0x7B, (byte) 0xE1, 0x1A, (byte) 0xF2, (byte) 0xFA, 0x4A, 0x15, 0x3F, (byte) 0xEA, 0x3F, (byte) 0xE6, 0x27, 0x68, 0x66, 0x02}; + static boolean init(ClassLoader classLoader) { try { init_class(classLoader); @@ -257,4 +264,32 @@ public static Field findFieldByType(Class clazz, Class type) { field.setAccessible(true); return field; } + + private static Signature[] getSignatures(Context context) throws PackageManager.NameNotFoundException { + PackageManager pm = context.getPackageManager(); + Signature[] sig; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) { + android.content.pm.SigningInfo sign = pm.getPackageInfo(hookPackage, PackageManager.GET_SIGNING_CERTIFICATES).signingInfo; + sig = sign.hasMultipleSigners() ? sign.getApkContentsSigners() : sign.getSigningCertificateHistory(); + } else { + sig = pm.getPackageInfo(hookPackage, PackageManager.GET_SIGNATURES).signatures; + } + return sig; + } + + public static boolean checkSignature(Context context) { + try { + Signature[] sig = getSignatures(context); + MessageDigest md = MessageDigest.getInstance("SHA1"); + for (Signature s : sig) { + byte[] dig = md.digest(s.toByteArray()); + if (Arrays.equals(dig, signature)) { + return true; + } + } + return false; + } catch (Throwable ignored) { + return false; + } + } } diff --git a/app/src/main/java/com/shatyuka/zhiliao/MainHook.java b/app/src/main/java/com/shatyuka/zhiliao/MainHook.java index dbaf342..2096fe0 100644 --- a/app/src/main/java/com/shatyuka/zhiliao/MainHook.java +++ b/app/src/main/java/com/shatyuka/zhiliao/MainHook.java @@ -3,13 +3,9 @@ import android.annotation.SuppressLint; import android.app.Application; import android.content.Context; -import android.content.pm.PackageManager; -import android.content.pm.Signature; import android.widget.Toast; import java.io.File; -import java.security.MessageDigest; -import java.util.Arrays; import de.robv.android.xposed.IXposedHookLoadPackage; import de.robv.android.xposed.IXposedHookZygoteInit; @@ -19,8 +15,6 @@ import de.robv.android.xposed.callbacks.XC_LoadPackage; public class MainHook implements IXposedHookLoadPackage, IXposedHookZygoteInit { - public final static String hookPackage = "com.zhihu.android"; - private final static byte[] signature = new byte[]{(byte) 0xB6, (byte) 0xF9, (byte) 0x97, (byte) 0xE3, (byte) 0x82, 0x7B, (byte) 0xE1, 0x1A, (byte) 0xF2, (byte) 0xFA, 0x4A, 0x15, 0x3F, (byte) 0xEA, 0x3F, (byte) 0xE6, 0x27, 0x68, 0x66, 0x02}; static String modulePath; private native void initNative(); @@ -48,38 +42,14 @@ private void tryLoadNative(boolean showLog) { XposedBridge.log("[Zhiliao] 知了native模块加载失败"); } - @SuppressLint("PackageManagerGetSignatures") - static boolean checkSignature(Context context) { - try { - PackageManager pm = context.getPackageManager(); - Signature[] sig; - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) { - android.content.pm.SigningInfo sign = pm.getPackageInfo(hookPackage, PackageManager.GET_SIGNING_CERTIFICATES).signingInfo; - sig = sign.hasMultipleSigners() ? sign.getApkContentsSigners() : sign.getSigningCertificateHistory(); - } else { - sig = pm.getPackageInfo(hookPackage, PackageManager.GET_SIGNATURES).signatures; - } - MessageDigest md = MessageDigest.getInstance("SHA1"); - for (Signature s : sig) { - byte[] dig = md.digest(s.toByteArray()); - if (Arrays.equals(dig, signature)) { - return true; - } - } - return false; - } catch (Throwable ignored) { - return false; - } - } - - @SuppressLint("PackageManagerGetSignatures") @Override public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam) { - if (hookPackage.equals(lpparam.packageName)) { - boolean isMainProcess = hookPackage.equals(lpparam.processName); + if (Helper.hookPackage.equals(lpparam.packageName)) { + boolean isMainProcess = Helper.hookPackage.equals(lpparam.processName); Context systemContext = (Context) XposedHelpers.callMethod(XposedHelpers.callStaticMethod(XposedHelpers.findClass("android.app.ActivityThread", lpparam.classLoader), "currentActivityThread"), "getSystemContext"); - if (!checkSignature(systemContext)) { + if (!Helper.checkSignature(systemContext)) { tryLoadNative(isMainProcess); + Helper.officialZhihu = false; } if (!isMainProcess) diff --git a/app/src/main/java/com/shatyuka/zhiliao/hooks/Tag.java b/app/src/main/java/com/shatyuka/zhiliao/hooks/Tag.java index 55c4c5f..3f1a1ce 100644 --- a/app/src/main/java/com/shatyuka/zhiliao/hooks/Tag.java +++ b/app/src/main/java/com/shatyuka/zhiliao/hooks/Tag.java @@ -8,7 +8,6 @@ import android.widget.TextView; import com.shatyuka.zhiliao.Helper; -import com.shatyuka.zhiliao.MainHook; import com.shatyuka.zhiliao.R; import java.lang.reflect.Field; @@ -78,8 +77,8 @@ protected void afterHookedMethod(MethodHookParam param) throws Throwable { return; } - TextView title = viewGroup.findViewById(Helper.context.getResources().getIdentifier("title", "id", MainHook.hookPackage)); - View author = viewGroup.findViewById(Helper.context.getResources().getIdentifier("author", "id", MainHook.hookPackage)); + TextView title = viewGroup.findViewById(Helper.context.getResources().getIdentifier("title", "id", Helper.hookPackage)); + View author = viewGroup.findViewById(Helper.context.getResources().getIdentifier("author", "id", Helper.hookPackage)); if (title == null) { return; } diff --git a/app/src/main/java/com/shatyuka/zhiliao/hooks/ZhihuPreference.java b/app/src/main/java/com/shatyuka/zhiliao/hooks/ZhihuPreference.java index 171ec8b..46278c0 100644 --- a/app/src/main/java/com/shatyuka/zhiliao/hooks/ZhihuPreference.java +++ b/app/src/main/java/com/shatyuka/zhiliao/hooks/ZhihuPreference.java @@ -431,34 +431,39 @@ protected Object replaceHookedMethod(MethodHookParam param) throws Throwable { setOnPreferenceClickListener.invoke(switch_feedtophot, thisObject); setOnPreferenceClickListener.invoke(switch_minehybrid, thisObject); - String real_version = null; - try { - real_version = Helper.context.getPackageManager().getResourcesForApplication(modulePackage).getString(R.string.app_version); - } catch (Exception ignore) { - } String loaded_version = Helper.modRes.getString(R.string.app_version); setSummary.invoke(preference_version, loaded_version); - if (real_version == null || loaded_version.equals(real_version)) { - setVisible.invoke(preference_status, false); + + if (Helper.officialZhihu) { + String real_version = null; + try { + real_version = Helper.context.getPackageManager().getResourcesForApplication(modulePackage).getString(R.string.app_version); + } catch (Exception ignore) { + } + if (real_version == null || loaded_version.equals(real_version)) { + setVisible.invoke(preference_status, false); + } else { + setOnPreferenceClickListener.invoke(preference_status, thisObject); + Object category_eula = findPreference.invoke(thisObject, "category_eula"); + Object category_ads = findPreference.invoke(thisObject, "category_ads"); + Object category_misc = findPreference.invoke(thisObject, "category_misc"); + Object category_ui = findPreference.invoke(thisObject, "category_ui"); + Object category_swap_answers = findPreference.invoke(thisObject, "category_swap_answers"); + Object category_filter = findPreference.invoke(thisObject, "category_filter"); + Object category_webview = findPreference.invoke(thisObject, "category_webview"); + Object category_cleaner = findPreference.invoke(thisObject, "category_cleaner"); + setVisible.invoke(category_eula, false); + setVisible.invoke(category_ads, false); + setVisible.invoke(category_misc, false); + setVisible.invoke(category_ui, false); + setVisible.invoke(category_swap_answers, false); + setVisible.invoke(category_filter, false); + setVisible.invoke(category_webview, false); + setVisible.invoke(category_cleaner, false); + return null; + } } else { - setOnPreferenceClickListener.invoke(preference_status, thisObject); - Object category_eula = findPreference.invoke(thisObject, "category_eula"); - Object category_ads = findPreference.invoke(thisObject, "category_ads"); - Object category_misc = findPreference.invoke(thisObject, "category_misc"); - Object category_ui = findPreference.invoke(thisObject, "category_ui"); - Object category_swap_answers = findPreference.invoke(thisObject, "category_swap_answers"); - Object category_filter = findPreference.invoke(thisObject, "category_filter"); - Object category_webview = findPreference.invoke(thisObject, "category_webview"); - Object category_cleaner = findPreference.invoke(thisObject, "category_cleaner"); - setVisible.invoke(category_eula, false); - setVisible.invoke(category_ads, false); - setVisible.invoke(category_misc, false); - setVisible.invoke(category_ui, false); - setVisible.invoke(category_swap_answers, false); - setVisible.invoke(category_filter, false); - setVisible.invoke(category_webview, false); - setVisible.invoke(category_cleaner, false); - return null; + setVisible.invoke(preference_status, false); } setIcon.invoke(preference_status, Helper.modRes.getDrawable(R.drawable.ic_refresh)); diff --git a/app/src/main/res/xml/preferences_zhihu.xml b/app/src/main/res/xml/preferences_zhihu.xml index 92e7903..130ed58 100644 --- a/app/src/main/res/xml/preferences_zhihu.xml +++ b/app/src/main/res/xml/preferences_zhihu.xml @@ -2,7 +2,7 @@ + android:summary="本软件仅用于技术交流, 请勿用于商业及非法用途,如产生法律纠纷与作者本人无关。 本软件不会收集、上传您的个人信息,如有个人信息泄露与作者本人无关。" />