java class檔案解析
將java class位元組碼檔案按照不同的區域進行解析處理。
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
/**
* Created by dezhonger on 2020/09/26
* <p>
* javaClass檔案解析
*/
public class ClazzResolve {
public static void main(String[] args) {
File file = new File("E:/深入剖析class檔案結構/第一章/example/Hello.class");
// File file = new File("E:\\Netease\\pri\\target\\classes/Hello.class");
InputStream in = null;
try {
in = new FileInputStream(file);
showAvailableBytes(in);
//讀取魔數
readMagicNumber(in);
//讀取版本號
showAvailableBytes(in);
readVersion(in);
//讀取常量池
showAvailableBytes(in);
readConstantPool(in);
//讀取access flag(訪問控制符)
showAvailableBytes(in);
readAccessFlag(in);
//this class
readThisClass(in);
//superclass
readSuperClass(in);
//interface
readInterface(in);
//field
readField(in);
//method
readMethod(in);
//attribute
readAttribute(in);
showAvailableBytes(in);
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void readInterface(InputStream in) {
byte[] read = read(in, 2);
int size = (read[0] << 8) + read[1];
System.out.println("介面數量 " +size);
for (int i = 0; i < size; i++) {
read(in, 2);
}
}
private static void readAttribute(InputStream in, int sz) {
//attribute_info[sz]
for (int k = 0; k < sz; k++) {
read(in, 2);
byte[] f = read(in, 4);
int t = (f[0] << 24) + (f[1] << 16) + (f[2] << 8) + f[3];
read(in, t);
}
}
private static void readAttribute(InputStream in) {
byte[] read = read(in, 2);
int size = (read[0] << 8) + read[1];
System.out.println("屬性數量 " +size);
readAttribute(in, size);
}
private static void readMethod(InputStream in) {
int len = 2;
byte[] read = read(in, len);
int size = (read[0] << 8) + read[1];
System.out.println("方法數量 " +size);
for (int i = 0; i < size; i++) {
//access_flags
read(in, 2);
//name_index
read(in, 2);
//descriptor_index
read(in, 2);
//attribute_count
byte[] s = read(in, 2);
int sz = (s[0] << 8) + s[1];
//attribute_info[sz]
readAttribute(in, sz);
}
}
private static void readField(InputStream in) {
int len = 2;
byte[] read = read(in, len);
int size = (read[0] << 8) + read[1];
for (int i = 0; i < size; i++) {
//access_flags
read(in, 2);
//name_index
read(in, 2);
//descriptor_index
read(in, 2);
//attribute_count
byte[] s = read(in, 2);
int sz = (s[0] << 8) + s[1];
//attribute_info[sz]
readAttribute(in, sz);
}
}
private static void readSuperClass(InputStream in) {
read(in, 2);
}
private static void readThisClass(InputStream in) {
read(in, 2);
}
private static void readAccessFlag(InputStream in) {
read(in, 2);
}
private static void readConstantPool(InputStream in) {
int len = 2;
byte[] read = read(in, len);
int size = (read[0] << 8) + read[1];
int tagLen = 1;
for (int i = 0; i < size - 1; i++) {
byte[] readTag = read(in, tagLen);
switch (readTag[0]) {
case 1://字串
byte[] utf8Length = read(in, 2);
read(in, (utf8Length[0] << 8) + utf8Length[1]);
break;
case 3: case 4://int float
read(in, 4);
break;
case 5: case 6://long double
read(in, 8);
break;
case 7://Class
read(in, 2);
break;
case 8://String
read(in, 2);
break;
case 9: case 10: case 11://fieldref methodref interfaceref
read(in, 2);
read(in, 2);
break;
case 12://NameAndType
read(in, 2);
read(in, 2);
break;
case 15: case 16: case 18:
read(in, 2);
read(in, 2);
break;
default:
System.err.println("出錯了" + readTag[0]);
break;
}
}
}
private static void readVersion(InputStream in) {
int len = 4;
read(in, len);
}
private static void readMagicNumber(InputStream in) {
int len = 4;
read(in, len);
}
private static byte[] read(InputStream in,int len) {
byte[] bytes = new byte[len];
try {
in.read(bytes);
String[] res = new String[len];
for (int i = 0; i < len; i++){
res[i] = Integer.toHexString(Byte.toUnsignedInt(bytes[i]));
if (res[i].length() == 1) res[i] = "0" + res[i];
// System.out.println(Integer.toHexString(Byte.toUnsignedInt(b)));
}
System.out.println(Arrays.toString(res));
} catch (IOException e) {
e.printStackTrace();
}
return bytes;
}
/**
* 顯示輸入流中還剩的位元組數
*/
private static void showAvailableBytes(InputStream in) {
try {
System.out.println("當前位元組輸入流中的位元組數為:" + in.available());
} catch (IOException e) {
e.printStackTrace();
}
}
}
相關文章
- java class 檔案格式解析Java
- Jvm之用java解析class檔案JVMJava
- Class檔案解析
- JVM 深入學習:Java 解析 Class 檔案過程解析JVMJava
- Java二進位制Class檔案格式解析Java
- 【JVM】深入解析class類檔案JVM
- java class檔案詳解Java
- Java Class檔案詳解Java
- JAVA Class類檔案結構Java
- 深入解析Class類檔案的結構
- 破解class檔案的第一步:深入理解JAVA Class檔案Java
- 解析Class檔案魔數和版本號[轉]
- 例項分析JAVA CLASS的檔案結構Java
- Java Class檔案結構例項分析(下)Java
- Java Class檔案結構例項分析(上)Java
- java解析yaml配置檔案JavaYAML
- 使用 Java 解析XML檔案JavaXML
- 用Java解析CSV檔案Java
- Java9之class檔案格式變動Java
- Java Class 位元組碼檔案結構詳解Java
- 如何將一個Java檔案編譯成classJava編譯
- class與dex檔案
- Java解析ELF檔案:ELF檔案格式規範Java
- Java虛擬機器之Class類檔案結構Java虛擬機
- Class 檔案格式詳解
- Class類檔案結構
- Java XML檔案解析書目錄JavaXML
- JXL包大解析;Java程式生成excel檔案和解析excel檔案內容JavaExcel
- k8s Java 專案替換 jar 中的 class 檔案K8SJavaJAR
- Java 原始碼編譯成 Class 檔案的過程分析Java原始碼編譯
- J2SE - Java命令執行class和jar檔案JavaJAR
- 怎樣將class檔案變成.exe檔案?薦
- java加密保護jar包及class檔案,防止反編譯Java加密JAR編譯
- 如何獲取java執行時動態生成的class檔案?Java
- 【深入Java虛擬機器】之二:Class類檔案結構Java虛擬機
- 如何實現一個Java Class解析器Java
- Java DOM4J 方式解析XML檔案JavaXML
- 檔案同步類SimFileSync.class.phpPHP