web-dev-qa-db-ja.com

デコンパイルせずにすでにコンパイルされた.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);
   }
 }
25
Breed Hansen

次の手順に従って、Javaクラスを変更できます。

  1. 実行したとおりに.classファイルを逆コンパイルし、.Javaとして保存します
  2. Javaファイル、ライブラリとしての元のJAR、およびそのすべての依存関係を含むプロジェクトをEclipseで作成します
  3. .Javaを変更してコンパイルする
  4. 変更された.classファイルを取得し、元のJAR内に再度配置します。
31
izaera

次のようなバイトコードエディタを使用します。

http://set.ee/jbe/

Javaバイトコードの非常に良い知識が必要なので注意してください。

また、AspectJのようなバイトコードウィービングを使用して、実行時にクラスを変更することもできます。

10
Lakatos Gyula

いくつかのコードを追加し、.classファイルを保存しました。

JD Eclipse Decompilerに表示されるのは、.classファイルのバイトコードの逆コンパイル表現です。テキストを変更しても、バイトコードには影響しません。

3

コードを逆コンパイルして変更する場合は、Eclipseプロジェクトのルートフォルダーに移動し、srcと同じレベルにあるbinフォルダーのクラスを確認する必要があります。次に、元のjarをZipツールで開き( 7Zip が適切です)、変更されたクラスをjar内の同じパッケージに入れます。

2
abk

Java Assist JavaアプリケーションのJavaバイトコード(.classファイル)を操作するためのライブラリ。

-> Spring、Hibernate、プロキシ実装にこれを使用するEJB

->バイトコード操作でプログラム分析を行うことができます

-> Javassistを使用して、すべてのメソッド呼び出しをインターセプトし、最初の呼び出しでのみスーパー実装に委任することにより、メソッドの戻り値の透過キャッシュを実装できます。

1
Vijay Gupta

時には、問題を修正するために、1000個のファイルから1つのファイルをコンパイルする必要があります。このような場合、クラスパスのような同じフォルダー構造を作成し、ファイルをJavaに逆コンパイルするか、ソースコードからJavaファイルをコピーします。必要な変更を行います。ある特定のファイルをすべての依存関係/クラスが適切なクラスにコンパイルし、最後にクラスファイルを置き換え、最後にコンテナを再起動します。

0
Harish Arora

コードを逆コンパイルするときに変更できますが、classファイルに再コンパイルする必要があり、逆コンパイラはJavaコードを出力します。これは、元のjar/classファイルと同じクラスパスで再コンパイルする必要があります

0
epoch

私が知る限り、それを行う簡単な方法はありません。最も簡単な方法は、クラスファイルを実際に実行可能ファイルに変換するのではなく、実行可能ランチャーをクラスファイルにラップすることです。つまり、コマンドラインからJavaクラスを単に呼び出すだけの実行可能ファイル(おそらくOSベースの実行可能スクリプトファイル)を作成します。

実際にそれを行うプログラムが必要な場合は、自動化されたインストーラーのいくつかを調べてください。

ここに私が見つけた方法があります:

[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]`
0
kytuni

任意のデコンパイラを使用して、最初にファイルを逆コンパイルできます。

以前、アプリケーションのソースコードがなく、ファイルに非常に小さな変更を加えなければならないという、同様の問題に直面していました。

以下は私がやったことです:

  1. Jarからクラスファイルを抽出しました

  2. デコンパイラで開きました(JD GUIを使用し、インターネット上の多くのリソースから簡単に取得できます) here からダウンロードできます。

  3. JD GUIを使用して、jar内のすべてのファイルを実際に表示できます。

  4. 必要なファイルに変更を加え、そのファイルからすべてのコードをコピーしました
  5. このクラス(と同じパッケージ構造を持つjar)のみでEclipseに新しいプロジェクトを作成し、元のjarをライブラリおよびその他のすべての依存関係として提供しました。
  6. クラスをコンパイルし、ワークスペースのbinフォルダーから.classファイルをjarに戻しました
  7. 私の変化をテストし、一杯のコーヒーをすすりながら祝った:)
0
user2280507