mirror of
https://github.com/MoonLeeeaf/FuckMaoNemo.git
synced 2025-06-06 11:23:33 +08:00
Compare commits
10 Commits
v1.0.1
...
54f1597235
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
54f1597235 | ||
|
|
68b3d96fdd | ||
|
|
c6a3f015e5 | ||
|
|
05f2d3915c | ||
|
|
9543727c7a | ||
|
|
7a529652c5 | ||
|
|
d43f1091d4 | ||
|
|
2b59a3a84d | ||
|
|
7469415b2a | ||
|
|
5bc2e427df |
35
.androidide/editor/openedFiles.json
Normal file
35
.androidide/editor/openedFiles.json
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"allFiles": [
|
||||||
|
{
|
||||||
|
"file": "/storage/emulated/0/铃芽の文件/Projects/FuckMaoNemo/app/src/main/res/xml/config.xml",
|
||||||
|
"selection": {
|
||||||
|
"end": {
|
||||||
|
"column": 36,
|
||||||
|
"index": 1031,
|
||||||
|
"line": 30
|
||||||
|
},
|
||||||
|
"start": {
|
||||||
|
"column": 36,
|
||||||
|
"index": 1031,
|
||||||
|
"line": 30
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "/storage/emulated/0/铃芽の文件/Projects/FuckMaoNemo/app/build.gradle",
|
||||||
|
"selection": {
|
||||||
|
"end": {
|
||||||
|
"column": 26,
|
||||||
|
"index": 302,
|
||||||
|
"line": 15
|
||||||
|
},
|
||||||
|
"start": {
|
||||||
|
"column": 26,
|
||||||
|
"index": 302,
|
||||||
|
"line": 15
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"selectedFile": "/storage/emulated/0/铃芽の文件/Projects/FuckMaoNemo/app/build.gradle"
|
||||||
|
}
|
||||||
BIN
.github/1.jpg
vendored
BIN
.github/1.jpg
vendored
Binary file not shown.
|
Before Width: | Height: | Size: 240 KiB After Width: | Height: | Size: 391 KiB |
@@ -12,8 +12,8 @@ android {
|
|||||||
applicationId "io.github.moonleeeaf.fuckmaonemo"
|
applicationId "io.github.moonleeeaf.fuckmaonemo"
|
||||||
minSdk 21
|
minSdk 21
|
||||||
targetSdk 33
|
targetSdk 33
|
||||||
versionCode 10100
|
versionCode 12100
|
||||||
versionName "1.0.1"
|
versionName "1.2.1"
|
||||||
|
|
||||||
vectorDrawables {
|
vectorDrawables {
|
||||||
useSupportLibrary true
|
useSupportLibrary true
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package io.github.moonleeeaf.fuckmaonemo;
|
package io.github.moonleeeaf.fuckmaonemo;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import de.robv.android.xposed.IXposedHookLoadPackage;
|
import de.robv.android.xposed.IXposedHookLoadPackage;
|
||||||
@@ -11,10 +13,16 @@ import de.robv.android.xposed.XposedBridge;
|
|||||||
import de.robv.android.xposed.XposedHelpers;
|
import de.robv.android.xposed.XposedHelpers;
|
||||||
import de.robv.android.xposed.callbacks.XC_LoadPackage;
|
import de.robv.android.xposed.callbacks.XC_LoadPackage;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.Proxy;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class Hook implements IXposedHookLoadPackage {
|
public class Hook implements IXposedHookLoadPackage {
|
||||||
private static boolean isHooked = false;
|
private static boolean isHooked = false;
|
||||||
private XSharedPreferences xsp;
|
private XSharedPreferences xsp;
|
||||||
|
private ClassLoader classLoader;
|
||||||
|
private int nohengheng;
|
||||||
|
private int aaaa;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam param) throws Throwable {
|
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam param) throws Throwable {
|
||||||
@@ -29,15 +37,15 @@ public class Hook implements IXposedHookLoadPackage {
|
|||||||
protected void afterHookedMethod(MethodHookParam mParam) throws Throwable {
|
protected void afterHookedMethod(MethodHookParam mParam) throws Throwable {
|
||||||
super.afterHookedMethod(mParam);
|
super.afterHookedMethod(mParam);
|
||||||
Object initApp = XposedHelpers.getObjectField(mParam.thisObject, "mInitialApplication");
|
Object initApp = XposedHelpers.getObjectField(mParam.thisObject, "mInitialApplication");
|
||||||
hook(param, initApp.getClass().getClassLoader());
|
classLoader = initApp.getClass().getClassLoader();
|
||||||
|
hook(param);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Method getMethod(Class clazz, String name, Class... args) throws NoSuchMethodException {
|
public static Method getMethod(Class clazz, String name, Class<?>... args) throws NoSuchMethodException {
|
||||||
return clazz.getDeclaredMethod(name, args);
|
return clazz.getDeclaredMethod(name, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,18 +53,19 @@ public class Hook implements IXposedHookLoadPackage {
|
|||||||
return (Application) XposedHelpers.callStaticMethod(Class.forName("android.app.ActivityThread"), "currentApplication");
|
return (Application) XposedHelpers.callStaticMethod(Class.forName("android.app.ActivityThread"), "currentApplication");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hook(XC_LoadPackage.LoadPackageParam param, ClassLoader classLoader) throws Exception {
|
public void hook(XC_LoadPackage.LoadPackageParam param) throws Exception {
|
||||||
if (isHooked) return;
|
if (isHooked) return;
|
||||||
else isHooked = true;
|
else isHooked = true;
|
||||||
|
|
||||||
int nohengheng = 0;
|
nohengheng = 0;
|
||||||
|
aaaa = 0;
|
||||||
|
|
||||||
xsp = new XSharedPreferences("io.github.moonleeeaf.fuckmaonemo", "config");
|
xsp = new XSharedPreferences("io.github.moonleeeaf.fuckmaonemo", "config");
|
||||||
|
|
||||||
XposedBridge.log("[FuckMaoNemo] 注入中...");
|
XposedBridge.log("[FuckMaoNemo] 注入中...");
|
||||||
|
|
||||||
// 拦截40x码
|
// 拦截40x码
|
||||||
if (xsp.getBoolean("fuck_40x", false)) {
|
load("fuck_40x", () -> {
|
||||||
XposedBridge.log("[FuckMaoNemo] Hook_拦截40x码");
|
XposedBridge.log("[FuckMaoNemo] Hook_拦截40x码");
|
||||||
XposedBridge.hookMethod(
|
XposedBridge.hookMethod(
|
||||||
getMethod(
|
getMethod(
|
||||||
@@ -72,53 +81,117 @@ public class Hook implements IXposedHookLoadPackage {
|
|||||||
if(code >= 400 && code <500) {
|
if(code >= 400 && code <500) {
|
||||||
Object rawRes = XposedHelpers.getObjectField(res, "rawResponse");
|
Object rawRes = XposedHelpers.getObjectField(res, "rawResponse");
|
||||||
XposedHelpers.setIntField(rawRes, "code", 200);
|
XposedHelpers.setIntField(rawRes, "code", 200);
|
||||||
XposedBridge.log("[FuckMaoNemo] 拦截响应 40x 码");
|
XposedBridge.log("[FuckMaoNemo] 拦截响应 " + code + " 码");
|
||||||
String t = "";
|
String t = "响应码 " + code;
|
||||||
switch (code){
|
switch (code) {
|
||||||
case 401:
|
case 401:
|
||||||
t = "已拦截异常登出";
|
t = "已阻止异常登出";
|
||||||
break;
|
|
||||||
case 422:
|
|
||||||
t = "已拦截封号页面替换资料卡";
|
|
||||||
break;
|
break;
|
||||||
case 405:
|
case 405:
|
||||||
t = "评论接口被禁止";
|
case 422:
|
||||||
|
t = "API 访问被拒绝,评论区或者已封禁账号?";
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
t = "未知拦截,响应码为 " + code;
|
|
||||||
}
|
}
|
||||||
Toast.makeText(getApplication(), "[FuckMaoNemo] " + t, Toast.LENGTH_SHORT).show();
|
Toast.makeText(getApplication(), "[FuckMaoNemo] " + t, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
nohengheng++;
|
});
|
||||||
}
|
|
||||||
|
|
||||||
// 绕过防沉迷
|
// 绕过防沉迷
|
||||||
if (xsp.getBoolean("fuck_fcm", false)) {
|
load("fuck_fcm", () -> {
|
||||||
XposedBridge.log("[FuckMaoNemo] Hook_绕过防沉迷");
|
XposedBridge.log("[FuckMaoNemo] Hook_绕过防沉迷");
|
||||||
|
methodToVoid(getMethod(
|
||||||
|
XposedHelpers.findClass("com.codemao.nemo.activity.WorkDetailActivity", classLoader),
|
||||||
|
"checkAntiAddictionState",
|
||||||
|
null
|
||||||
|
));
|
||||||
|
});
|
||||||
|
|
||||||
|
// 强制显示再创作按钮
|
||||||
|
load("force_show_rework", () -> {
|
||||||
|
XposedBridge.log("[FuckMaoNemo] Hook_强制显示再创作按钮");
|
||||||
XposedBridge.hookMethod(
|
XposedBridge.hookMethod(
|
||||||
getMethod(
|
getMethod(
|
||||||
XposedHelpers.findClass("com.codemao.nemo.activity.WorkDetailActivity", classLoader),
|
XposedHelpers.findClass("com.codemao.creativecenter.utils.bcm.bean.CreativeWorkDetailInfo", classLoader),
|
||||||
"checkAntiAddictionState",
|
"isFork_enable",
|
||||||
null
|
null
|
||||||
),
|
),
|
||||||
new XC_MethodReplacement() {
|
new XC_MethodReplacement() {
|
||||||
@Override
|
@Override
|
||||||
protected Object replaceHookedMethod(MethodHookParam arg0) throws Throwable {
|
protected Object replaceHookedMethod(MethodHookParam arg0) throws Throwable {
|
||||||
XposedBridge.log("[FuckMaoNemo] 拦截防沉迷方法调用");
|
return true;
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
nohengheng++;
|
});
|
||||||
}
|
|
||||||
|
// 不追踪
|
||||||
|
load("no_records", () -> {
|
||||||
|
XposedBridge.log("[FuckMaoNemo] Hook_不追踪");
|
||||||
|
methodToVoid(getMethod(
|
||||||
|
XposedHelpers.findClass("cn.codemao.android.stat.CodeMaoStat", classLoader),
|
||||||
|
"recordEvent",
|
||||||
|
String.class,
|
||||||
|
Map.class
|
||||||
|
));
|
||||||
|
});
|
||||||
|
|
||||||
|
// 反防抓包
|
||||||
|
load("fuck_no_proxy", () -> {
|
||||||
|
XposedBridge.log("[FuckMaoNemo] Hook_反防抓包");
|
||||||
|
// TODO:其实可以从 OkHttp 底层去Hook的
|
||||||
|
methodToVoid(
|
||||||
|
getMethod(
|
||||||
|
XposedHelpers.findClass("okhttp3.OkHttpClient$Builder", classLoader),
|
||||||
|
"proxy",
|
||||||
|
Proxy.class
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 屏蔽更新
|
||||||
|
load("fuck_update", () -> {
|
||||||
|
XposedBridge.log("[FuckMaoNemo] Hook_屏蔽更新");
|
||||||
|
methodToVoid(
|
||||||
|
getMethod(
|
||||||
|
XposedHelpers.findClass("com.codemao.nemo.sdk.update.NetChangeReceiver", classLoader),
|
||||||
|
"onReceive",
|
||||||
|
Context.class,
|
||||||
|
Intent.class
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
XposedBridge.log("[FuckMaoNemo] 执行完毕");
|
XposedBridge.log("[FuckMaoNemo] 执行完毕");
|
||||||
|
|
||||||
Toast.makeText(getApplication(), "[FuckMaoNemo] 加载成功 (≧▽≦)\n" + nohengheng + " 个功能已加载", Toast.LENGTH_LONG).show();
|
Toast.makeText(getApplication(), "[FuckMaoNemo] 加载成功 (≧▽≦)\n" + nohengheng + " 个功能加载成功, " + aaaa + " 个失败", Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Callback {
|
||||||
|
public void onCallback() throws Exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void methodToVoid(Method m) {
|
||||||
|
XposedBridge.hookMethod(m, new XC_MethodReplacement() {
|
||||||
|
@Override
|
||||||
|
protected Object replaceHookedMethod(MethodHookParam arg0) throws Throwable {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void load(String pref, Callback cb) {
|
||||||
|
if (xsp.getBoolean(pref, false)) {
|
||||||
|
try {
|
||||||
|
cb.onCallback();
|
||||||
|
nohengheng++;
|
||||||
|
} catch (Exception e) {
|
||||||
|
XposedBridge.log(e);
|
||||||
|
aaaa++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<Preference
|
<Preference
|
||||||
android:title="作者"
|
android:title="作者"
|
||||||
android:summary="编程猫 @满月叶\nGitHub @MoonLeeeaf" />
|
android:summary="编程猫 @满月叶\nGitHub @MoonLeeeaf\n喵呜~" />
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
@@ -17,7 +17,23 @@
|
|||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:key="fuck_40x"
|
android:key="fuck_40x"
|
||||||
android:title="阻止服务端响应 40x 码"
|
android:title="阻止服务端响应 40x 码"
|
||||||
android:summary="启用此开关后,将可以:\n拦截 401 码强制登出账号\n强制浏览已封禁账号的资料卡\n评论接口检测\n其他作用" />
|
android:summary="拦截 401 码强制登出账号\n强制浏览已封禁账号的资料卡\n评论接口检测\n获得调试信息?" />
|
||||||
|
|
||||||
|
<SwitchPreference
|
||||||
|
android:key="no_records"
|
||||||
|
android:title="不要追踪我"
|
||||||
|
android:summary="启用后,模块将会拦截 CodeMaoStat.recordEvent(str, map) 调用(比如点击创作按钮都会发送一个 collect 请求),风险未知" />
|
||||||
|
|
||||||
|
|
||||||
|
<SwitchPreference
|
||||||
|
android:key="fuck_update"
|
||||||
|
android:title="屏蔽更新"
|
||||||
|
android:summary="主页不会弹更新对话框" />
|
||||||
|
|
||||||
|
<SwitchPreference
|
||||||
|
android:key="fuck_no_proxy"
|
||||||
|
android:title="反防抓包"
|
||||||
|
android:summary="效果不太明显,目前只能发现账号相关的有反防抓包" />
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
@@ -28,11 +44,13 @@
|
|||||||
android:title="绕过防沉迷"
|
android:title="绕过防沉迷"
|
||||||
android:summary="滞空防沉迷检测方法的调用实现无伤速通破解防沉迷,无需 Player 链接" />
|
android:summary="滞空防沉迷检测方法的调用实现无伤速通破解防沉迷,无需 Player 链接" />
|
||||||
|
|
||||||
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
<PreferenceCategory android:title="已弃用">
|
||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:key="force_rework"
|
android:key="force_show_rework"
|
||||||
android:title="强制显示再创作"
|
android:title="强制显示再创作图标"
|
||||||
android:enabled="false"
|
android:summary="使作品的 再创作 按钮永远显示,即使作品并未设置为开放源代码(显示了也没啥用,服务端给你拦截了:作品未开源)" />
|
||||||
android:summary="使作品的 再创作 按钮永远显示,即使作品并未设置为开放源代码(未制作QWQ)" />
|
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
@@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
### 使用
|
### 使用
|
||||||
|
|
||||||
0. 已安装 LSPosed 框架(由于使用了 XSharedPreferences,故对免 Root 的 Xposed 框架不支持?)
|
0. 建议点个猫版本为 4.3.4,已安装 LSPosed 框架(由于使用了 XSharedPreferences,故免 Root 的 Xposed 框架貌似无法正常运作)
|
||||||
|
|
||||||
1. 从 [Releases](./releases/) 或 [Actions](./actions/) 下载(注:签名不同,除非你有核心破解),普通用户建议下载 Releases 版本
|
1. 从 [Releases](../../releases/) 或 [Actions](../../actions/) 下载(注:签名不同,除非你有核心破解),普通用户建议下载 Releases 版本
|
||||||
|
|
||||||
2. 安装并激活此模块,作用域选择 点个猫(com.codemao.nemo),强制停止
|
2. 安装并激活此模块,作用域选择 点个猫(com.codemao.nemo),强制停止
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
4. 打开点个猫,然后 Enjoy it (≧▽≦)
|
4. 打开点个猫,然后 Enjoy it (≧▽≦)
|
||||||
|
|
||||||
5. 使用过程中存在任何问题欢迎提到 [Issues](./issues/)(需要 GitHub 账号) 或者是我的发布页[评论区](https://shequ.codemao.cn/work/227492197)(需要编程猫账号),建议点个猫版本为 4.5.0
|
5. 使用过程中存在任何问题欢迎提到 [Issues](../../issues/)(需要 GitHub 账号) 或者是我的发布页[评论区](https://shequ.codemao.cn/work/227492197)(需要编程猫账号)
|
||||||
|
|
||||||
(小声BB:我相信各位猫友大多都不晓得这些东西,因此,它可能并不适合你)
|
(小声BB:我相信各位猫友大多都不晓得这些东西,因此,它可能并不适合你)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user