Java類轉位元組碼工具

Erosion2020發表於2024-12-09

學Java安全的時候發現好多師傅分析漏洞的時候直接就給了一段Base64位元組碼,然後雖然一些師傅也會給出來對應的程式碼,但是有些小白是不知道怎麼把一個java類轉成Base64位元組碼的。

對於剛學Java安全的小白來說真的太不友好啦,也不知道這玩意兒是什麼意思,所以這裡寫一個小工具,專門用來把Java類轉成Base64位元組碼,以及把位元組碼轉成.class檔案,這樣即便有些師傅只給了Base64我們也可以用這份程式碼還原一下師傅用的位元組碼檔案。

Java程式碼

import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Base64;

public class ByteJavaUtil {

    public static String toBase64Byte(String javaFilePath) throws Exception{
        // 獲取 Java 編譯器
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        if (compiler == null) {
            throw new IllegalStateException("未找到 Java 編譯器,請確保使用的是 JDK 而不是 JRE。");
        }
        // 編譯 Java 檔案
        int result = compiler.run(null, null, null, javaFilePath);
        if (result != 0) {
            throw new RuntimeException("Java 檔案編譯失敗,請檢查語法錯誤:" + javaFilePath);
        }
        // 獲取 .class 檔案路徑
        String classFilePath = javaFilePath.replace(".java", ".class");
        // 讀取 .class 檔案內容為位元組陣列
        File classFile = new File(classFilePath);
        if (!classFile.exists()) {
            throw new RuntimeException(".class 檔案未生成:" + classFilePath);
        }
        byte[] classBytes = readFileToByteArray(classFile);
        // 轉換為 Base64 字串
        return Base64.getEncoder().encodeToString(classBytes);
    }

    private static byte[] readFileToByteArray(File file) throws IOException {
        try (FileInputStream fis = new FileInputStream(file)) {
            byte[] buffer = new byte[(int) file.length()];
            int ignore = fis.read(buffer);
            return buffer;
        }
    }
    public static void toJavaClassFile(String targetPath, String base64Data) throws MalformedURLException {
        // 解碼 Base64 資料
        byte[] classData = Base64.getDecoder().decode(base64Data);
        // 寫入 .class 檔案
        Path path = Paths.get(targetPath, "DecodedTest.class");
        try (FileOutputStream fos = new FileOutputStream(path.toFile())) {
            fos.write(classData);
            System.out.println("Class file decoded successfully!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) throws Exception {
        // 把指定的java檔案轉換成位元組碼,同時進行base64編碼
        String base64Byte = ByteJavaUtil.toBase64Byte("...\\Exp.java");
        // 輸出base64編碼
        System.out.println(base64Byte);
		// 把base64位元組碼轉換成.class檔案,並且輸出到指定的路徑中
        ByteJavaUtil.toJavaClassFile("...\\Desktop", base64Byte);
    }
}

我要轉換的Java程式碼如下:

image-20241209154758370

然後執行指令碼會有一些輸出:

# 一些警告......
yv66vgAAADQAIQoABgATCgAUABUIABYKABQAFwcAGAcAGQEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApFeGNlcHRpb25zBwAaAQAJdHJhbnNmb3JtAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgcAGwEAClNvdXJjZUZpbGUBAAhFeHAuamF2YQwABwAIBwAcDAAdAB4BAARjYWxjDAAfACABABtmYXN0anNvbl9sYWJzL3ZlcnNpb24yMy9FeHABAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQATamF2YS9pby9JT0V4Y2VwdGlvbgEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAFAAYAAAAAAAMAAQAHAAgAAgAJAAAALgACAAEAAAAOKrcAAbgAAhIDtgAEV7EAAAABAAoAAAAOAAMAAAAMAAQADQANAA4ACwAAAAQAAQAMAAEADQAOAAEACQAAABkAAAAEAAAAAbEAAAABAAoAAAAGAAEAAAARAAEADQAPAAIACQAAABkAAAADAAAAAbEAAAABAAoAAAAGAAEAAAAVAAsAAAAEAAEAEAABABEAAAACABI=
Class file decoded successfully!

最終在你給出的路徑下回輸出一個.class檔案,開啟就是剛才的那個.java檔案內容

image-20241209154517413

相關文章