From 45fca818aa7d3c0d77c885e60a2f47bbb15b5d49 Mon Sep 17 00:00:00 2001 From: HChenX Date: Mon, 27 Jan 2025 17:45:45 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=EF=BC=8C=E7=AE=80=E5=8C=96=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 2 +- app/proguard-rules.pro | 6 +- .../main/java/com/hchen/hooktool/BaseHC.java | 15 +- .../java/com/hchen/hooktool/HCEntrance.java | 9 +- .../main/java/com/hchen/hooktool/HCInit.java | 12 +- .../main/java/com/hchen/hooktool/HCState.java | 8 +- .../java/com/hchen/hooktool/ToolTest.java | 48 +-- .../hchen/hooktool/helper/ConvertHelper.java | 2 +- .../com/hchen/hooktool/helper/TryHelper.java | 28 +- .../java/com/hchen/hooktool/hook/IHook.java | 2 +- .../com/hchen/hooktool/log/AndroidLog.java | 2 +- .../com/hchen/hooktool/log/LogExpand.java | 8 +- .../com/hchen/hooktool/tool/ChainTool.java | 18 +- .../com/hchen/hooktool/tool/CoreBase.java | 273 ++++++++++-------- .../com/hchen/hooktool/tool/CoreTool.java | 130 ++++----- .../com/hchen/hooktool/tool/ParamTool.java | 2 +- .../com/hchen/hooktool/tool/SingleMember.java | 59 ++-- .../hooktool/tool/additional/ContextTool.java | 6 +- .../hooktool/tool/additional/DeviceTool.java | 8 +- .../hooktool/tool/additional/PackageTool.java | 4 +- .../tool/additional/ResInjectTool.java | 4 +- .../tool/additional/SystemPropTool.java | 12 +- .../hooktool/tool/itool/IPrefsApply.java | 2 +- 23 files changed, 348 insertions(+), 312 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index abbb913..d548897 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -74,7 +74,7 @@ afterEvaluate { groupId = 'com.github.HChenX' artifactId = 'HookTool' version = defVersion - + artifact androidSourcesJar } } diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 9f647a7..9f42090 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -22,4 +22,8 @@ -keep class * extends com.hchen.hooktool.BaseHC -keep class com.hchen.hooktool.HCEntrance --keep class com.hchen.hooktool.HCState \ No newline at end of file +-keep class com.hchen.hooktool.HCState { + static boolean isEnabled; + static java.lang.String mFramework; + static int mVersion; + } \ No newline at end of file diff --git a/app/src/main/java/com/hchen/hooktool/BaseHC.java b/app/src/main/java/com/hchen/hooktool/BaseHC.java index eb0f792..32d5e4c 100644 --- a/app/src/main/java/com/hchen/hooktool/BaseHC.java +++ b/app/src/main/java/com/hchen/hooktool/BaseHC.java @@ -99,7 +99,7 @@ protected void onApplicationAfter(Context context) { } /** - * 发生崩溃时回调,不要在这里继续执行 hook 逻辑。 + * 发生崩溃时回调,可用于清理操作;不要在这里继续执行 hook 或可能引发崩溃的逻辑。 */ protected void onThrowable(Throwable throwable) { } @@ -128,11 +128,16 @@ final public void onClassLoader(ClassLoader classLoader) { // Hook Application final public BaseHC onApplicationCreate() { - if (!enabled()) return this; + try { + if (!enabled()) return this; - if (!mIApplications.contains(this)) - mIApplications.add(this); - initApplicationHook(); + if (!mIApplications.contains(this)) + mIApplications.add(this); + initApplicationHook(); + } catch (Throwable e) { + onThrowable(e); + logE(TAG, "Waring! can't hook application!!", e); + } return this; } diff --git a/app/src/main/java/com/hchen/hooktool/HCEntrance.java b/app/src/main/java/com/hchen/hooktool/HCEntrance.java index ee79d03..25f3463 100644 --- a/app/src/main/java/com/hchen/hooktool/HCEntrance.java +++ b/app/src/main/java/com/hchen/hooktool/HCEntrance.java @@ -55,19 +55,18 @@ public void onInitZygote(StartupParam startupParam) throws Throwable { *

* Tip: 因为传入的 lpparam 偶尔会被其他系统应用干扰,所以可以配置排除名单。 */ - public String[] ignoreList() { + public String[] ignorePackageNameList() { return null; } @Override public final void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable { - if (ignoreList() != null) { - if (Arrays.stream(ignoreList()).anyMatch(s -> Objects.equals(s, lpparam.packageName))) + if (ignorePackageNameList() != null) { + if (Arrays.stream(ignorePackageNameList()).anyMatch(s -> Objects.equals(s, lpparam.packageName))) return; } - if (HCData.getModulePackageName() != null && !HCData.getModulePackageName().isEmpty() - && Objects.equals(HCData.getModulePackageName(), lpparam.packageName)) { + if (HCData.getModulePackageName() != null && Objects.equals(HCData.getModulePackageName(), lpparam.packageName)) { initHCState(); } diff --git a/app/src/main/java/com/hchen/hooktool/HCInit.java b/app/src/main/java/com/hchen/hooktool/HCInit.java index 8ee4cf2..df53210 100644 --- a/app/src/main/java/com/hchen/hooktool/HCInit.java +++ b/app/src/main/java/com/hchen/hooktool/HCInit.java @@ -46,11 +46,11 @@ public final class HCInit { // ------- END -------------- @IntDef(value = { - LOG_NONE, - LOG_I, - LOG_W, - LOG_E, - LOG_D + LOG_NONE, + LOG_I, + LOG_W, + LOG_E, + LOG_D }) @Retention(RetentionPolicy.SOURCE) private @interface LogLevel { @@ -144,7 +144,7 @@ public BasicData setModulePackageName(@NonNull String modulePackageName) { } // 设置日志 TAG。Tip: 建议设置。 - public BasicData setTag(String tag) { + public BasicData setTag(@NonNull String tag) { this.tag = tag; return this; } diff --git a/app/src/main/java/com/hchen/hooktool/HCState.java b/app/src/main/java/com/hchen/hooktool/HCState.java index e5f340b..3a182c1 100644 --- a/app/src/main/java/com/hchen/hooktool/HCState.java +++ b/app/src/main/java/com/hchen/hooktool/HCState.java @@ -39,8 +39,12 @@ *

* 记得配置混淆,否则不可用: *

- * {@code - * -keep class com.hchen.hooktool.HCState + *

{@code
+ * -keep class  com.hchen.hooktool.HCState {
+ *         static boolean isEnabled;
+ *         static java.lang.String mFramework;
+ *         static int  mVersion;
+ * }
  * }
  *
  * @author 焕晨HChen
diff --git a/app/src/main/java/com/hchen/hooktool/ToolTest.java b/app/src/main/java/com/hchen/hooktool/ToolTest.java
index 806937d..50915d7 100644
--- a/app/src/main/java/com/hchen/hooktool/ToolTest.java
+++ b/app/src/main/java/com/hchen/hooktool/ToolTest.java
@@ -50,23 +50,23 @@ public void initZygote(IXposedHookZygoteInit.StartupParam startupParam) {
     public void init() {
         // 链式
         chain("com.hchen.demo", method("test")
-                .hook(new IHook() {
-                    @Override
-                    public void before() {
-                        super.before();
-                    }
-                })
-
-                .method("test1", String.class)
-                .hook(new IHook() {
-                    @Override
-                    public void after() {
-                        super.after();
-                    }
-                })
-
-                .constructor()
-                .returnResult(false)
+            .hook(new IHook() {
+                @Override
+                public void before() {
+                    super.before();
+                }
+            })
+
+            .method("test1", String.class)
+            .hook(new IHook() {
+                @Override
+                public void after() {
+                    super.after();
+                }
+            })
+
+            .constructor()
+            .returnResult(false)
         );
 
         hookMethod("com.hchen.demo", "test", new IHook() {
@@ -132,13 +132,13 @@ private static class InitHook extends HCEntrance {
         @Override
         public HCInit.BasicData initHC(HCInit.BasicData basicData) {
             return basicData.setTag("HookTool")
-                    .setLogLevel(HCInit.LOG_D)
-                    .setModulePackageName("com.hchen.demo")
-                    .setPrefsName("myprefs") // 可选
-                    .xPrefsAutoReload(true) // 可选
-                    .initLogExpand(new String[]{
-                            "com.hchen.demo.hook"
-                    });
+                .setLogLevel(HCInit.LOG_D)
+                .setModulePackageName("com.hchen.demo")
+                .setPrefsName("myprefs") // 可选
+                .xPrefsAutoReload(true) // 可选
+                .initLogExpand(new String[]{
+                    "com.hchen.demo.hook"
+                });
         }
 
         @Override
diff --git a/app/src/main/java/com/hchen/hooktool/helper/ConvertHelper.java b/app/src/main/java/com/hchen/hooktool/helper/ConvertHelper.java
index a1dfd2b..28dc0d6 100644
--- a/app/src/main/java/com/hchen/hooktool/helper/ConvertHelper.java
+++ b/app/src/main/java/com/hchen/hooktool/helper/ConvertHelper.java
@@ -62,7 +62,7 @@ public static Class[] arrayToClass(ClassLoader classLoader, Object... objs) {
             if (o instanceof Class c) {
                 classes.add(c);
             } else if (o instanceof String s) {
-                Class ct = findClass(s, classLoader).get();
+                Class ct = findClass(s, classLoader);
                 if (ct == null) return null;
                 classes.add(ct);
             } else if (o instanceof IHook) {
diff --git a/app/src/main/java/com/hchen/hooktool/helper/TryHelper.java b/app/src/main/java/com/hchen/hooktool/helper/TryHelper.java
index 7be601c..03653c0 100644
--- a/app/src/main/java/com/hchen/hooktool/helper/TryHelper.java
+++ b/app/src/main/java/com/hchen/hooktool/helper/TryHelper.java
@@ -21,8 +21,6 @@
 import static com.hchen.hooktool.log.LogExpand.getTag;
 import static com.hchen.hooktool.log.XposedLog.logE;
 
-import com.hchen.hooktool.tool.SingleMember;
-
 /**
  * 方法执行与异常处理类
  *
@@ -36,13 +34,6 @@ public static  Result run(Run supplier) {
         return new Result<>(supplier);
     }
 
-    /*
-     * 执行并储存执行的结果与抛错。
-     * */
-    public static  SingleMember createSingleMember(Run supplier) {
-        return new Result<>(supplier).create();
-    }
-
     /*
      * 简单的执行代码并获取返回值,与此同时主动抛出可能的异常。
      */
@@ -71,10 +62,6 @@ private void doRun(Run supplier) {
             }
         }
 
-        private SingleMember create() {
-            return new SingleMember(mResult, mThrowable);
-        }
-
         // 获取执行结果
         public V get() {
             return mResult;
@@ -86,14 +73,19 @@ public V or(V or) {
             return or;
         }
 
+        // 获取抛错
+        public Throwable getThrowable() {
+            return mThrowable;
+        }
+
         // 如果失败返回指定 or 值,并执行异常回调
-        public V orErr(V or, Err err) {
+        public V orError(V or, Error error) {
             if (isSuccess) return mResult;
-            err.err(mThrowable);
+            error.error(mThrowable);
             return or;
         }
 
-        public V orErrMag(V or, String msg) {
+        public V orErrorMag(V or, String msg) {
             if (isSuccess) return mResult;
             logE(getTag(), msg, mThrowable);
             return or;
@@ -108,8 +100,8 @@ public boolean isFailed() {
             return !isSuccess;
         }
 
-        public interface Err {
-            void err(Throwable throwable);
+        public interface Error {
+            void error(Throwable throwable);
         }
     }
 }
diff --git a/app/src/main/java/com/hchen/hooktool/hook/IHook.java b/app/src/main/java/com/hchen/hooktool/hook/IHook.java
index 03ada68..5a4300a 100644
--- a/app/src/main/java/com/hchen/hooktool/hook/IHook.java
+++ b/app/src/main/java/com/hchen/hooktool/hook/IHook.java
@@ -23,7 +23,7 @@
 
 /**
  * Hook 动作接口
- * 
+ *
  * @author 焕晨HChen
  */
 public abstract class IHook extends ParamTool {
diff --git a/app/src/main/java/com/hchen/hooktool/log/AndroidLog.java b/app/src/main/java/com/hchen/hooktool/log/AndroidLog.java
index 9adc64f..263c5d4 100644
--- a/app/src/main/java/com/hchen/hooktool/log/AndroidLog.java
+++ b/app/src/main/java/com/hchen/hooktool/log/AndroidLog.java
@@ -24,7 +24,7 @@
 
 /**
  * 安卓日志
- * 
+ *
  * @author 焕晨HChen
  */
 public final class AndroidLog {
diff --git a/app/src/main/java/com/hchen/hooktool/log/LogExpand.java b/app/src/main/java/com/hchen/hooktool/log/LogExpand.java
index 38997c7..2bb8ca7 100644
--- a/app/src/main/java/com/hchen/hooktool/log/LogExpand.java
+++ b/app/src/main/java/com/hchen/hooktool/log/LogExpand.java
@@ -74,9 +74,9 @@ public void accept(StackTraceElement stackTraceElement) {
                 String field = stackTraceElement.getFileName();
                 int line = stackTraceElement.getLineNumber();
                 stringBuilder.append("\nat ").append(clazz).append(".")
-                        .append(method).append("(")
-                        .append(field).append(":")
-                        .append(line).append(")");
+                    .append(method).append("(")
+                    .append(field).append(":")
+                    .append(line).append(")");
             }
         });
         return stringBuilder.toString();
@@ -145,7 +145,7 @@ public void detailedLogs() {
         StringBuilder log = new StringBuilder();
         for (int i = 0; i < param.args.length; i++) {
             log.append("    (").append(param.args[i] == null ? "null" : param.args[i].getClass().getSimpleName())
-                    .append(")->").append("[").append(paramToString(param.args[i])).append("]\n");
+                .append(")->").append("[").append(paramToString(param.args[i])).append("]\n");
         }
         logI(TAG, "Method called! Class: [" + className + "], Method: [" + methodName + "]\nParam: {\n" + log + "}");
     }
diff --git a/app/src/main/java/com/hchen/hooktool/tool/ChainTool.java b/app/src/main/java/com/hchen/hooktool/tool/ChainTool.java
index 6ca9a47..6f4b651 100644
--- a/app/src/main/java/com/hchen/hooktool/tool/ChainTool.java
+++ b/app/src/main/java/com/hchen/hooktool/tool/ChainTool.java
@@ -66,11 +66,11 @@ public ChainTool() {
     }
 
     public static void chain(String clazz, ChainTool chain) {
-        chain.doFind(findClass(clazz).get());
+        chain.doFind(findClass(clazz));
     }
 
     public static void chain(String clazz, ClassLoader classLoader, ChainTool chain) {
-        chain.doFind(findClass(clazz, classLoader).get());
+        chain.doFind(findClass(clazz, classLoader));
     }
 
     public static void chain(Class clazz, ChainTool chain) {
@@ -137,19 +137,19 @@ private void doFind(Class clazz) {
                 case TYPE_METHOD -> {
                     if (cacheData.mCheckExist)
                         if (!existsMethod(clazz, cacheData.mName, cacheData.mParams)) continue;
-                    members.add(new ChainData(findMethod(clazz, cacheData.mName, cacheData.mParams).get()));
+                    members.add(new ChainData(findMethod(clazz, cacheData.mName, cacheData.mParams)));
                 }
                 case TYPE_CONSTRUCTOR -> {
                     if (cacheData.mCheckExist)
                         if (!existsConstructor(clazz, cacheData.mParams)) continue;
-                    members.add(new ChainData(findConstructor(clazz, cacheData.mParams).get()));
+                    members.add(new ChainData(findConstructor(clazz, cacheData.mParams)));
                 }
                 case TYPE_ANY_METHOD ->
-                        members.addAll(Arrays.stream(CoreTool.findAllMethod(clazz, cacheData.mName)).map(
-                                ChainData::new).collect(Collectors.toCollection(ArrayList::new)));
+                    members.addAll(Arrays.stream(CoreTool.findAllMethod(clazz, cacheData.mName)).map(
+                        ChainData::new).collect(Collectors.toCollection(ArrayList::new)));
                 case TYPE_ANY_CONSTRUCTOR ->
-                        members.addAll(Arrays.stream(CoreTool.findAllConstructor(clazz)).map(
-                                ChainData::new).collect(Collectors.toCollection(ArrayList::new)));
+                    members.addAll(Arrays.stream(CoreTool.findAllConstructor(clazz)).map(
+                        ChainData::new).collect(Collectors.toCollection(ArrayList::new)));
                 default -> {
                     logW(getTag(), "Unknown type: " + cacheData.mType + getStackTrace());
                     members.clear();
@@ -164,7 +164,7 @@ private void doFind(Class clazz) {
                     if (memberData.member == null || existingMembers.contains(memberData.member)) {
                         iterator.remove();
                         logW(getTag(), "This member maybe repeated or maybe is null, will remove it! " +
-                                "\ndebug: " + UUID + "#member: " + memberData.member);
+                            "\ndebug: " + UUID + "#member: " + memberData.member);
                         continue;
                     }
                     existingMembers.add(memberData.member);
diff --git a/app/src/main/java/com/hchen/hooktool/tool/CoreBase.java b/app/src/main/java/com/hchen/hooktool/tool/CoreBase.java
index 4cc0448..7d8d31a 100644
--- a/app/src/main/java/com/hchen/hooktool/tool/CoreBase.java
+++ b/app/src/main/java/com/hchen/hooktool/tool/CoreBase.java
@@ -19,7 +19,6 @@
 package com.hchen.hooktool.tool;
 
 import static com.hchen.hooktool.helper.ConvertHelper.arrayToClass;
-import static com.hchen.hooktool.helper.TryHelper.createSingleMember;
 import static com.hchen.hooktool.helper.TryHelper.run;
 import static com.hchen.hooktool.hook.HookFactory.createHook;
 import static com.hchen.hooktool.log.LogExpand.getStackTrace;
@@ -27,12 +26,10 @@
 import static com.hchen.hooktool.log.XposedLog.logE;
 import static com.hchen.hooktool.log.XposedLog.logI;
 import static com.hchen.hooktool.log.XposedLog.logW;
-import static com.hchen.hooktool.tool.CoreTool.callMethod;
 import static com.hchen.hooktool.tool.CoreTool.callStaticMethod;
-import static com.hchen.hooktool.tool.CoreTool.findConstructor;
-import static com.hchen.hooktool.tool.CoreTool.findMethod;
+import static com.hchen.hooktool.tool.SingleMember.createSingleMember;
 
-import com.hchen.hooktool.helper.TryHelper;
+import com.hchen.hooktool.HCData;
 import com.hchen.hooktool.hook.IHook;
 import com.hchen.hooktool.tool.itool.IMemberFilter;
 
@@ -55,61 +52,64 @@
  * @author 焕晨HChen
  */
 final class CoreBase {
-    private CoreBase() {
+    static SingleMember> baseFindClass(String name) {
+        return baseFindClass(name, HCData.getClassLoader());
     }
 
     static SingleMember> baseFindClass(String name, ClassLoader classLoader) {
-        return TryHelper.>createSingleMember(() ->
-                XposedHelpers.findClass(name, classLoader)
-        ).setErrMsg("Failed to find class, classLoader: " + classLoader);
+        return SingleMember.>createSingleMember(() ->
+            XposedHelpers.findClass(name, classLoader)
+        ).setErrorMsg("Failed to find class!! classLoader: " + classLoader);
     }
 
     static SingleMember baseFindMethod(SingleMember> clazz, String name, Object... objs) {
-        return clazz.reportOrRun(member ->
-                        createSingleMember(
-                                () -> XposedHelpers.findMethodExact(member, name, arrayToClass(member.getClassLoader(), objs))
-                        ).setErrMsg("Failed to find method!"),
-                new SingleMember<>(null));
+        return clazz.exec(new SingleMember<>(),
+            member ->
+                createSingleMember(
+                    () -> XposedHelpers.findMethodExact(member, name, arrayToClass(member.getClassLoader(), objs)))
+                    .setErrorMsg("Failed to find method!"));
     }
 
     static Method[] baseFindAllMethod(SingleMember> clazz, String name) {
-        return clazz.reportOrRun(member ->
-                        createSingleMember(
-                                () -> Arrays.stream(member.getDeclaredMethods())
-                                        .filter(method -> name.equals(method.getName()))
-                                        .toArray(Method[]::new)
-                        ).setErrMsg("Failed to find all method!").or(new Method[0]),
-                new Method[0]);
+        return clazz.exec(new Method[0],
+            member ->
+                createSingleMember(
+                    () -> Arrays.stream(member.getDeclaredMethods())
+                        .filter(method -> name.equals(method.getName()))
+                        .toArray(Method[]::new)
+                ).setErrorMsg("Failed to find all method!")
+                    .or(new Method[0]));
     }
 
     static SingleMember> baseFindConstructor(SingleMember> clazz, Object... objs) {
-        return clazz.reportOrRun(member ->
-                        createSingleMember(
-                                () -> XposedHelpers.findConstructorExact(member, arrayToClass(member.getClassLoader(), objs))
-                        ).setErrMsg("Failed to find constructor!"),
-                new SingleMember<>(null));
+        return clazz.exec(new SingleMember<>(),
+            member ->
+                SingleMember.>createSingleMember(
+                    () -> XposedHelpers.findConstructorExact(member, arrayToClass(member.getClassLoader(), objs))
+                ).setErrorMsg("Failed to find constructor!"));
     }
 
     static Constructor[] baseFindAllConstructor(SingleMember> clazz) {
-        return clazz.reportOrRun(member ->
-                        createSingleMember(
-                                member::getDeclaredConstructors
-                        ).setErrMsg("Failed to find constructor!").or(new Constructor[0]),
-                new Constructor[0]);
+        return clazz.exec(new Constructor[0],
+            member ->
+                createSingleMember(
+                    member::getDeclaredConstructors
+                ).setErrorMsg("Failed to find constructor!")
+                    .or(new Constructor[0]));
     }
 
     static SingleMember baseFindField(SingleMember> clazz, String name) {
-        return clazz.reportOrRun(member ->
-                        createSingleMember(
-                                () -> XposedHelpers.findField(member, name)
-                        ).setErrMsg("Failed to find field!"),
-                new SingleMember<>(null));
+        return clazz.exec(new SingleMember<>(),
+            member ->
+                createSingleMember(
+                    () -> XposedHelpers.findField(member, name)
+                ).setErrorMsg("Failed to find field!"));
     }
 
     static XC_MethodHook.Unhook baseHook(SingleMember> clazz, String method, Object... params) {
         String tag = getTag();
-        String debug = (method != null ? "METHOD" : "CONSTRUCTOR") + "#" + (clazz.getNoReport() == null ? "null" : clazz.getNoReport().getName())
-                + "#" + method + "#" + Arrays.toString(params);
+        String debug = (method != null ? "METHOD" : "CONSTRUCTOR") + "#" + (clazz.getNotReport() == null ? "null" : clazz.getNotReport().getName())
+            + "#" + method + "#" + Arrays.toString(params);
         if (params == null || params.length == 0 || !(params[params.length - 1] instanceof IHook iHook)) {
             logW(tag, "Hook params is null or length is 0 or last param not is IAction! \ndebug: " + debug + getStackTrace());
             return null;
@@ -120,21 +120,21 @@ static XC_MethodHook.Unhook baseHook(SingleMember> clazz, String method
             return null;
         }
 
-        SingleMember member;
+        SingleMember member;
         if (method != null)
-            member = findMethod(clazz.getNoReport(), method, params);
+            member = (SingleMember) (SingleMember) baseFindMethod(new SingleMember<>(clazz.getNotReport()), method, params);
         else
-            member = findConstructor(clazz.getNoReport(), params);
+            member = (SingleMember) (SingleMember) baseFindConstructor(new SingleMember<>(clazz.getNotReport()), params);
         if (member.getThrowable() != null) {
             logE(tag, "Failed to hook! \ndebug: " + debug, member.getThrowable());
             return null;
         }
 
         return run(() -> {
-            XC_MethodHook.Unhook unHook = XposedBridge.hookMethod(((SingleMember) member).getNoReport(), createHook(tag, iHook));
-            logI(tag, "Success to hook: " + member.getNoReport());
+            XC_MethodHook.Unhook unHook = XposedBridge.hookMethod(member.getNotReport(), createHook(tag, iHook));
+            logI(tag, "Success to hook: " + member.getNotReport());
             return unHook;
-        }).orErrMag(null, "Failed to hook! \ndebug: " + debug);
+        }).orErrorMag(null, "Failed to hook! \ndebug: " + debug);
     }
 
     static  XC_MethodHook.Unhook[] baseHookAll(List members, IHook iHook) {
@@ -146,15 +146,15 @@ static XC_MethodHook.Unhook[] baseHookAll(Member[] members, IHook iHook) {
         String tag = getTag();
 
         return Arrays.stream(members).map(member ->
-                        run(() -> {
-                                    XC_MethodHook.Unhook unhook = XposedBridge.hookMethod(member, createHook(tag, iHook));
-                                    logI(tag, "Success to hook: " + member);
-                                    return unhook;
-                                }
-                        ).orErrMag(null, "Failed to hook: " + member)
-                )
-                .filter(Objects::nonNull)
-                .toArray(XC_MethodHook.Unhook[]::new);
+                run(() -> {
+                        XC_MethodHook.Unhook unhook = XposedBridge.hookMethod(member, createHook(tag, iHook));
+                        logI(tag, "Success to hook: " + member);
+                        return unhook;
+                    }
+                ).orErrorMag(null, "Failed to hook: " + member)
+            )
+            .filter(Objects::nonNull)
+            .toArray(XC_MethodHook.Unhook[]::new);
     }
 
     static XC_MethodHook.Unhook baseFirstUnhook(XC_MethodHook.Unhook[] unhooks) {
@@ -163,34 +163,39 @@ static XC_MethodHook.Unhook baseFirstUnhook(XC_MethodHook.Unhook[] unhooks) {
     }
 
     static Method[] baseFilterMethod(SingleMember> clazz, IMemberFilter iMemberFilter) {
-        return clazz.reportOrRun(member ->
-                        createSingleMember(
-                                () -> Arrays.stream(member.getDeclaredMethods())
-                                        .filter(iMemberFilter::test)
-                                        .toArray(Method[]::new)
-                        ).setErrMsg("Failed to filter method!").or(new Method[0]),
-                new Method[0]);
+        return clazz.exec(new Method[0],
+            member ->
+                createSingleMember(
+                    () -> Arrays.stream(member.getDeclaredMethods())
+                        .filter(iMemberFilter::test)
+                        .toArray(Method[]::new)
+                ).setErrorMsg("Failed to filter method!")
+                    .or(new Method[0])
+        );
     }
 
     static Constructor[] baseFilterConstructor(SingleMember> clazz, IMemberFilter> iMemberFilter) {
-        return clazz.reportOrRun(member ->
-                        createSingleMember(
-                                () -> Arrays.stream(member.getDeclaredConstructors())
-                                        .filter(iMemberFilter::test)
-                                        .toArray(Constructor[]::new)
-                        ).setErrMsg("Failed to filter constructor!").or(new Constructor[0]),
-                new Constructor[0]);
+        return clazz.exec(new Constructor[0],
+            member ->
+                createSingleMember(
+                    () -> Arrays.stream(member.getDeclaredConstructors())
+                        .filter(iMemberFilter::test)
+                        .toArray(Constructor[]::new)
+                ).setErrorMsg("Failed to filter constructor!")
+                    .or(new Constructor[0])
+        );
     }
 
     static Object baseCallMethod(Object instance, Object type, Object... objs) {
         if (type instanceof String name) {
-            return run(() -> XposedHelpers.callMethod(instance, name, objs))
-                    .orErrMag(null, "Failed to call method!");
+            return run(
+                () -> XposedHelpers.callMethod(instance, name, objs)
+            ).orErrorMag(null, "Failed to call method!");
         } else if (type instanceof Method method) {
             return run(() -> {
                 method.setAccessible(true);
                 return method.invoke(instance, objs);
-            }).orErrMag(null, "Failed to call method!");
+            }).orErrorMag(null, "Failed to call method!");
         }
         return null;
     }
@@ -200,19 +205,20 @@ static Object baseCallSuperPrivateMethod(Object instance, String name, Object...
             Method method = baseGetSuperPrivateMethod(instance.getClass(), name, objs);
             if (method == null) return null;
 
-            return callMethod(instance, method, objs);
-        }).orErrMag(null, "Failed to call super private method!");
+            return baseCallMethod(instance, method, objs);
+        }).orErrorMag(null, "Failed to call super private method!");
     }
 
     static Object baseGetField(Object instance, Object type) {
         if (type instanceof String name) {
-            return run(() -> XposedHelpers.getObjectField(instance, name))
-                    .orErrMag(null, "Failed to get field!");
+            return run(
+                () -> XposedHelpers.getObjectField(instance, name)
+            ).orErrorMag(null, "Failed to get field!");
         } else if (type instanceof Field field) {
             return run(() -> {
                 field.setAccessible(true);
                 return field.get(instance);
-            }).orErrMag(null, "Failed to get field!");
+            }).orErrorMag(null, "Failed to get field!");
         }
         return null;
     }
@@ -222,102 +228,119 @@ static boolean baseSetField(Object instance, Object type, Object value) {
             return run(() -> {
                 XposedHelpers.setObjectField(instance, name, value);
                 return true;
-            }).orErrMag(false, "Failed to set field!");
+            }).orErrorMag(false, "Failed to set field!");
         } else if (type instanceof Field field) {
             return run(() -> {
                 field.setAccessible(true);
                 field.set(instance, value);
                 return true;
-            }).orErrMag(false, "Failed to set field!");
+            }).orErrorMag(false, "Failed to set field!");
         }
         return false;
     }
 
     static Object baseNewInstance(SingleMember> clz, Object... objs) {
-        return clz.reportOrRun(member ->
-                        createSingleMember(
-                                () -> XposedHelpers.newInstance(member, objs)
-                        ).setErrMsg("Failed to create new instance!").or(null),
-                null);
+        return clz.exec(null,
+            member ->
+                createSingleMember(
+                    () -> XposedHelpers.newInstance(member, objs)
+                ).setErrorMsg("Failed to create new instance!")
+                    .or(null)
+        );
     }
 
     static Object baseCallStaticMethod(SingleMember> clz, Method method, String name, Object... objs) {
         if (clz != null)
-            return clz.reportOrRun(member ->
-                            createSingleMember(
-                                    () -> XposedHelpers.callStaticMethod(member, name, objs)
-                            ).setErrMsg("Failed to call static method!").or(null),
-                    null);
+            return clz.exec(null,
+                member ->
+                    createSingleMember(
+                        () -> XposedHelpers.callStaticMethod(member, name, objs)
+                    ).setErrorMsg("Failed to call static method!")
+                        .or(null)
+            );
         else
             return run(() -> {
                 method.setAccessible(true);
                 return method.invoke(null, objs);
-            }).orErrMag(null, "Failed to call static method!");
+            }).orErrorMag(null, "Failed to call static method!");
     }
 
     static Object baseCallSuperStaticPrivateMethod(SingleMember> clz, String name, Object... objs) {
-        return clz.reportOrRun(member ->
-                        createSingleMember(() -> {
-                                    Method method = baseGetSuperPrivateMethod(member, name, objs);
-                                    if (method == null) return null;
-                                    return callStaticMethod(method, objs);
-                                }
-                        ).setErrMsg("Failed to call super private static field!").or(null),
-                null);
+        return clz.exec(null,
+            member ->
+                createSingleMember(() -> {
+                        Method method = baseGetSuperPrivateMethod(member, name, objs);
+                        if (method == null) return null;
+
+                        return callStaticMethod(method, objs);
+                    }
+                ).setErrorMsg("Failed to call super private static field!")
+                    .or(null)
+        );
     }
 
     static Object baseGetStaticField(SingleMember> clz, Field field, String name) {
         if (clz != null)
-            return clz.reportOrRun(member ->
-                            createSingleMember(
-                                    () -> XposedHelpers.getStaticObjectField(member, name)
-                            ).setErrMsg("Failed to get static field!").or(null),
-                    null);
+            return clz.exec(null,
+                member ->
+                    createSingleMember(
+                        () -> XposedHelpers.getStaticObjectField(member, name)
+                    ).setErrorMsg("Failed to get static field!")
+                        .or(null)
+            );
         else
             return run(() -> {
                 field.setAccessible(true);
                 return field.get(null);
-            }).orErrMag(null, "Failed to get static field!");
+            }).orErrorMag(null, "Failed to get static field!");
     }
 
     static boolean baseSetStaticField(SingleMember> clz, Field field, String name, Object value) {
         if (clz != null)
-            return clz.reportOrRun(member ->
-                            createSingleMember(() -> {
-                                XposedHelpers.setStaticObjectField(member, name, value);
-                                return true;
-                            }).setErrMsg("Failed to set static field!").or(false),
-                    false);
+            return clz.exec(false,
+                member ->
+                    createSingleMember(() -> {
+                        XposedHelpers.setStaticObjectField(member, name, value);
+                        return true;
+                    }).setErrorMsg("Failed to set static field!")
+                        .or(false)
+            );
         else
             return run(() -> {
                 field.setAccessible(true);
                 field.set(null, value);
                 return true;
-            }).orErrMag(false, "Failed to set static field!");
+            }).orErrorMag(false, "Failed to set static field!");
     }
 
     static Object baseSetAdditionalStaticField(SingleMember> clz, String key, Object value) {
-        return clz.reportOrRun(member ->
-                        createSingleMember(
-                                () -> XposedHelpers.setAdditionalStaticField(member, key, value)
-                        ).setErrMsg("Failed to set static additional instance!").or(null),
-                null);
+        return clz.exec(null,
+            member ->
+                createSingleMember(
+                    () -> XposedHelpers.setAdditionalStaticField(member, key, value)
+                ).setErrorMsg("Failed to set static additional instance!")
+                    .or(null)
+        );
     }
 
     static Object baseGetAdditionalStaticField(SingleMember> clz, String key) {
-        return clz.reportOrRun(member ->
-                        createSingleMember(
-                                () -> XposedHelpers.getAdditionalStaticField(member, key)
-                        ).setErrMsg("Failed to get static additional instance!").or(null),
-                null);
+        return clz.exec(null,
+            member ->
+                createSingleMember(
+                    () -> XposedHelpers.getAdditionalStaticField(member, key)
+                ).setErrorMsg("Failed to get static additional instance!")
+                    .or(null)
+        );
     }
 
     static Object baseRemoveAdditionalStaticField(SingleMember> clz, String key) {
-        return clz.reportOrRun(member ->
-                        createSingleMember(
-                                () -> XposedHelpers.removeAdditionalStaticField(member, key)
-                        ).setErrMsg("Failed to remove static additional instance!").or(null),
-                null);
+        return clz.exec(null,
+            member ->
+                createSingleMember(
+                    () -> XposedHelpers.removeAdditionalStaticField(member, key)
+                ).setErrorMsg("Failed to remove static additional instance!")
+                    .or(null)
+        );
     }
 
     private static Method baseGetSuperPrivateMethod(Class clz, String name, Object... objs) {
@@ -337,6 +360,6 @@ private static Method baseGetSuperPrivateMethod(Class clz, String name, Objec
             } while ((clazz = clazz.getSuperclass()) != null);
 
             return method;
-        }).orErrMag(null, "Failed to get super private method!");
+        }).orErrorMag(null, "Failed to get super private method!");
     }
 }
diff --git a/app/src/main/java/com/hchen/hooktool/tool/CoreTool.java b/app/src/main/java/com/hchen/hooktool/tool/CoreTool.java
index 4be19fa..f80471a 100644
--- a/app/src/main/java/com/hchen/hooktool/tool/CoreTool.java
+++ b/app/src/main/java/com/hchen/hooktool/tool/CoreTool.java
@@ -77,38 +77,38 @@ public static boolean existsClass(String clazz) {
     }
 
     public static boolean existsClass(String clazz, ClassLoader classLoader) {
-        return findClass(clazz, classLoader).isSuccess();
+        return baseFindClass(clazz, classLoader).isSuccess();
     }
 
     // --------- 查找类 -----------
-    public static SingleMember> findClass(String name) {
+    public static Class findClass(String name) {
         return findClass(name, HCData.getClassLoader());
     }
 
-    public static SingleMember> findClass(String name, ClassLoader classLoader) {
-        return baseFindClass(name, classLoader);
+    public static Class findClass(String name, ClassLoader classLoader) {
+        return baseFindClass(name, classLoader).get();
     }
 
     //------------ 检查指定方法是否存在 --------------
     public static boolean existsMethod(String clazz, String name, Object... objs) {
-        return existsMethod(findClass(clazz).getNoReport(), name, objs);
+        return existsMethod(baseFindClass(clazz).getNotReport(), name, objs);
     }
 
     public static boolean existsMethod(String clazz, ClassLoader classLoader, String name, Object... objs) {
-        return existsMethod(findClass(clazz, classLoader).getNoReport(), name, objs);
+        return existsMethod(baseFindClass(clazz, classLoader).getNotReport(), name, objs);
     }
 
     public static boolean existsMethod(Class clazz, String name, Object... objs) {
         if (clazz == null || name == null || name.isEmpty() || objs == null) return false;
-        return findMethod(clazz, name, objs).isSuccess();
+        return baseFindMethod(new SingleMember<>(clazz), name, objs).isSuccess();
     }
 
     public static boolean existsAnyMethod(String clazz, String name) {
-        return existsAnyMethod(findClass(clazz).getNoReport(), name);
+        return existsAnyMethod(baseFindClass(clazz).getNotReport(), name);
     }
 
     public static boolean existsAnyMethod(String clazz, ClassLoader classLoader, String name) {
-        return existsAnyMethod(findClass(clazz, classLoader).getNoReport(), name);
+        return existsAnyMethod(baseFindClass(clazz, classLoader).getNotReport(), name);
     }
 
     public static boolean existsAnyMethod(Class clazz, String name) {
@@ -117,24 +117,24 @@ public static boolean existsAnyMethod(Class clazz, String name) {
     }
 
     // ------------ 查找方法 --------------
-    public static SingleMember findMethod(String clazz, String name, Object... objs) {
-        return baseFindMethod(findClass(clazz), name, objs);
+    public static Method findMethod(String clazz, String name, Object... objs) {
+        return baseFindMethod(baseFindClass(clazz), name, objs).get();
     }
 
-    public static SingleMember findMethod(String clazz, ClassLoader classLoader, String name, Object... objs) {
-        return baseFindMethod(findClass(clazz, classLoader), name, objs);
+    public static Method findMethod(String clazz, ClassLoader classLoader, String name, Object... objs) {
+        return baseFindMethod(baseFindClass(clazz, classLoader), name, objs).get();
     }
 
-    public static SingleMember findMethod(Class clazz, String name, Object... objs) {
-        return baseFindMethod(new SingleMember<>(clazz, null), name, objs);
+    public static Method findMethod(Class clazz, String name, Object... objs) {
+        return baseFindMethod(new SingleMember<>(clazz, null), name, objs).get();
     }
 
     public static Method[] findAllMethod(String clazz, String name) {
-        return baseFindAllMethod(findClass(clazz), name);
+        return baseFindAllMethod(baseFindClass(clazz), name);
     }
 
     public static Method[] findAllMethod(String clazz, ClassLoader classLoader, String name) {
-        return baseFindAllMethod(findClass(clazz, classLoader), name);
+        return baseFindAllMethod(baseFindClass(clazz, classLoader), name);
     }
 
     public static Method[] findAllMethod(Class clazz, String name) {
@@ -143,37 +143,37 @@ public static Method[] findAllMethod(Class clazz, String name) {
 
     //------------ 检查指定构造函数是否存在 --------------
     public static boolean existsConstructor(String clazz, Object... objs) {
-        return existsConstructor(findClass(clazz).getNoReport(), objs);
+        return existsConstructor(baseFindClass(clazz).getNotReport(), objs);
     }
 
     public static boolean existsConstructor(String clazz, ClassLoader classLoader, Object... objs) {
-        return existsConstructor(findClass(clazz, classLoader).getNoReport(), objs);
+        return existsConstructor(baseFindClass(clazz, classLoader).getNotReport(), objs);
     }
 
     public static boolean existsConstructor(Class clazz, Object... objs) {
         if (clazz == null || objs == null) return false;
-        return findConstructor(clazz, objs).isSuccess();
+        return baseFindConstructor(new SingleMember<>(clazz), objs).isSuccess();
     }
 
     // --------- 查找构造函数 -----------
-    public static SingleMember> findConstructor(String clazz, Object... objs) {
-        return baseFindConstructor(findClass(clazz), objs);
+    public static Constructor findConstructor(String clazz, Object... objs) {
+        return baseFindConstructor(baseFindClass(clazz), objs).get();
     }
 
-    public static SingleMember> findConstructor(String clazz, ClassLoader classLoader, Object... objs) {
-        return baseFindConstructor(findClass(clazz, classLoader), objs);
+    public static Constructor findConstructor(String clazz, ClassLoader classLoader, Object... objs) {
+        return baseFindConstructor(baseFindClass(clazz, classLoader), objs).get();
     }
 
-    public static SingleMember> findConstructor(Class clazz, Object... objs) {
-        return baseFindConstructor(new SingleMember<>(clazz, null), objs);
+    public static Constructor findConstructor(Class clazz, Object... objs) {
+        return baseFindConstructor(new SingleMember<>(clazz, null), objs).get();
     }
 
     public static Constructor[] findAllConstructor(String clazz) {
-        return baseFindAllConstructor(findClass(clazz));
+        return baseFindAllConstructor(baseFindClass(clazz));
     }
 
     public static Constructor[] findAllConstructor(String clazz, ClassLoader classLoader) {
-        return baseFindAllConstructor(findClass(clazz, classLoader));
+        return baseFindAllConstructor(baseFindClass(clazz, classLoader));
     }
 
     public static Constructor[] findAllConstructor(Class clazz) {
@@ -182,39 +182,39 @@ public static Constructor[] findAllConstructor(Class clazz) {
 
     //------------ 检查指定字段是否存在 --------------
     public static boolean existsField(String clazz, String name) {
-        return existsField(findClass(clazz).getNoReport(), name);
+        return existsField(baseFindClass(clazz).getNotReport(), name);
     }
 
     public static boolean existsField(String clazz, ClassLoader classLoader, String name) {
-        return existsField(findClass(clazz, classLoader).getNoReport(), name);
+        return existsField(baseFindClass(clazz, classLoader).getNotReport(), name);
     }
 
     public static boolean existsField(Class clazz, String name) {
         if (clazz == null || name == null || name.isEmpty()) return false;
-        return findField(clazz, name).isSuccess();
+        return baseFindField(new SingleMember<>(clazz), name).isSuccess();
     }
 
     // --------- 查找字段 -----------
-    public static SingleMember findField(String clazz, String name) {
-        return baseFindField(findClass(clazz), name);
+    public static Field findField(String clazz, String name) {
+        return baseFindField(baseFindClass(clazz), name).get();
     }
 
-    public static SingleMember findField(String clazz, ClassLoader classLoader, String name) {
-        return baseFindField(findClass(clazz, classLoader), name);
+    public static Field findField(String clazz, ClassLoader classLoader, String name) {
+        return baseFindField(baseFindClass(clazz, classLoader), name).get();
     }
 
-    public static SingleMember findField(Class clazz, String name) {
-        return baseFindField(new SingleMember<>(clazz, null), name);
+    public static Field findField(Class clazz, String name) {
+        return baseFindField(new SingleMember<>(clazz, null), name).get();
     }
 
     // --------- 执行 hook -----------
     // --------- 普通方法 -------------
     public static XC_MethodHook.Unhook hookMethod(String clazz, String method, Object... params) {
-        return baseHook(findClass(clazz), method, params);
+        return baseHook(baseFindClass(clazz), method, params);
     }
 
     public static XC_MethodHook.Unhook hookMethod(String clazz, ClassLoader classLoader, String method, Object... params) {
-        return baseHook(findClass(clazz, classLoader), method, params);
+        return baseHook(baseFindClass(clazz, classLoader), method, params);
     }
 
     public static XC_MethodHook.Unhook hookMethod(Class clazz, String method, Object... params) {
@@ -235,11 +235,11 @@ public static XC_MethodHook.Unhook[] hookAllMethod(Class clazz, String method
 
     // --------- 构造函数 ------------
     public static XC_MethodHook.Unhook hookConstructor(String clazz, Object... params) {
-        return baseHook(findClass(clazz), null, params);
+        return baseHook(baseFindClass(clazz), null, params);
     }
 
     public static XC_MethodHook.Unhook hookConstructor(String clazz, ClassLoader classLoader, Object... params) {
-        return baseHook(findClass(clazz, classLoader), null, params);
+        return baseHook(baseFindClass(clazz, classLoader), null, params);
     }
 
     public static XC_MethodHook.Unhook hookConstructor(Class clazz, Object... params) {
@@ -293,11 +293,11 @@ public static void unHook(Member member, XC_MethodHook xcMethodHook) {
 
     // --------- 过滤方法 -----------
     public static Method[] filterMethod(String clazz, IMemberFilter iMemberFilter) {
-        return baseFilterMethod(findClass(clazz), iMemberFilter);
+        return baseFilterMethod(baseFindClass(clazz), iMemberFilter);
     }
 
     public static Method[] filterMethod(String clazz, ClassLoader classLoader, IMemberFilter iMemberFilter) {
-        return baseFilterMethod(findClass(clazz, classLoader), iMemberFilter);
+        return baseFilterMethod(baseFindClass(clazz, classLoader), iMemberFilter);
     }
 
     public static Method[] filterMethod(Class clazz, IMemberFilter iMemberFilter) {
@@ -305,11 +305,11 @@ public static Method[] filterMethod(Class clazz, IMemberFilter iMembe
     }
 
     public static Constructor[] filterConstructor(String clazz, IMemberFilter> iMemberFilter) {
-        return baseFilterConstructor(findClass(clazz), iMemberFilter);
+        return baseFilterConstructor(baseFindClass(clazz), iMemberFilter);
     }
 
     public static Constructor[] filterConstructor(String clazz, ClassLoader classLoader, IMemberFilter> iMemberFilter) {
-        return baseFilterConstructor(findClass(clazz, classLoader), iMemberFilter);
+        return baseFilterConstructor(baseFindClass(clazz, classLoader), iMemberFilter);
     }
 
     public static Constructor[] filterConstructor(Class clazz, IMemberFilter> iMemberFilter) {
@@ -334,7 +334,7 @@ public static long timeConsumption(Runnable runnable) {
             runnable.run();
             Instant end = Instant.now();
             return Duration.between(start, end).toMillis();
-        }).orErrMag(-1L, "Failed to check code time consumption!");
+        }).orErrorMag(-1L, "Failed to check code time consumption!");
     }
 
     // ---------- 非静态 -----------
@@ -368,17 +368,17 @@ public static boolean setField(Object instance, Field field, Object value) {
 
     public static Object setAdditionalInstanceField(Object instance, String key, Object value) {
         return run(() -> XposedHelpers.setAdditionalInstanceField(instance, key, value))
-                .orErrMag(null, "Failed to set additional instance!");
+            .orErrorMag(null, "Failed to set additional instance!");
     }
 
     public static Object getAdditionalInstanceField(Object instance, String key) {
         return run(() -> XposedHelpers.getAdditionalInstanceField(instance, key))
-                .orErrMag(null, "Failed to get additional instance!");
+            .orErrorMag(null, "Failed to get additional instance!");
     }
 
     public static Object removeAdditionalInstanceField(Object instance, String key) {
         return run(() -> XposedHelpers.removeAdditionalInstanceField(instance, key))
-                .orErrMag(null, "Failed to remove additional instance!");
+            .orErrorMag(null, "Failed to remove additional instance!");
     }
 
     // ---------- 静态 ------------
@@ -387,11 +387,11 @@ public static Object newInstance(Class clz, Object... objs) {
     }
 
     public static Object newInstance(String clz, Object... objs) {
-        return baseNewInstance(findClass(clz), objs);
+        return baseNewInstance(baseFindClass(clz), objs);
     }
 
     public static Object newInstance(String clz, ClassLoader classLoader, Object... objs) {
-        return baseNewInstance(findClass(clz, classLoader), objs);
+        return baseNewInstance(baseFindClass(clz, classLoader), objs);
     }
 
     public static Object callStaticMethod(Class clz, String name, Object... objs) {
@@ -399,11 +399,11 @@ public static Object callStaticMethod(Class clz, String name, Object... objs)
     }
 
     public static Object callStaticMethod(String clz, String name, Object... objs) {
-        return baseCallStaticMethod(findClass(clz), null, name, objs);
+        return baseCallStaticMethod(baseFindClass(clz), null, name, objs);
     }
 
     public static Object callStaticMethod(String clz, ClassLoader classLoader, String name, Object... objs) {
-        return baseCallStaticMethod(findClass(clz, classLoader), null, name, objs);
+        return baseCallStaticMethod(baseFindClass(clz, classLoader), null, name, objs);
     }
 
     public static Object callStaticMethod(Method method, Object... objs) {
@@ -411,11 +411,11 @@ public static Object callStaticMethod(Method method, Object... objs) {
     }
 
     public static Object callSuperStaticPrivateMethod(String clz, String name, Object... objs) {
-        return baseCallSuperStaticPrivateMethod(findClass(clz), name, objs);
+        return baseCallSuperStaticPrivateMethod(baseFindClass(clz), name, objs);
     }
 
     public static Object callSuperStaticPrivateMethod(String clz, ClassLoader classLoader, String name, Object... objs) {
-        return baseCallSuperStaticPrivateMethod(findClass(clz, classLoader), name, objs);
+        return baseCallSuperStaticPrivateMethod(baseFindClass(clz, classLoader), name, objs);
     }
 
     public static Object callSuperStaticPrivateMethod(Class clz, String name, Object... objs) {
@@ -427,11 +427,11 @@ public static Object getStaticField(Class clz, String name) {
     }
 
     public static Object getStaticField(String clz, String name) {
-        return baseGetStaticField(findClass(clz), null, name);
+        return baseGetStaticField(baseFindClass(clz), null, name);
     }
 
     public static Object getStaticField(String clz, ClassLoader classLoader, String name) {
-        return baseGetStaticField(findClass(clz, classLoader), null, name);
+        return baseGetStaticField(baseFindClass(clz, classLoader), null, name);
     }
 
     public static Object getStaticField(Field field) {
@@ -443,11 +443,11 @@ public static boolean setStaticField(Class clz, String name, Object value) {
     }
 
     public static boolean setStaticField(String clz, String name, Object value) {
-        return baseSetStaticField(findClass(clz), null, name, value);
+        return baseSetStaticField(baseFindClass(clz), null, name, value);
     }
 
     public static boolean setStaticField(String clz, ClassLoader classLoader, String name, Object value) {
-        return baseSetStaticField(findClass(clz, classLoader), null, name, value);
+        return baseSetStaticField(baseFindClass(clz, classLoader), null, name, value);
     }
 
     public static boolean setStaticField(Field field, Object value) {
@@ -459,11 +459,11 @@ public static Object setAdditionalStaticField(Class clz, String key, Object v
     }
 
     public static Object setAdditionalStaticField(String clz, String key, Object value) {
-        return baseSetAdditionalStaticField(findClass(clz), key, value);
+        return baseSetAdditionalStaticField(baseFindClass(clz), key, value);
     }
 
     public static Object setAdditionalStaticField(String clz, ClassLoader classLoader, String key, Object value) {
-        return baseSetAdditionalStaticField(findClass(clz, classLoader), key, value);
+        return baseSetAdditionalStaticField(baseFindClass(clz, classLoader), key, value);
     }
 
     public static Object getAdditionalStaticField(Class clz, String key) {
@@ -471,11 +471,11 @@ public static Object getAdditionalStaticField(Class clz, String key) {
     }
 
     public static Object getAdditionalStaticField(String clz, String key) {
-        return baseGetAdditionalStaticField(findClass(clz), key);
+        return baseGetAdditionalStaticField(baseFindClass(clz), key);
     }
 
     public static Object getAdditionalStaticField(String clz, ClassLoader classLoader, String key) {
-        return baseGetAdditionalStaticField(findClass(key, classLoader), key);
+        return baseGetAdditionalStaticField(baseFindClass(key, classLoader), key);
     }
 
     public static Object removeAdditionalStaticField(Class clz, String key) {
@@ -483,10 +483,10 @@ public static Object removeAdditionalStaticField(Class clz, String key) {
     }
 
     public static Object removeAdditionalStaticField(String clz, String key) {
-        return baseRemoveAdditionalStaticField(findClass(clz), key);
+        return baseRemoveAdditionalStaticField(baseFindClass(clz), key);
     }
 
     public static Object removeAdditionalStaticField(String clz, ClassLoader classLoader, String key) {
-        return baseRemoveAdditionalStaticField(findClass(clz, classLoader), key);
+        return baseRemoveAdditionalStaticField(baseFindClass(clz, classLoader), key);
     }
 }
diff --git a/app/src/main/java/com/hchen/hooktool/tool/ParamTool.java b/app/src/main/java/com/hchen/hooktool/tool/ParamTool.java
index d17a8b5..4b7fab3 100644
--- a/app/src/main/java/com/hchen/hooktool/tool/ParamTool.java
+++ b/app/src/main/java/com/hchen/hooktool/tool/ParamTool.java
@@ -109,7 +109,7 @@ final public int argsLength() {
     private boolean checkIndex(int index) {
         if (argsLength() < index + 1) {
             logE(PRIVATETAG, "Args available index length is: [" + (argsLength() - 1) +
-                    "] but index is : [" + index + "] , Exceeding!!" + getStackTrace());
+                "] but index is : [" + index + "] , Exceeding!!" + getStackTrace());
             return false;
         }
         return true;
diff --git a/app/src/main/java/com/hchen/hooktool/tool/SingleMember.java b/app/src/main/java/com/hchen/hooktool/tool/SingleMember.java
index b2e3d6a..293e804 100644
--- a/app/src/main/java/com/hchen/hooktool/tool/SingleMember.java
+++ b/app/src/main/java/com/hchen/hooktool/tool/SingleMember.java
@@ -22,6 +22,7 @@
 
 import androidx.annotation.Nullable;
 
+import com.hchen.hooktool.helper.TryHelper;
 import com.hchen.hooktool.log.LogExpand;
 
 /**
@@ -29,75 +30,83 @@
  *
  * @author 焕晨HChen
  */
-public final class SingleMember {
-    private final T mMember;
+public final class SingleMember {
+    private final V mMember;
     private final Throwable mThrowable;
-    private String mMsg = "Unknown";
+    private String mErrorMsg = "Unknown";
 
-    public SingleMember(T member) {
+    SingleMember() {
+        this(null, null);
+    }
+
+    SingleMember(V member) {
         this(member, null);
     }
 
-    public SingleMember(T member, Throwable throwable) {
+    SingleMember(V member, Throwable throwable) {
         mMember = member;
         mThrowable = throwable;
     }
 
     @Nullable
-    public T get() {
+    V get() {
         report();
         return mMember;
     }
 
     @Nullable
-    public T or(T or) {
-        T get = get();
-        if (get == null)
+    V or(V or) {
+        if (isSuccess())
+            return get();
+        else {
+            report();
             return or;
-        return get;
+        }
     }
 
     @Nullable
-    public T getNoReport() {
+    V getNotReport() {
         return mMember;
     }
 
     @Nullable
-    public Throwable getThrowable() {
+    Throwable getThrowable() {
         return mThrowable;
     }
 
-    public boolean isSuccess() {
+    boolean isSuccess() {
         return mThrowable == null;
     }
 
-    SingleMember setErrMsg(String msg) {
-        mMsg = msg;
+    SingleMember setErrorMsg(String msg) {
+        mErrorMsg = msg;
         return this;
     }
 
-    String getErrMsg() {
-        return mMsg;
+    String getErrorMsg() {
+        return mErrorMsg;
     }
 
-    private void report() {
+    void report() {
         if (mThrowable != null)
-            logE(LogExpand.getTag(), mMsg, mThrowable);
+            logE(LogExpand.getTag(), mErrorMsg, mThrowable);
     }
 
-     R reportOrRun(Run run) {
-        return reportOrRun(run, null);
+    static  SingleMember createSingleMember(TryHelper.Run supplier) {
+        TryHelper.Result result = new TryHelper.Result<>(supplier);
+        return new SingleMember<>(result.get(), result.getThrowable());
     }
 
-     R reportOrRun(Run run, R def) {
+     R exec(R def, Exec exec) {
         if (mThrowable != null) {
             report();
             return def;
         }
-        return (R) run.run(mMember);
+
+        return (R) exec.exec(mMember);
     }
 
-    interface Run {
-        Object run(T member);
+    interface Exec {
+        R exec(V value);
     }
 }
diff --git a/app/src/main/java/com/hchen/hooktool/tool/additional/ContextTool.java b/app/src/main/java/com/hchen/hooktool/tool/additional/ContextTool.java
index cc22e7d..3197eaa 100644
--- a/app/src/main/java/com/hchen/hooktool/tool/additional/ContextTool.java
+++ b/app/src/main/java/com/hchen/hooktool/tool/additional/ContextTool.java
@@ -40,9 +40,9 @@
 @SuppressLint({"PrivateApi", "SoonBlockedPrivateApi", "DiscouragedPrivateApi"})
 public final class ContextTool {
     @IntDef(value = {
-            FLAG_ALL,
-            FLAG_CURRENT_APP,
-            FlAG_ONLY_ANDROID
+        FLAG_ALL,
+        FLAG_CURRENT_APP,
+        FlAG_ONLY_ANDROID
     })
     @Retention(RetentionPolicy.SOURCE)
     private @interface Duration {
diff --git a/app/src/main/java/com/hchen/hooktool/tool/additional/DeviceTool.java b/app/src/main/java/com/hchen/hooktool/tool/additional/DeviceTool.java
index 023b11b..005f27f 100644
--- a/app/src/main/java/com/hchen/hooktool/tool/additional/DeviceTool.java
+++ b/app/src/main/java/com/hchen/hooktool/tool/additional/DeviceTool.java
@@ -199,8 +199,8 @@ public static boolean isHarmonyOs() {
         if (!isMoreAndroidVersion(Build.VERSION_CODES.Q)) return false;
         try {
             Object osBrand = InvokeTool.callStaticMethod(
-                    "com.huawei.system.BuildEx",
-                    "getOsBrand", new Class[]{});
+                "com.huawei.system.BuildEx",
+                "getOsBrand", new Class[]{});
             return "Harmony".equalsIgnoreCase(String.valueOf(osBrand));
         } catch (Throwable throwable) {
             logE(getTag(), throwable);
@@ -222,7 +222,7 @@ public static boolean isRightRom(final String... names) {
         if (names == null) return false;
         for (String name : names) {
             if (Build.BRAND.toLowerCase().contains(name.toLowerCase())
-                    || Build.MANUFACTURER.toLowerCase().contains(name.toLowerCase())) {
+                || Build.MANUFACTURER.toLowerCase().contains(name.toLowerCase())) {
                 return true;
             }
         }
@@ -302,7 +302,7 @@ public static boolean isMiuiPad() {
     private static boolean isPadByProp() {
         String mDeviceType = getProp("ro.build.characteristics", "default");
         return (mDeviceType != null && mDeviceType.toLowerCase().contains("tablet"))
-                || getProp("persist.sys.muiltdisplay_type", 0) == 2;
+            || getProp("persist.sys.muiltdisplay_type", 0) == 2;
     }
 
     private static boolean isPadBySize(Context context) {
diff --git a/app/src/main/java/com/hchen/hooktool/tool/additional/PackageTool.java b/app/src/main/java/com/hchen/hooktool/tool/additional/PackageTool.java
index 12b95ee..66d462d 100644
--- a/app/src/main/java/com/hchen/hooktool/tool/additional/PackageTool.java
+++ b/app/src/main/java/com/hchen/hooktool/tool/additional/PackageTool.java
@@ -124,8 +124,8 @@ public static boolean isHidden(Context context, String pkg) {
      */
     public static int getUserId(int uid) {
         return (int) Optional.ofNullable(
-                        InvokeTool.callStaticMethod(UserHandle.class, "getUserId", new Class[]{int.class}, uid))
-                .orElse(-1);
+                InvokeTool.callStaticMethod(UserHandle.class, "getUserId", new Class[]{int.class}, uid))
+            .orElse(-1);
     }
 
     /**
diff --git a/app/src/main/java/com/hchen/hooktool/tool/additional/ResInjectTool.java b/app/src/main/java/com/hchen/hooktool/tool/additional/ResInjectTool.java
index 69c3046..f368b03 100644
--- a/app/src/main/java/com/hchen/hooktool/tool/additional/ResInjectTool.java
+++ b/app/src/main/java/com/hchen/hooktool/tool/additional/ResInjectTool.java
@@ -139,7 +139,7 @@ public static Resources loadModuleRes(Context context) {
     private static boolean loadResAboveApi30(Resources resources, boolean doOnMainLooper) {
         if (resourcesLoader == null) {
             try (ParcelFileDescriptor pfd = ParcelFileDescriptor.open(new File(mModulePath),
-                    ParcelFileDescriptor.MODE_READ_ONLY)) {
+                ParcelFileDescriptor.MODE_READ_ONLY)) {
                 ResourcesProvider provider = ResourcesProvider.loadFromApk(pfd);
                 ResourcesLoader loader = new ResourcesLoader();
                 loader.addProvider(provider);
@@ -283,7 +283,7 @@ private static void applyHooks() {
                      "getDimensionPixelOffset", "getDimensionPixelSize", "getText", "getFloat",
                      "getIntArray", "getStringArray", "getTextArray", "getAnimation" -> {
                     if (method.getParameterTypes().length == 1
-                            && method.getParameterTypes()[0].equals(int.class)) {
+                        && method.getParameterTypes()[0].equals(int.class)) {
                         hookResMethod(method.getName(), int.class, hookResBefore);
                     }
                 }
diff --git a/app/src/main/java/com/hchen/hooktool/tool/additional/SystemPropTool.java b/app/src/main/java/com/hchen/hooktool/tool/additional/SystemPropTool.java
index 915e2c4..896e40d 100644
--- a/app/src/main/java/com/hchen/hooktool/tool/additional/SystemPropTool.java
+++ b/app/src/main/java/com/hchen/hooktool/tool/additional/SystemPropTool.java
@@ -41,22 +41,22 @@ public static boolean getProp(String key, boolean def) {
 
     public static int getProp(String key, int def) {
         return (int) Optional.ofNullable(invokeMethod("getInt", new Class[]{String.class, int.class}, key, def))
-                .orElse(def);
+            .orElse(def);
     }
 
     public static long getProp(String key, long def) {
         return (long) Optional.ofNullable(invokeMethod("getLong", new Class[]{String.class, long.class}, key, def))
-                .orElse(def);
+            .orElse(def);
     }
 
     public static String getProp(String key, String def) {
         return (String) Optional.ofNullable(invokeMethod("get", new Class[]{String.class, String.class}, key, def))
-                .orElse(def);
+            .orElse(def);
     }
 
     public static String getProp(String key) {
         return (String) Optional.ofNullable(invokeMethod("get", new Class[]{String.class}, key))
-                .orElse("");
+            .orElse("");
     }
 
     /**
@@ -68,8 +68,8 @@ public static void setProp(String key, String vale) {
 
     private static String classLoaderMethod(ClassLoader classLoader, String name) {
         return (String) Optional.ofNullable(InvokeTool.callStaticMethod(
-               "android.os.SystemProperties", classLoader,
-                "get", new Class[]{String.class}, name)).orElse("");
+            "android.os.SystemProperties", classLoader,
+            "get", new Class[]{String.class}, name)).orElse("");
     }
 
     private static  T invokeMethod(String str, Class[] clsArr, Object... objArr) {
diff --git a/app/src/main/java/com/hchen/hooktool/tool/itool/IPrefsApply.java b/app/src/main/java/com/hchen/hooktool/tool/itool/IPrefsApply.java
index 98788f8..592c5ed 100644
--- a/app/src/main/java/com/hchen/hooktool/tool/itool/IPrefsApply.java
+++ b/app/src/main/java/com/hchen/hooktool/tool/itool/IPrefsApply.java
@@ -26,7 +26,7 @@
 /**
  * prefs 工具接口,方法具体介绍请看实现类 >>
  * {@link com.hchen.hooktool.tool.PrefsTool}
- * 
+ *
  * @author 焕晨HChen
  */
 public interface IPrefsApply {