Skip to content

Latest commit

 

History

History
449 lines (371 loc) · 60.8 KB

Seeyon_clazzDecompile.md

File metadata and controls

449 lines (371 loc) · 60.8 KB

起因

安装完致远A8 v8.1集团版后,使用了旧版本的补丁补丁文件,替换了jwycbjnoyees.jar文件。服务可以正常启动,但是在登录时却发现输入账户名和密码后无法登录,会跳转回登录页面。

排查

于是通过调试,发现是在LoginControlImpl#_transDoLogin_函数出现了异常,导致登录过程中断。相关代码如下

private static final Class c1 = MclclzUtil.ioiekc("com.seeyon.ctp.login.LoginHelper");

// more code ...

Method method = (Method)methodMap.computeIfAbsent("transDoLogin", methodName -> {
    Method method1 = null;

    try {
        method1 = c1.getMethod(methodName, HttpServletRequest.class, HttpSession.class, HttpServletResponse.class);
    } catch (NoSuchMethodException var3x) {
        LOGGER.error("get c1 method fail", var3x);
    }

    method1.setAccessible(true);
    return method1;
});

其中的lambda函数在执行c1.getMethod时抛出异常,无法找到指定方法。

起初并不知道是补丁文件的问题,而是搜索了一下com.seeyon.ctp.login.LoginHelper这个类在哪里,发现找不到,于是搜索com.seeyon.ctp.login,发现在ctp-login.jar包中的有一个LoginHelper.clazz文件。

文件内容如下

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

尝试base64解码,解码后文件magic并不是classmagic

转过头查看

private static final Class c1 = MclclzUtil.ioiekc("com.seeyon.ctp.login.LoginHelper");

阅读代码发现最后会调用com.seeyon.ctp.common.init.Xcyskm#_loadClassData_

public byte[] loadClassData(String className) throws IOException {
    String res = className.replace('.', '/').concat(".class");
    InputStream is = this.getResourceAsStream(res);
    byte[] classData = IOUtility.toByteArray(is);
    if (seekretList.contains(className)) {
        try {
            byte[] datas = Base64.decodeBase64(classData);
            classData = RSMocnoyees.decode(
                RSMocnoyees.getPublicKey("65537",
Base64Util.decode("Nzg4NDM2MTAxMzc1NzA0MDQ1Nzc3ODQ3MzM0OTg2NzgxNjEzNDM5Mzg5OTMyODA2ODcwNDQ0Nzk4NDIyODE2MTk0MTEzMzA2NDcyNjkzNTQzMDg4NjUyODc4NDA0NjUwMDEwMDAyNjI0ODQ4NjMxMzA3MjgzMTc4NzE1ODYzMjE1OTYzMDY3NDkwNTYzNDc1NTg0ODM0NzU1NzQ5MDI2NDkyMDk5NTUyMTIzNDAyOTA2NDIyMzgzMTQ1ODUzMjc3OTM4MDQxMDQ5MTU5NzczOTk0ODY3NzA5NzYwMjQzMDcwNTQzMjA3")
                ),
                datas,
                96
            );
        } catch (Throwable var6) {
            LOG.error(var6.getLocalizedMessage(), var6);
            return null;
        }
    }

    return classData;
}

看到这段代码我疑惑了,这里读取的文件补上的后缀是.class。纠结了好一会我把鼠标移到了文件tab窗口上看看它来自哪个jar包。

发现这个文件来自替换后的补丁文件,遂恍然大悟,于是把备份的原始jwycbjnoyees.jar文件拿来并查看了其中com.seeyon.ctp.common.init.Xcyskm#_loadClassData_方法,如下

public byte[] loadClassData(String className) throws IOException {
    String res = className.replace('.', '/').concat(".clazz");
    InputStream is = getResourceAsStream(res);
    byte[] classData = IOUtility.toByteArray(is);
    if (seekretList.contains(className))
        try {
            byte[] datas = Base64.decodeBase64(classData);
            classData = RSMocnoyees.decode(RSMocnoyees.getPublicKey("65537", Base64Util.decode("Nzg4NDM2MTAxMzc1NzA0MDQ1Nzc3ODQ3MzM0OTg2NzgxNjEzNDM5Mzg5OTMyODA2ODcwNDQ0Nzk4NDIyODE2MTk0MTEzMzA2NDcyNjkzNTQzMDg4NjUyODc4NDA0NjUwMDEwMDAyNjI0ODQ4NjMxMzA3MjgzMTc4NzE1ODYzMjE1OTYzMDY3NDkwNTYzNDc1NTg0ODM0NzU1NzQ5MDI2NDkyMDk5NTUyMTIzNDAyOTA2NDIyMzgzMTQ1ODUzMjc3OTM4MDQxMDQ5MTU5NzczOTk0ODY3NzA5NzYwMjQzMDcwNTQzMjA3")), datas, 96);
        } catch (Throwable e) {
            LOG.error(e.getLocalizedMessage(), e);
            return null;
        }  
    return classData;
}

它们的差别只体现在拼接的文件后缀上。

于是编写了如下代码,来反编译查看补丁中的LoginHelper.class文件

是的,这里发现在打补丁后,com.seeyon.ctp.login。LoginHelper位于补丁中,文件后缀为class。

// Loader是一个继承了ClassLoader的类,内容
// 是空的。
Loader loader = new Loader();

String className = "com.seeyon.ctp.login.LoginHelper";
String res = className.replace(".", "/").concat(".class");
InputStream is = loader.getResourceAsStream(res);

byte[] classData = IOUtility.toByteArray(is);
byte[] datas = Base64.decodeBase64(classData);
classData = RSMocnoyees.decode(
        RSMocnoyees.getPublicKey(
                "65537",
                Base64Util.decode(                        "Nzg4NDM2MTAxMzc1NzA0MDQ1Nzc3ODQ3MzM0OTg2NzgxNjEzNDM5Mzg5OTMyODA2ODcwNDQ0Nzk4NDIyODE2MTk0MTEzMzA2NDcyNjkzNTQzMDg4NjUyODc4NDA0NjUwMDEwMDAyNjI0ODQ4NjMxMzA3MjgzMTc4NzE1ODYzMjE1OTYzMDY3NDkwNTYzNDc1NTg0ODM0NzU1NzQ5MDI2NDkyMDk5NTUyMTIzNDAyOTA2NDIyMzgzMTQ1ODUzMjc3OTM4MDQxMDQ5MTU5NzczOTk0ODY3NzA5NzYwMjQzMDcwNTQzMjA3"
                )
        ),
        datas,
        96
);

FileOutputStream fos = new FileOutputStream("com.seeyon.ctp.login.LoginHelper.class");
fos.write(classData);

之后查看输出的com.seeyon.ctp.login.LoginHelper.class文件,transDoLogin函数的声明如下

public static LoginResult transDoLogin(HttpServletRequest request, HttpSession session, HttpServletResponse response, LoginControlImpl loginControl) throws BusinessException {}

发现它多了一个LoginControlImpl loginControl参数,和LoginControlImpl中的如下代码

method1 = c1.getMethod(methodName, HttpServletRequest.class, HttpSession.class, HttpServletResponse.class);

是不兼容的。

解惑

前面确定了原因是由于补丁文件不再适用安装的新版本了。根据LoginControlImpl#transDologin的逻辑,需要调用获取的method1后返回正确的结果才能正常登录。

为此需要修改以前的补丁文件,对比了两个文件的差异后,有部分文件需要解密后再对比

old jwycbjnoyees.jar(patched) -> new jwycbjnoyees.jar(unpatch)
com/seeyon/apps/mplus/a/v/a.class -> com/seeyon/apps/mplus/a/v/a.clazz
none -> com/seeyon/ctp/common/init/ConstansUtil.clazz
com/seeyon/ctp/common/init/SystemLoader.class -> none
com/seeyon/ctp/common/plugin/PluginSystemInit.class -> com/seeyon/ctp/common/plugin/PluginSystemInit.clazz
com/seeyon/ctp/login/LoginHelper.class -> none
com/seeyon/ctp/common/permission/bo/LicensePerInfo.class -> none
com/v3x/dee/context/EngineController.class -> com/v3x/dee/context/EngineController.clazz

// 无需解密
none -> com/seeyon/ctp/common/init/ServerUtil.class
com/seeyon/ctp/login/online/*.class -> none
none -> com/seeyon/ctp/product/BlacklistEnum.class
com/seeyon/ctp/product/CrackCheckTask.class -> none
com/seeyon/ctp/product/OnlineUserVerifyImpl.class -> none
com/seeyon/ctp/product/ProductInfo.class -> none
none -> com/seeyon/ctp/product/XinChuangBlackList.class

而在Xcyskml类中有如下列表

static {
    seekretList.add("com.seeyon.ctp.common.init.ConstantsUtil");
    seekretList.add("com.seeyon.ctp.common.init.SystemLoader");
    seekretList.add("com.seeyon.ctp.common.plugin.PluginSystemInit");
    seekretList.add("com.seeyon.ctp.login.LoginHelper");
    seekretList.add("com.seeyon.ctp.product.ProductInfo");
    seekretList.add("com.seeyon.ctp.permission.bo.LicensePerInfo");
    seekretList.add("com.seeyon.v3x.dee.context.EngineController");
    seekretList.add("com.seeyon.apps.mplus.a.v.a");
}

从前面的对比结果中可知在未打补丁情况下

  • com/seeyon/apps/mplus/a/v/a.clazz
  • com/seeyon/ctp/common/init/ConstansUtil.clazz
  • com/seeyon/ctp/common/plugin/PluginSystemInit.clazz
  • com/v3x/dee/context/EngineController.clazz

都位于jwycbjnoyees.jar包中,其余

  • com/seeyon/ctp/common/init/SystemLoader.clazz
  • com/seeyon/ctp/login/LoginHelper.clazz
  • com/seeyon/ctp/common/permission/bo/LicensePerInfo.clazz
  • com/seeyon/ctp/product/ProductInfo.clazz

位于ctp-login.jar包中,为了便于对比jar包的内容,通过如下代码来处理类文件被加密的情况(clazzclass后缀)。

package org.example;

import com.seeyon.ctp.util.Base64;
import www.seeyon.com.mocnoyees.DogException;
import www.seeyon.com.mocnoyees.RSMocnoyees;
import www.seeyon.com.utils.Base64Util;

import java.io.*;
import java.util.ArrayList;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;

public class App {

    public static ArrayList<String> seekretList = new ArrayList<>();
    static {
        seekretList.add("com.seeyon.ctp.common.init.ConstantsUtil");
        seekretList.add("com.seeyon.ctp.common.init.SystemLoader");
        seekretList.add("com.seeyon.ctp.common.plugin.PluginSystemInit");
        seekretList.add("com.seeyon.ctp.product.ProductInfo");
        seekretList.add("com.seeyon.ctp.login.LoginHelper");
        seekretList.add("com.seeyon.ctp.permission.bo.LicensePerInfo");
        seekretList.add("com.seeyon.v3x.dee.context.EngineController");
        seekretList.add("com.seeyon.apps.mplus.a.v.a");
    }

    public static byte[] decode(JarInputStream jis) throws IOException, DogException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[2048];
        int len = -1;
        while ((len = jis.read(buffer)) != -1) {
            byteArrayOutputStream.write(buffer, 0, len);
        }

        byte[] classData = byteArrayOutputStream.toByteArray();
        byte[] datas = Base64.decodeBase64(classData);
        classData = RSMocnoyees.decode(
                RSMocnoyees.getPublicKey(
                        "65537",
                        Base64Util.decode(
                                "Nzg4NDM2MTAxMzc1NzA0MDQ1Nzc3ODQ3MzM0OTg2NzgxNjEzNDM5Mzg5OTMyODA2ODcwNDQ0Nzk4NDIyODE2MTk0MTEzMzA2NDcyNjkzNTQzMDg4NjUyODc4NDA0NjUwMDEwMDAyNjI0ODQ4NjMxMzA3MjgzMTc4NzE1ODYzMjE1OTYzMDY3NDkwNTYzNDc1NTg0ODM0NzU1NzQ5MDI2NDkyMDk5NTUyMTIzNDAyOTA2NDIyMzgzMTQ1ODUzMjc3OTM4MDQxMDQ5MTU5NzczOTk0ODY3NzA5NzYwMjQzMDcwNTQzMjA3"
                        )
                ),
                datas,
                96
        );

        return classData;
    }

    public static boolean inSeekretList(String name) {
        for (String see : seekretList) {
            if (name.startsWith(see.replace(".", "/"))) {
                return true;
            }
        }
        return false;
    }

    public static void main(String[] args) {
        if (args.length < 2) {
            return;
        }

        String jarPath = args[0];
        String jarOutPath = args[1];
        try {
            JarInputStream zis = new JarInputStream(new FileInputStream(jarPath));
            JarOutputStream zos = new JarOutputStream(new FileOutputStream(jarOutPath));

            JarEntry entry = null;

            while ((entry = zis.getNextJarEntry()) != null) {
                String entryFileName = entry.getName();
                System.out.println(entryFileName);
                if (inSeekretList(entryFileName)) {
                    JarEntry jarEntry = new JarEntry(entryFileName.replace(".clazz", ".class"));
                    zos.putNextEntry(jarEntry);
                    // Decode before write
                    zos.write(decode(zis));
                } else {
                    // Copy
                    zos.putNextEntry(entry);
                    if (entry.isDirectory()) {
                        continue;
                    }
                    byte[] buffer = new byte[2048];
                    int len = -1;
                    while ((len = zis.read(buffer)) != -1) {
                        zos.write(buffer, 0, len);
                    }
                }
            }

            zis.close();
            zos.close();

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

这段代码会将seekretListl列表中的文件解密后保存至新的jar包中,之后就可以通过jd打开,并在反编译后进行比对。

下面想尝试将旧补丁文件中的LoginHelper.class文件,替换为ctp-login.jar中的LoginHelper.clazz,只是改一下后缀即可。之后重启服务,但是并没有成功,查看Tomcat日志之后发现有如下异常

20-Sep-2022 19:44:15.137 严重 [localhost-startStop-1] org.apache.catalina.core.StandardContext.listenerStart 异常将上下文初始化事件发送到类的侦听器实例.[com.seeyon.ctp.common.web.filter.CTPCsrfGuardServletContextListener]
	java.lang.NoClassDefFoundError: com/seeyon/ctp/common/init/MclclzUtil
		at com.seeyon.ctp.common.SystemEnvironment.<clinit>(SystemEnvironment.java:943)
		at com.seeyon.ctp.common.AppContext.<clinit>(AppContext.java:151)
		at com.seeyon.ctp.common.web.filter.CTPCsrfGuard.getSystemConfig(CTPCsrfGuard.java:90)
		at com.seeyon.ctp.common.web.filter.CTPCsrfGuard.isEnabled(CTPCsrfGuard.java:226)
		at com.seeyon.ctp.common.web.filter.CTPCsrfGuard.toString(CTPCsrfGuard.java:569)
		at com.seeyon.ctp.common.web.filter.CTPCsrfGuardServletContextListener.printConfigIfConfigured(CTPCsrfGuardServletContextListener.java:103)
		at com.seeyon.ctp.common.web.filter.CTPCsrfGuardServletContextListener.contextInitialized(CTPCsrfGuardServletContextListener.java:87)
		at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4763)
		at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5232)
		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
		at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:755)
		at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:729)
		at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:695)
		at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1177)
		at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1925)
		at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
		at java.util.concurrent.FutureTask.run(FutureTask.java:266)
		at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
		at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
		at java.lang.Thread.run(Thread.java:748)
	Caused by: java.lang.ClassNotFoundException: com.seeyon.ctp.common.init.MclclzUtil
		at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1415)
		at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1223)
		... 20 more

发现是加载com.seeyon.ctp.common.init.MclclzUtil时出现了异常,不太正常,检查了下刚刚修改后的jwycbjnoyees.jar包文件,发现由于压缩时所在的目录不对,导致多了一级目录jwycbjnoyeesclass

去掉压缩包中的目录jwycbjnoyeesclass后,重试依旧不行。

报错信息如下

AsyncLogger error handling event seq=3109, value='Logger=com.seeyon.ctp.login.controller.MainController Level=ERROR Message=Could not initialize class com.seeyon.ctp.login.interceptor.XCLoginInterceptor': java.lang.ClassFormatError: Incompatible magic value 1517385078 in class file com/seeyon/ctp/login/LoginHelper
java.lang.ClassFormatError: Incompatible magic value 1517385078 in class file com/seeyon/ctp/login/LoginHelper
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:756)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
        at org.apache.catalina.loader.WebappClassLoaderBase.findClassInternal(WebappClassLoaderBase.java:2485)
        at org.apache.catalina.loader.WebappClassLoaderBase.findClass(WebappClassLoaderBase.java:876)
        at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1379)
        at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1223)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:264)
        at org.apache.logging.log4j.util.LoaderUtil.loadClass(LoaderUtil.java:168)
        at org.apache.logging.log4j.core.impl.ThrowableProxy.loadClass(ThrowableProxy.java:622)
        at org.apache.logging.log4j.core.impl.ThrowableProxy.toExtendedStackTrace(ThrowableProxy.java:738)
        at org.apache.logging.log4j.core.impl.ThrowableProxy.<init>(ThrowableProxy.java:138)
        at org.apache.logging.log4j.core.impl.ThrowableProxy.<init>(ThrowableProxy.java:122)
        at org.apache.logging.log4j.core.impl.Log4jLogEvent.getThrownProxy(Log4jLogEvent.java:605)
        at org.apache.logging.log4j.core.pattern.ExtendedThrowablePatternConverter.format(ExtendedThrowablePatternConverter.java:64)
        at org.apache.logging.log4j.core.pattern.PatternFormatter.format(PatternFormatter.java:38)
        at org.apache.logging.log4j.core.layout.PatternLayout$PatternSerializer.toSerializable(PatternLayout.java:334)
        at org.apache.logging.log4j.core.layout.PatternLayout.toText(PatternLayout.java:233)
        at org.apache.logging.log4j.core.layout.PatternLayout.encode(PatternLayout.java:218)
        at org.apache.logging.log4j.core.layout.PatternLayout.encode(PatternLayout.java:58)
        at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.directEncodeEvent(AbstractOutputStreamAppender.java:177)
        at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.tryAppend(AbstractOutputStreamAppender.java:170)
        at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.append(AbstractOutputStreamAppender.java:161)
        at com.seeyon.ctp.log4j2.appender.CtpRollingFileAppender.append(CtpRollingFileAppender.java:312)
        at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:156)
        at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:129)
        at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:120)
        at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:84)
        at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:464)
        at org.apache.logging.log4j.core.async.AsyncLoggerConfig.callAppenders(AsyncLoggerConfig.java:120)
        at org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:448)
        at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:431)
        at org.apache.logging.log4j.core.async.AsyncLoggerConfig.log(AsyncLoggerConfig.java:114)
        at org.apache.logging.log4j.core.async.AsyncLoggerConfig.logToAsyncLoggerConfigsOnCurrentThread(AsyncLoggerConfig.java:162)
        at org.apache.logging.log4j.core.async.AsyncLoggerConfigDisruptor$Log4jEventWrapperHandler.onEvent(AsyncLoggerConfigDisruptor.java:111)
        at org.apache.logging.log4j.core.async.AsyncLoggerConfigDisruptor$Log4jEventWrapperHandler.onEvent(AsyncLoggerConfigDisruptor.java:97)
        at com.lmax.disruptor.BatchEventProcessor.processEvents(BatchEventProcessor.java:168)
        at com.lmax.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:125)
        at java.lang.Thread.run(Thread.java:748)

提示XCLoginInterceptor初始化失败,相关代码private static final Class<?> _c1_ = MclclzUtil._ioiekc_(``"com.seeyon.ctp.product.XinChuangBlackList"``)``;,原因是jwycbjnoyees.jar中缺少com.seeyon.ctp.product.XinChuangBlackList类的字节码文件,把它和它的相关依赖补充至jwycbjnoyees.jar中后终于可以正常登录。

在查看前面的报错信息时,我的关注点先落在了java.lang.ClassFormatError: Incompatible magic value 1517385078 in class file com/seeyon/ctp/login/LoginHelper这段信息上。可在经过一些测试后我坚定,放入的LoginHelper.class文件是没有问题的,可以被类加载器加载并初始化。而且正常来讲,这个类是由Xcyskm进行加载,但这个调用栈让我十分迷惑。

折腾了半天也没有排查出具体的原因,com.seeyon.ctp.product.XinChuangBlackList并不依赖LoginHelper。最后只是猜测可能由于com.seeyon.ctp.product.XinChuangBlackList的缺失,导致加载过程出了点小意外,LoginHelper虽然能被load,但却无法resolve,从而也无法调用它的transDoLogin方法。

这里在创建新的jar包(将其它class文件,拷贝到解压后原补丁文件中)时,使用如下代码进行压缩,

不推荐直接使用7zip之类的压缩软件进行压缩,再重命名文件后缀,可能会出错。

public static void recursionJar(File file, JarOutputStream jarOut, String filePath) throws Exception {
    if (file.isDirectory()) {
        String path = Objects.equals(filePath, "") ? "" : filePath + "/";
        if (path.length() > 0)
            jarOut.putNextEntry(new JarEntry(path));
        File[] files = file.listFiles();
        for (File fileSrc : files) {
            if (fileSrc.isDirectory()) {
                recursionJar(fileSrc, jarOut, path + fileSrc.getName());
            } else {
                recursionJar(fileSrc, jarOut, path);
            }
        }
    } else {
        String path = Objects.equals(filePath, "") ? "" : filePath;
        InputStream input = new FileInputStream(file);
        jarOut.putNextEntry(new JarEntry(path + file.getName()));
        byte[] buffer = new byte[4096];
        int len = -1;
        while ((len = input.read(buffer)) != -1) {
            jarOut.write(buffer, 0, len);
        }
        input.close();
    }
}

public static void main(String[] args) {
    if (args.length < 2) {
        return;
    }

    String pathToCompress = args[0];
    String jarName = args[1];

    File file = new File(pathToCompress);

    try {
        JarOutputStream jos = new JarOutputStream(new FileOutputStream(jarName));
        // 压缩时不会添加pathToCompress自身这个entry,只遍历子目录和文件。
        recursionJar(file, jos, "");
        jos.close();
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

最终的补丁文件见附件,jwycbjnoyees.jar文件