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
- Class檔案解析
- 【JVM】深入解析class類檔案JVM
- java class檔案詳解Java
- 深入解析Class類檔案的結構
- 破解class檔案的第一步:深入理解JAVA Class檔案Java
- 例項分析JAVA CLASS的檔案結構Java
- Java Class檔案結構例項分析(下)Java
- Java Class檔案結構例項分析(上)Java
- java解析yaml配置檔案JavaYAML
- 使用 Java 解析XML檔案JavaXML
- 如何將一個Java檔案編譯成classJava編譯
- Java虛擬機器之Class類檔案結構Java虛擬機
- Class 檔案格式詳解
- k8s Java 專案替換 jar 中的 class 檔案K8SJavaJAR
- J2SE - Java命令執行class和jar檔案JavaJAR
- java加密保護jar包及class檔案,防止反編譯Java加密JAR編譯
- 如何獲取java執行時動態生成的class檔案?Java
- 類檔案結構_class類檔案的的結構
- ☕[Java技術指南](1)Class類檔案的結構介紹(上篇)Java
- 如何實現一個Java Class解析器Java
- eml檔案解析
- 《深入理解Java虛擬機器》-(實戰)練習修改class檔案Java虛擬機
- linux替換jar裡面的class檔案LinuxJAR
- ecplise配置jad反編譯.class檔案編譯
- JVM學習--Class類檔案結構JVM
- Class檔案結構&位元組碼指令
- 如果你還不瞭解 Java Class 檔案結構,來看看這篇吧Java
- Java虛擬機器,類檔案結構深度解析Java虛擬機
- SpringBoot自定義classloader加密保護class檔案Spring Boot加密
- JVM載入Class檔案的原理機制JVM
- python XML 檔案解析PythonXML
- jdom解析xml檔案XML
- BVH檔案格式解析
- XML 檔案解析實踐 (DOM 解析)XML
- Java中的屠龍之術(二):如何方便快捷地生成.class檔案Java
- es6 class解析
- java將Excel檔案上傳並解析為List陣列JavaExcel陣列