37

我想更改 .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);
   }
 }
4

10 回答 10

42

您可以按照以下步骤修改您的 java 类:

  1. 像你一样反编译.class文件并将其保存为.java
  2. 在 Eclipse 中使用该 java 文件、作为库的原始 JAR 及其所有依赖项创建一个项目
  3. 更改 .java 并编译
  4. 获取修改后的 .class 文件并将其再次放入原始 JAR 中。
于 2012-12-28T11:53:24.513 回答
15

使用字节码编辑器,例如:

http://set.ee/jbe/

请小心,因为您需要非常了解 Java 字节码。

您还可以在运行时使用字节码编织(如 AspectJ)更改类。

于 2012-12-28T11:51:33.173 回答
3

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

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

于 2012-12-28T11:52:07.667 回答
2

当您反编译和更改代码时,您必须进入 Eclipse 项目的根文件夹并检查 bin 文件夹中的类,该文件夹与 src 处于同一级别。然后用 zip 工具打开你的原始 jar(7zip很好)并将修改后的类放在 jar 内的同一个包中。

于 2013-06-07T13:14:28.747 回答
2

Recaf是一个反编译器 GUI,允许您编辑和重新编译文件。 以下是手册的相关部分:

编辑字节码的最简单方法是将其作为反编译源进行编辑。这不适用于高度复杂的案例和混淆,但对于大多数简单的编辑,您只需要这样做。只需打开类,将更改作为纯 Java 代码进行,然后保存。

于 2021-12-01T04:45:32.490 回答
1

使用java 辅助Java 库来操作应用程序的 Java 字节码(.class 文件)。

-> Spring , Hibernate , EJB 使用它来实现代理

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

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

于 2017-03-17T06:38:52.730 回答
1

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

我曾经遇到过一个类似的问题,我没有应用程序的源代码,不得不对文件进行非常小的更改。

以下是我所做的:

  1. 从jar中提取类文件

  2. 在反编译器中打开它(我使用 JD GUI,您可以从互联网上的许多资源中轻松获取)您可以从这里下载

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

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

反编译时可以更改代码,但必须重新编译成class文件,反编译器输出代码,必须使用与原始/文件java相同的类路径重新编译jarclass

于 2012-12-28T11:51:52.147 回答
0

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

于 2017-08-23T05:28:57.600 回答
-1

据我所知,没有简单的方法可以做到这一点。最简单的方法是不实际将类文件转换为可执行文件,而是在类文件周围包装一个可执行启动器。也就是说,创建一个可执行文件(可能是一个基于操作系统的可执行脚本文件),它只是通过命令行调用 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]`
于 2014-06-29T22:52:27.023 回答