فهرست منبع

第二轮整体测试,代码优化、逻辑完善、bug修复

JustryDeng 5 سال پیش
والد
کامیت
bd2380286f

+ 1 - 16
class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/Reverses.java

@@ -108,7 +108,7 @@ public class Reverses {
                             if (javaagentCmdArgs.isDebug()) {
                                 Logger.error(Reverses.class, ExceptionUtil.getStackTraceMessage(e));
                             }
-                            String lib = parseLib(classWinterInfoDir);
+                            String lib = DecryptExecutor.parseLib(classWinterInfoDir);
                             Logger.error(Reverses.class, "decrypt class[" + className + "] fail. \nPlease check:\n"
                                     + "\t1. Ensure 'Your lib " + lib + " need a input password ?'\n"
                                     + "\t2. Ensure 'Your lib "+ lib +"'s password is correct ?'");
@@ -123,21 +123,6 @@ public class Reverses {
                         return classfileBuffer;
                     }
                 }
-                
-                /**
-                 * 根据classWinterInfoDir解析lib名称
-                 * <p>
-                 *     如: META-INF/winter/abc-1.0.0_jar/解析出来的lib为abc-1.0.0.jar
-                 * </p>
-                 *
-                 * @param classWinterInfoDir
-                 *            lib对应的class-winter信息存储目录, 形如META-INF/winter/abc-1.0.0_jar/
-                 * @return lib名称
-                 */
-                private String parseLib(String classWinterInfoDir) {
-                    classWinterInfoDir = classWinterInfoDir.replace(Constant.DEFAULT_ENCRYPTED_CLASSES_SAVE_DIR, "");
-                    return classWinterInfoDir.replace("_jar/", Constant.JAR_SUFFIX);
-                }
             });
         }
     }

+ 22 - 6
class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/executor/DecryptExecutor.java

@@ -32,8 +32,8 @@ public class DecryptExecutor {
     /**
      * 以key-value的形式记录lib中的被混淆的类(key-被混淆的类的无后缀全类名, value-存放采集到的类所在lib的信息的文件夹)。
      *
-     * key   - com.abc.xyz.Qwer
-     * value - META-INF/winter/abc-1.0.0_jar/
+     * key   - 形如: com.abc.xyz.Qwer
+     * value - 形如: META-INF/winter/abc-1.0.0_jar/
      */
     private static Map<String, String> checklistOfAllLibsMap;
 
@@ -173,23 +173,24 @@ public class DecryptExecutor {
     public static boolean verifyLibSeal(String projectPath, String classLongName, byte[] classBytes) {
         if (Cache.libSealCache == null) {
             Cache.libSealCache = new HashMap<>(8);
-            checklistOfAllLibsMap.values().forEach(libDirRelativePath -> {
+            checklistOfAllLibsMap.values().stream().distinct().forEach(libDirRelativePath -> {
                 byte[] sealByte = IOUtil.readFileFromWorkbenchRoot(new File(projectPath),
                         libDirRelativePath + Constant.SEAL_FILE_SIMPLE_NAME);
                 if (sealByte == null) {
                     throw new ClassWinterException("Lib " + libDirRelativePath.substring(0, libDirRelativePath.length() - 4)
                             + Constant.JAR_SUFFIX + " missing seal information.");
                 } else {
-                    Cache.libSealCache.put(libDirRelativePath, new String(sealByte, StandardCharsets.UTF_8));
+                    String libSealContent = new String(sealByte, StandardCharsets.UTF_8);
+                    Logger.debug(DecryptExecutor.class,
+                            "seal(from lib[" + DecryptExecutor.parseLib(libDirRelativePath) + "]) is " + libSealContent);
+                    Cache.libSealCache.put(libDirRelativePath, libSealContent);
                 }
             });
         }
     
         // 当且仅当checklistOfAllLibsMap.containsKey(classLongName)为true时才会调用此方法,所以这里libDirRelativePath一定有值的
         String libDirRelativePath = getLibDirRelativePath(classLongName);
-    
         String sealContent = Cache.libSealCache.get(libDirRelativePath);
-        Logger.debug(DecryptExecutor.class, "sealContent(from lib) " + sealContent);
         return new String(classBytes, StandardCharsets.UTF_8).contains(sealContent);
     }
     
@@ -220,6 +221,21 @@ public class DecryptExecutor {
         return userIfInputPwdWhileDecrypt;
     }
     
+    /**
+     * 根据classWinterInfoDir解析lib名称
+     * <p>
+     *     如: META-INF/winter/abc-1.0.0_jar/解析出来的lib为abc-1.0.0.jar
+     * </p>
+     *
+     * @param classWinterInfoDir
+     *            lib对应的class-winter信息存储目录, 形如META-INF/winter/abc-1.0.0_jar/
+     * @return lib名称
+     */
+    public static String parseLib(String classWinterInfoDir) {
+        classWinterInfoDir = classWinterInfoDir.replace(Constant.DEFAULT_ENCRYPTED_CLASSES_SAVE_DIR, "");
+        return classWinterInfoDir.replace("_jar/", Constant.JAR_SUFFIX);
+    }
+    
     /**
      * 获取class-winter加密时自动生成的密码
      *

+ 29 - 31
class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/AlreadyProtectedLibs_Test.java

@@ -6,23 +6,22 @@ import winter.com.ideaaedi.classwinter.util.BashUtil;
 import winter.com.ideaaedi.classwinter.util.Constant;
 import winter.com.ideaaedi.classwinter.util.PathUtil;
 
-import java.util.concurrent.TimeUnit;
-
 /**
  * 测试originJarOrWar
  *
  * @author {@link JustryDeng}
  * @since 2021/6/12 14:34:45
  */
+@SuppressWarnings("unused")
 public class AlreadyProtectedLibs_Test {
     
     public static void main(String[] args) {
         // 杀下进程(以保证端口没有被占用)
         BashUtil.killProcessByPorts("8080");
         
-        test0();
+//        test0();
 //        test1();
-//        test2();
+        test2();
     }
     
     /**
@@ -38,7 +37,7 @@ public class AlreadyProtectedLibs_Test {
      *
      * 期望结果:
      *    启动后,不能正常使用encrypted-lib-no-pwd-1.0.0.jar包的功能。
-     *    根据my-project-with-encrypted-lib-no-pwd.jar中的逻辑,启动后会报错。
+     *    根据我提供的jar中的代码逻辑,启动后会报错。
      */
     private static void test0() {
         String projectRootDir = PathUtil.getProjectRootDir(AlreadyProtectedLibs_Test.class);
@@ -62,7 +61,7 @@ public class AlreadyProtectedLibs_Test {
      *
      * 期望结果:
      *    项目正常启动,且能正常使用encrypted-lib-no-pwd-1.0.0.jar的功能。
-     *    根据my-project-with-encrypted-lib-no-pwd.jar中的逻辑,启动后会调用encrypted-lib-no-pwd-1.0.0.jar中的类输出一个加密解密
+     *    根据我提供的jar中的代码逻辑, 当有<我是业务逻辑的输出>输出时,即表示成功了
      */
     private static void test1() {
         String projectRootDir = PathUtil.getProjectRootDir(AlreadyProtectedLibs_Test.class);
@@ -73,58 +72,57 @@ public class AlreadyProtectedLibs_Test {
                 // 那么这里值随便填一个使其不匹配当前项目的包前缀即可
                 .includePrefix("non-exist")
                 .alreadyProtectedLibs("encrypted-lib-no-pwd-1.0.0.jar")
+                .debug(true)
                 .build();
         String encryptedJar = encryptExecutor.process();
         System.out.println(encryptedJar);
     
         // (解密)启动
         // 使用javaagent运行加密后的jar,测试
-        String javaagentArgs = "";
+        // String javaagentArgs = "";
+        String javaagentArgs = "=debug=true";
         // String javaagentArgs = "=debug=true,password=xxx";
         BashUtil.runCmdAndPrint(String.format("java -javaagent:%s%s -jar %s", encryptedJar, javaagentArgs, encryptedJar));
-    
-        try {
-            TimeUnit.SECONDS.sleep(3);
-        } catch (InterruptedException e) {
-            // ignore
-        }
-        // 杀下进程(以防下一个测试方法启动jar时因为端口被占用启动不起来)
-        BashUtil.killProcessByPorts("8080");
     }
     
     /**
      * 场景:
-     *    项目my-project-with-encrypted-lib-no-pwd.jar中的lib包
-     *    encrypted-lib-no-pwd-1.0.0.jar本身就是被class-winter以用户主动指定的密码加密过了的
-     * 测试期望结果:
-     *    正常启动项目my-project-with-encrypted-lib-no-pwd.jar,并
-     *    正常使用encrypted-lib-no-pwd-1.0.0.jar中的功能
+     *   项目my-project-with-encrypted-lib-have-pwd.jar中依赖了encrypted-lib-have-pwd-1.0.0.jar包,
+     *   但是这个encrypted-lib-have-pwd-1.0.0.jar包是被class-winter混淆了的,
+     *   如过想要正常使用my-project-with-encrypted-lib-have-pwd.jar,那么必须
+     *   对my-project-with-encrypted-lib-have-pwd.jar进行class-winter混淆,
+     *   且在alreadyProtectedLibs中指定encrypted-lib-have-pwd-1.0.0.jar及其密码。
+     *
+     *   注:对mencrypted-lib-have-pwd-1.0.0.jar加密时,我主动指定了密码为qwer123~。
+     *      所以这里在alreadyProtectedLibs中指定encrypted-lib-have-pwd-1.0.0.jar时,需要把密码带上。
+     *
+     * 测试case:
+     *    对项目my-project-with-encrypted-lib-have-pwd.jar进行class-winter混淆,然后使用javaagent启动jar。
+     *
+     * 期望结果:
+     *    项目正常启动,且能正常使用my-project-with-encrypted-lib-have-pwd.jar的功能。
+     *    根据我提供的jar中的代码逻辑, 当有<我是业务逻辑的输出>输出时,即表示成功了。
      */
     private static void test2() {
         String projectRootDir = PathUtil.getProjectRootDir(AlreadyProtectedLibs_Test.class);
         // 加密
         EncryptExecutor encryptExecutor = EncryptExecutor.builder()
-                .originJarOrWar(projectRootDir + Constant.LINUX_FILE_SEPARATOR + "my-project-with-encrypted-lib-no-pwd.jar")
+                .originJarOrWar(projectRootDir + Constant.LINUX_FILE_SEPARATOR + "my-project-with-encrypted-lib-have-pwd.jar")
                 // includePrefix字段是必填的,但是我们项目(my-project-with-encrypted-lib-no-pwd.jar)本身是没有混淆的,
                 // 只是其中的lib(encrypted-lib-no-pwd-1.0.0.jar)混淆了,我们项目是没必要进行解密的,所以这里值随便填什么都可以的
                 .includePrefix("non-exist")
-                .alreadyProtectedLibs("my-project-with-encrypted-lib-have-pwd.jar:qwer123~")
+                // 多个之间使用逗号隔开,形如 xxx1.jar:password1,xxx2.jar:password2
+                .alreadyProtectedLibs("encrypted-lib-have-pwd-1.0.0.jar:qwer123~")
+                .debug(true)
                 .build();
         String encryptedJar = encryptExecutor.process();
         System.out.println(encryptedJar);
     
         // (解密)启动
         // 使用javaagent运行加密后的jar,测试
-        String javaagentArgs = "";
+        // String javaagentArgs = "";
+        String javaagentArgs = "=debug=true";
         // String javaagentArgs = "=debug=true,password=xxx";
         BashUtil.runCmdAndPrint(String.format("java -javaagent:%s%s -jar %s", encryptedJar, javaagentArgs, encryptedJar));
-    
-        try {
-            TimeUnit.SECONDS.sleep(3);
-        } catch (InterruptedException e) {
-            // ignore
-        }
-        // 杀下进程(以防下一个测试方法启动jar时因为端口被占用启动不起来)
-        BashUtil.killProcessByPorts("8080");
     }
 }