Skip to content

Commit

Permalink
wip: merge features from qhmk
Browse files Browse the repository at this point in the history
  • Loading branch information
cinit committed Sep 30, 2023
1 parent 0f667a5 commit a239a0a
Show file tree
Hide file tree
Showing 9 changed files with 432 additions and 3 deletions.
1 change: 1 addition & 0 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
-keep class moe.zapic.** { *; }
-keep class cc.microblock.** { *; }
-keep class com.tencent.mmkv.** { *; }
-keep class com.alphi.qhmk.** { *; }

-keepclasseswithmembernames class * {
native <methods>;
Expand Down
11 changes: 9 additions & 2 deletions app/src/main/java/cc/ioctl/hook/misc/AntiUpdate.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ object AntiUpdate : CommonSwitchFunctionHook() {
override val name: String = "屏蔽更新"

override fun initOnce(): Boolean {
val clz = Initiator._UpgradeController()
val kUpgradeController = Initiator._UpgradeController()
?: throw ClassNotFoundException("UpgradeController")
val kUpgradeDetailWrapper = Initiator.load("com.tencent.mobileqq.upgrade.UpgradeDetailWrapper")
?: Initiator.loadClass("com.tencent.mobileqq.app.upgrade.UpgradeDetailWrapper")
Expand All @@ -64,10 +64,17 @@ object AntiUpdate : CommonSwitchFunctionHook() {
hookBeforeIfEnabled(method) { param -> param.result = null }
} else {
// older versions
clz.findAllMethods {
kUpgradeController.findAllMethods {
emptyParam && returnType == kUpgradeDetailWrapper && name.length == 1
}.hookBefore { if (isEnabled) it.result = null }
}
for (m in kUpgradeController.getDeclaredMethods()) {
if (m.returnType == Void.TYPE) {
hookBeforeIfEnabled(m) { p -> p.setResult(null) }
} else if (m.returnType == Boolean::class.javaPrimitiveType) {
hookBeforeIfEnabled(m) { p -> p.result = false }
}
}
return true
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,19 @@
import io.github.qauxv.base.annotation.UiItemAgentEntry;
import io.github.qauxv.dsl.FunctionEntryRouter.Locations.Auxiliary;
import io.github.qauxv.hook.CommonSwitchFunctionHook;
import io.github.qauxv.util.Initiator;
import io.github.qauxv.util.Log;
import io.github.qauxv.util.SyncUtils;
import io.github.qauxv.util.Toasts;
import io.github.qauxv.util.dexkit.DexKit;
import io.github.qauxv.util.dexkit.DexKitTarget;
import io.github.qauxv.util.dexkit.NWebSecurityPluginV2_callback;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import kotlin.collections.ArraysKt;

@FunctionHookEntry
@UiItemAgentEntry
Expand Down Expand Up @@ -88,6 +95,87 @@ protected boolean initOnce() throws Exception {
}
}
});
Class<?> kCommonJsPluginFactory = Initiator.load("com.tencent.mobileqq.webprocess.WebAccelerateHelper$CommonJsPluginFactory");
if (kCommonJsPluginFactory == null) {
Class<?> aClassTemp = Initiator.loadClass("com.tencent.mobileqq.webprocess.WebAccelerateHelper");
Method[] methods = aClassTemp.getDeclaredMethods();
for (Method m : methods) {
Class<?>[] parameterTypes = m.getParameterTypes();
for (Class<?> ct : parameterTypes) {
if (ct.getSimpleName().contains("CommonJsPluginFactory")) {
kCommonJsPluginFactory = ct;
break;
}
}
}
}
Objects.requireNonNull(kCommonJsPluginFactory, "kCommonJsPluginFactory is null");
Method m1 = ArraysKt.single(kCommonJsPluginFactory.getDeclaredMethods(), m -> m.getReturnType() == List.class);
HookUtils.hookAfterIfEnabled(this, m1, param -> {
ArrayList array = (ArrayList) param.getResult();
ArrayList arrayTemp = (ArrayList) array.clone();
for (Object obj : arrayTemp) {
Class<?> mPlugin = obj.getClass();
String mPluginNameSpace = (String) mPlugin.getField("mPluginNameSpace").get(obj);
if (mPluginNameSpace.equals("forceHttps") || mPluginNameSpace.contains("UrlSaveVerify")
|| mPluginNameSpace.equals("Webso") || mPluginNameSpace.contains("Report")) {
array.remove(obj);
Log.d("WebSec: rm-" + mPlugin.getName());
continue;
}
Method[] methods = mPlugin.getDeclaredMethods();
for (Method m : methods) {
Class<?>[] parameterTypes = m.getParameterTypes();
if (parameterTypes.length > 0) {
Class<?> parameterType = parameterTypes[0];
if (parameterType.getSimpleName().equals("MessageRecord")) {
array.remove(obj);
}
}
}
}
param.setResult(array);
});

Class<?> AbsWebViewClass = Initiator.loadClass("com.tencent.mobileqq.webview.AbsWebView");
Method method_bindAllJavaScript;
try {
method_bindAllJavaScript = AbsWebViewClass.getDeclaredMethod("bindAllJavaScript");
} catch (NoSuchMethodException e) {
try {
method_bindAllJavaScript = AbsWebViewClass.getDeclaredMethod("bindBaseJavaScript");
} catch (NoSuchMethodException ex) {
e.addSuppressed(ex);
throw e;
}
}
Field mPluginListField = AbsWebViewClass.getField("mPluginList");
HookUtils.hookAfterIfEnabled(this, method_bindAllJavaScript, param -> {
ArrayList mPluginList = (ArrayList) mPluginListField.get(AbsWebViewClass);
ArrayList arrayTemp = (ArrayList) mPluginList.clone();
for (Object o : arrayTemp) {
Class<?> mPlugin = o.getClass();
String mPluginNameSpace = (String) mPlugin.getField("mPluginNameSpace").get(o);
if (mPluginNameSpace.contains("UrlSaveVerify") || mPluginNameSpace.equals("Webso")
|| mPluginNameSpace.contains("Report")) {
mPluginList.remove(o);
Log.d("WebSec: rm-" + mPlugin.getName());
continue;
}
Method[] methods = mPlugin.getMethods();
for (Method m : methods) {
Class<?>[] parameterTypes = m.getParameterTypes();
if (parameterTypes.length > 0) {
Class<?> parameterType = parameterTypes[0];
if (parameterType.getSimpleName().equals("MessageRecord")) {
mPluginList.remove(o);
Log.d("HookWebSecurity: hooked!");
}
}
}
}
mPluginListField.set(AbsWebViewClass, mPluginList);
});
return true;
}
}
75 changes: 75 additions & 0 deletions app/src/main/java/com/alphi/qhmk/module/DisableX5.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.alphi.qhmk.module;

import androidx.annotation.NonNull;
import cc.ioctl.util.HookUtils;
import io.github.qauxv.base.annotation.FunctionHookEntry;
import io.github.qauxv.base.annotation.UiItemAgentEntry;
import io.github.qauxv.dsl.FunctionEntryRouter;
import io.github.qauxv.hook.CommonSwitchFunctionHook;
import io.github.qauxv.util.Initiator;
import io.github.qauxv.util.Log;
import io.github.qauxv.util.SyncUtils;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import kotlin.collections.ArraysKt;

@UiItemAgentEntry
@FunctionHookEntry
public class DisableX5 extends CommonSwitchFunctionHook {

public static final DisableX5 INSTANCE = new DisableX5();

private DisableX5() {
super(SyncUtils.PROC_MAIN | SyncUtils.PROC_TOOL);
}

@Override
protected boolean initOnce() throws Exception {
//
Class<?> tbsClass = Initiator.loadClass("com.tencent.smtt.sdk.WebView");
Class<?> TbsClassConfig = null;
for (Field field : tbsClass.getDeclaredFields()) {
Class<?> type = field.getType();
if (type.getName().contains("com.tencent.smtt.utils.")) {
TbsClassConfig = type;
}
}
if (TbsClassConfig == null) {
throw new IllegalStateException("X5Settings init fail!!!");
}
Method method = ArraysKt.single(TbsClassConfig.getDeclaredMethods(), m -> m.getReturnType() == void.class);
HookUtils.hookAfterIfEnabled(this, method, param -> {
boolean result = false;
Log.d("hook:" + param.thisObject.getClass());
for (Field field : param.thisObject.getClass().getFields()) {
if (field.getType() == boolean.class) {
try {
field.set(param.thisObject, true);
result = true;
} catch (IllegalAccessException e) {
traceError(e);
}
}
}
if (result) {
Log.d("ForceUseSystemWebView success!");
} else {
Log.e("ForceUseSystemWebView fail!!!");
}
});
return true;
}

@NonNull
@Override
public String getName() {
return "禁用浏览器X5内核";
}

@NonNull
@Override
public String[] getUiItemLocation() {
return FunctionEntryRouter.Locations.Auxiliary.MISC_CATEGORY;
}

}
66 changes: 66 additions & 0 deletions app/src/main/java/com/alphi/qhmk/module/HiddenApolloView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.alphi.qhmk.module;

import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import cc.ioctl.util.HookUtils;
import cc.ioctl.util.HostInfo;
import io.github.qauxv.base.annotation.FunctionHookEntry;
import io.github.qauxv.base.annotation.UiItemAgentEntry;
import io.github.qauxv.dsl.FunctionEntryRouter;
import io.github.qauxv.hook.CommonSwitchFunctionHook;
import io.github.qauxv.util.Initiator;
import io.github.qauxv.util.QQVersion;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import kotlin.collections.ArraysKt;

/**
* IDEA 2022/02/21 隐藏侧滑厘米秀
*/
@UiItemAgentEntry
@FunctionHookEntry
public class HiddenApolloView extends CommonSwitchFunctionHook {

private HiddenApolloView() {
}

public static final HiddenApolloView INSTANCE = new HiddenApolloView();

@Override
protected boolean initOnce() throws Exception {
Class<?> aClass = Initiator.loadClass("com/tencent/mobileqq/apollo/SettingMeApolloViewController");
Field field = ArraysKt.single(aClass.getDeclaredFields(), f -> f.getType().getSimpleName().contains("View"));
field.setAccessible(true);
Method method = ArraysKt.single(aClass.getDeclaredMethods(), m -> m.getReturnType() == void.class);
HookUtils.hookAfterIfEnabled(this, method, param -> {
View view = (View) field.get(param.thisObject);
view.setVisibility(View.GONE);
});
return true;
}

@NonNull
@Override
public String getName() {
return "隐藏侧滑厘米秀";
}

@Nullable
@Override
public CharSequence getDescription() {
return "最高支持 8.4.10";
}

@NonNull
@Override
public String[] getUiItemLocation() {
return FunctionEntryRouter.Locations.Simplify.SLIDING_UI;
}

@Override
public boolean isAvailable() {
return HostInfo.isQQ() && HostInfo.getVersionCode() <= QQVersion.QQ_8_4_10;
}

}
46 changes: 46 additions & 0 deletions app/src/main/java/com/alphi/qhmk/module/HiddenVipIconForSe.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.alphi.qhmk.module;

import android.view.View;
import androidx.annotation.NonNull;
import cc.ioctl.util.HookUtils;
import io.github.qauxv.base.annotation.FunctionHookEntry;
import io.github.qauxv.base.annotation.UiItemAgentEntry;
import io.github.qauxv.dsl.FunctionEntryRouter;
import io.github.qauxv.hook.CommonSwitchFunctionHook;
import io.github.qauxv.util.Initiator;
import java.lang.reflect.Method;

@UiItemAgentEntry
@FunctionHookEntry
public class HiddenVipIconForSe extends CommonSwitchFunctionHook {

private HiddenVipIconForSe() {
}

public static final HiddenVipIconForSe INSTANCE = new HiddenVipIconForSe();

@Override
protected boolean initOnce() throws Exception {
Class<?> qsmClass = Initiator.loadClass("Lcom/tencent/mobileqq/widget/QVipMedalView;");
Method onLayout = qsmClass.getDeclaredMethod("onLayout", boolean.class, int.class, int.class, int.class, int.class);
HookUtils.hookBeforeIfEnabled(this, onLayout, param -> {
View obj = (View) param.thisObject;
obj.setClickable(false);
param.setResult(null);
});
return true;
}

@NonNull
@Override
public String getName() {
return "隐藏侧滑面板的VIP图标";
}

@NonNull
@Override
public String[] getUiItemLocation() {
return FunctionEntryRouter.Locations.Simplify.SLIDING_UI;
}

}
Loading

0 comments on commit a239a0a

Please sign in to comment.