You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何读取Java Class文件并替换其中的静态字符串内容?

Alright, let's break this down step by step. You want to swap the static string "Hello" with "Hi" in your compiled test.class file—here's how to do it properly, including a ready-to-use code template.

1. Reading the Class File

Class files are binary formats, so we'll read the entire file into a byte array using standard Java I/O. This gives us full access to modify the underlying bytes directly, no fancy libraries needed.

2. Key Logic for Replacing the Static String

Static strings in a class file live in the constant pool—a dedicated section that stores all literal values, class names, method names, and other reusable data. Specifically, your "Hello" is stored as a CONSTANT_Utf8_info entry, which follows this structure:

  • 1-byte tag (fixed value = 1, marking it as a UTF-8 string)
  • 2-byte unsigned length (stored in big-endian order)
  • N-byte UTF-8 encoded string (where N matches the length value)

To replace "Hello" with "Hi", you need to:

  • Locate the CONSTANT_Utf8_info entry that holds "Hello"
  • Update the 2-byte length from 5 (length of "Hello") to 2 (length of "Hi")
  • Replace the 5 UTF-8 bytes of "Hello" with the 2 bytes of "Hi"

Important: If you skip updating the length value, the class file will be corrupted and won't run—don't forget this step!

3. Complete Code Template

Here's a self-contained Java program that handles reading, modifying, and writing back the class file. It's tailored to your specific use case but can be adapted for similar tasks:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class ClassStringReplacer {
    public static void main(String[] args) throws IOException {
        // Configure your paths and target strings here
        String classFilePath = "test.class";
        String targetString = "Hello";
        String replacementString = "Hi";

        // Step 1: Read the entire class file into a byte array
        byte[] classBytes = readClassFile(classFilePath);

        // Step 2: Modify the constant pool to swap the strings
        modifyConstantPool(classBytes, targetString, replacementString);

        // Step 3: Write the modified bytes back to the class file
        writeClassFile(classFilePath, classBytes);

        System.out.println("Success! Replaced \"" + targetString + "\" with \"" + replacementString + "\"");
    }

    private static byte[] readClassFile(String path) throws IOException {
        try (FileInputStream fis = new FileInputStream(path)) {
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            return buffer;
        }
    }

    private static void modifyConstantPool(byte[] classBytes, String target, String replacement) {
        // Constant pool starts at offset 8 (after 4-byte magic number + 4-byte version info)
        int constantPoolCount = ((classBytes[8] & 0xFF) << 8) | (classBytes[9] & 0xFF);

        int offset = 10; // Start of the first constant pool entry

        for (int i = 1; i < constantPoolCount; i++) {
            byte tag = classBytes[offset];
            if (tag == 1) { // We found a CONSTANT_Utf8_info entry
                // Read the string length (big-endian 2 bytes)
                int length = ((classBytes[offset + 1] & 0xFF) << 8) | (classBytes[offset + 2] & 0xFF);
                // Extract the actual string from the byte array
                String str = new String(classBytes, offset + 3, length);

                if (str.equals(target)) {
                    // Update the length to match the replacement string
                    byte[] replacementLength = intTo2Bytes(replacement.length());
                    classBytes[offset + 1] = replacementLength[0];
                    classBytes[offset + 2] = replacementLength[1];

                    // Replace the string bytes
                    byte[] replacementBytes = replacement.getBytes();
                    System.arraycopy(replacementBytes, 0, classBytes, offset + 3, replacementBytes.length);

                    // Exit early—we found and modified our target string
                    break;
                }

                // Move offset to the next constant pool entry
                offset += 3 + length;
            } else {
                // Skip over other constant pool entry types (fixed sizes)
                switch (tag) {
                    case 7: case 8: case 16:
                        offset += 3;
                        break;
                    case 9: case 10: case 11: case 12: case 18:
                        offset += 5;
                        break;
                    case 3: case 4:
                        offset += 5;
                        break;
                    case 5: case 6:
                        offset += 9;
                        i++; // Long/Double take two slots in the count
                        break;
                    default:
                        offset++;
                        break;
                }
            }
        }
    }

    private static byte[] intTo2Bytes(int value) {
        // Convert an int to a 2-byte big-endian array
        return new byte[]{(byte) (value >> 8), (byte) value};
    }

    private static void writeClassFile(String path, byte[] bytes) throws IOException {
        try (FileOutputStream fos = new FileOutputStream(path)) {
            fos.write(bytes);
        }
    }
}
4. How to Use This
  1. Compile your original test.java to generate test.class
  2. Compile this ClassStringReplacer.java program
  3. Run ClassStringReplacer—it will modify your test.class file in place
  4. Run java test—you'll see the output is now Hi instead of Hello

A quick heads-up: This works perfectly for your simple test case. For more complex class files (like obfuscated code, or where the same string appears multiple times), you might need to add extra checks to target the exact constant pool entry used in your println call. But for your given code, this will do the trick.

内容的提问来源于stack exchange,提问作者Srinivas Jayaram

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:23:40