Skip to content

Commit

Permalink
Fix module update check
Browse files Browse the repository at this point in the history
  • Loading branch information
shatyuka committed Mar 9, 2024
1 parent 0dcf85b commit df5b9b0
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 63 deletions.
35 changes: 35 additions & 0 deletions app/src/main/java/com/shatyuka/zhiliao/Helper.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
}
}
38 changes: 4 additions & 34 deletions app/src/main/java/com/shatyuka/zhiliao/MainHook.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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();
Expand Down Expand Up @@ -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)
Expand Down
5 changes: 2 additions & 3 deletions app/src/main/java/com/shatyuka/zhiliao/hooks/Tag.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down
55 changes: 30 additions & 25 deletions app/src/main/java/com/shatyuka/zhiliao/hooks/ZhihuPreference.java
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/xml/preferences_zhihu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="免责声明" android:key="category_eula">
<Preference
android:summary="本软件仅用于技术交流, 请勿用于商业及非法用途,如产生法律纠纷与本人无关&#x000A;&#x000A;本软件不会收集、上传您的个人信息,如有个人信息泄露与本人无关" />
android:summary="本软件仅用于技术交流, 请勿用于商业及非法用途,如产生法律纠纷与作者本人无关&#x000A;&#x000A;本软件不会收集、上传您的个人信息,如有个人信息泄露与作者本人无关" />
<com.zhihu.android.app.ui.widget.SwitchPreference
android:defaultValue="false"
android:key="accept_eula"
Expand Down

0 comments on commit df5b9b0

Please sign in to comment.