如何更改已编译的.class文件而不反编译?

我想改变.class文件的方法。 我安装了JD Eclipse Decompiler并打开了.class文件。 我添加了一些代码并保存.class文件。 但是,.class文件并没有改变。

我不知道如何使用反编译器。 如果有可能,如何更改.class文件而不使用反编译器。

我正在使用Ubuntu

问候

编辑:

这是我反编译的代码:

/* */ package org.hibernate.id; /* */ /* */ import java.io.Serializable; /* */ import java.sql.ResultSet; /* */ import java.sql.SQLException; /* */ import java.util.HashMap; /* */ import java.util.Properties; /* */ import org.apache.commons.logging.Log; /* */ import org.apache.commons.logging.LogFactory; /* */ import org.hibernate.HibernateException; /* */ import org.hibernate.MappingException; /* */ import org.hibernate.dialect.Dialect; /* */ import org.hibernate.type.Type; /* */ import org.hibernate.util.ReflectHelper; /* */ /* */ public final class IdentifierGeneratorFactory /* */ { /* 25 */ private static final Log log = LogFactory.getLog(IdentifierGeneratorFactory.class); /* */ /* 64 */ private static final HashMap GENERATORS = new HashMap(); /* */ /* 66 */ public static final Serializable SHORT_CIRCUIT_INDICATOR = new Serializable() { /* */ public String toString() { return "SHORT_CIRCUIT_INDICATOR"; /* */ } /* 66 */ }; /* */ /* 70 */ public static final Serializable POST_INSERT_INDICATOR = new Serializable() { /* */ public String toString() { return "POST_INSERT_INDICATOR"; /* */ } /* 70 */ }; /* */ /* */ public static Serializable getGeneratedIdentity(ResultSet rs, Type type) /* */ throws SQLException, HibernateException, IdentifierGenerationException /* */ { /* 32 */ if (!(rs.next())) { /* 33 */ throw new HibernateException("The database returned no natively generated identity value"); /* */ } /* 35 */ Serializable id = get(rs, type); /* */ /* 37 */ if (log.isDebugEnabled()) log.debug("Natively generated identity: " + id); /* 38 */ return id; /* */ } /* */ /* */ public static Serializable get(ResultSet rs, Type type) /* */ throws SQLException, IdentifierGenerationException /* */ { /* 45 */ Class clazz = type.getReturnedClass(); /* 46 */ if (clazz == Long.class) { /* 47 */ return new Long(rs.getLong(1)); /* */ } /* 49 */ if (clazz == Integer.class) { /* 50 */ return new Integer(rs.getInt(1)); /* */ } /* 52 */ if (clazz == Short.class) { /* 53 */ return new Short(rs.getShort(1)); /* */ } /* 55 */ if (clazz == String.class) { /* 56 */ return rs.getString(1); /* */ } if(clazz == java.math.BigDecimal.class){ return rs.getBigDecimal(1); } /* */ /* 59 */ throw new IdentifierGenerationException("this id generator generates long, integer, short or string78"); /* */ } /* */ /* */ public static IdentifierGenerator create(String strategy, Type type, Properties params, Dialect dialect) /* */ throws MappingException /* */ { /* */ try /* */ { /* 92 */ Class clazz = getIdentifierGeneratorClass(strategy, dialect); /* 93 */ IdentifierGenerator idgen = (IdentifierGenerator)clazz.newInstance(); /* 94 */ if (idgen instanceof Configurable) ((Configurable)idgen).configure(type, params, dialect); /* 95 */ return idgen; /* */ } /* */ catch (Exception e) { /* 98 */ throw new MappingException("could not instantiate id generator", e); /* */ } /* */ } /* */ /* */ public static Class getIdentifierGeneratorClass(String strategy, Dialect dialect) { /* 103 */ Class clazz = (Class)GENERATORS.get(strategy); /* 104 */ if ("native".equals(strategy)) clazz = dialect.getNativeIdentifierGeneratorClass(); /* */ try { /* 106 */ if (clazz == null) clazz = ReflectHelper.classForName(strategy); /* */ } /* */ catch (ClassNotFoundException e) { /* 109 */ throw new MappingException("could not interpret id generator strategy: " + strategy); /* */ } /* 111 */ return clazz; /* */ } /* */ /* */ public static Number createNumber(long value, Class clazz) throws IdentifierGenerationException { /* 115 */ if (clazz == Long.class) { /* 116 */ return new Long(value); /* */ } /* 118 */ if (clazz == Integer.class) { /* 119 */ return new Integer((int)value); /* */ } /* 121 */ if (clazz == Short.class) { /* 122 */ return new Short((short)(int)value); /* */ } /* */ /* 125 */ throw new IdentifierGenerationException("this id generator generates long, integer, short"); /* */ } /* */ /* */ static /* */ { /* 75 */ GENERATORS.put("uuid", UUIDHexGenerator.class); GENERATORS.put("hilo", TableHiLoGenerator.class); GENERATORS.put("assigned", Assigned.class); GENERATORS.put("identity", IdentityGenerator.class); GENERATORS.put("select", SelectGenerator.class); GENERATORS.put("sequence", SequenceGenerator.class); GENERATORS.put("seqhilo", SequenceHiLoGenerator.class); GENERATORS.put("increment", IncrementGenerator.class); GENERATORS.put("foreign", ForeignGenerator.class); GENERATORS.put("guid", GUIDGenerator.class); GENERATORS.put("uuid.hex", UUIDHexGenerator.class); GENERATORS.put("sequence-identity", SequenceIdentityGenerator.class); } } 

你可以按照这些步骤来修改你的java类:

  1. 反编译.class文件,并保存为.java
  2. 在Eclipse中使用该java文件,原始JAR作为库以及所有依赖关系创建一个项目
  3. 更改.java并编译
  4. 获取修改后的.class文件,并将其放在原始JAR中。

使用字节码编辑器,如:

http://set.ee/jbe/

要小心,因为你需要从java字节码中获得非常好的知识。

您也可以使用反射在运行时更改类。

我添加了一些代码并保存.class文件。

您在JD EClipse Decompiler中看到的是在.class文件中反编译字节码的表示形式。 即使您更改文本,也不会影响字节码。

当你反编译和改变代码,你必须去你的eclipse项目的根文件夹,并检查你的类在bin文件夹至极与src相同的水平。 然后打开你的原始jar与zip工具( 7zip是很好的),并把修改后的类在同一个包里面的jar。

使用java assist Java库来处理应用程序的Java字节码(.class文件)。

– > Spring,Hibernate,EJB使用这个代理实现

– >我们可以通过字节码操作来做一些程序分析

– >我们可以使用Javassist为方法返回值实现一个透明缓存,通过拦截所有的方法调用,并且只在第一次调用时委托给超级实现。

你可以在反编译时修改代码,但是必须重新编译为class文件,反编译器输出java代码,必须使用与原始jar / class文件相同的类路径重新编译

据我所知,没有简单的方法来做到这一点。 最简单的方法是实际上不将类文件转换为可执行文件,而是将可执行文件包装在类文件中。 也就是说,创建一个可执行文件(可能是一个基于OS的可执行脚本文件),通过命令行简单地调用Java类。

如果你想实际上有一个程序,那么你应该看看那里的一些自动安装程序。

这是我找到的一种方式:

 [code] import java.io.*; import java.util.jar.*; class OnlyExt implements FilenameFilter{ String ext; public OnlyExt(String ext){ this.ext="." + ext; } @Override public boolean accept(File dir,String name){ return name.endsWith(ext); } } public class ExeCreator { public static int buffer = 10240; protected void create(File exefile, File[] listFiles) { try { byte b[] = new byte[buffer]; FileOutputStream fout = new FileOutputStream(exefile); JarOutputStream out = new JarOutputStream(fout, new Manifest()); for (int i = 0; i < listFiles.length; i++) { if (listFiles[i] == null || !listFiles[i].exists()|| listFiles[i].isDirectory()) System.out.println("Adding " + listFiles[i].getName()); JarEntry addFiles = new JarEntry(listFiles[i].getName()); addFiles.setTime(listFiles[i].lastModified()); out.putNextEntry(addFiles); FileInputStream fin = new FileInputStream(listFiles[i]); while (true) { int len = fin.read(b, 0, b.length); if (len <= 0) break; out.write(b, 0, len); } fin.close(); } out.close(); fout.close(); System.out.println("Jar File is created successfully."); } catch (Exception ex) {} } public static void main(String[]args){ ExeCreator exe=new ExeCreator(); FilenameFilter ff = new OnlyExt("class"); File folder = new File("./examples"); File[] files = folder.listFiles(ff); File file=new File("examples.exe"); exe.create(file, files); } } [/code]` 

您可以使用任何反编译器首先反编译文件。

我曾遇到类似的问题,我没有应用程序的源代码,只能在文件中做一个很小的改动。

以下是我所做的:

  1. 从jar中提取类文件

  2. 在一个反编译器中打开它(我使用JD GUI,你可以很容易地从互联网上的许多资源中获得)你可以从这里下载

  3. 您可以使用JD GUI实际查看jar中的所有文件。

  4. 对我想要的文件进行了更改,并复制了该文件中的所有代码
  5. 在eclipse中创建了一个只有这个类的新项目( 与jar中的包结构相同 ),提供了原始jar作为库和所有其他依赖项。
  6. 编译这个类,将.class文件注入到我的工作空间的bin文件夹中的jar文件中
  7. 测试了我的变化,喝了一杯咖啡来庆祝它:)

有时我们需要编译出千个文件中的一个文件来解决这个问题。 在这种情况下,可以像创建类路径一样创建相同的文件夹结构,将文件反编译成java或从源代码复制java文件。 进行必要的更改,将所有依赖项/类编译到一个类中,最后替换类文件。 最后重启容器。 一旦战争爆炸,文件将不会被取代。