- 浏览: 110083 次
- 性别:
- 来自: 沈阳
最新评论
-
a999888huang:
这个极难重现。。。虽然根据Java® Language Spe ...
<Java concurrency in practice>说这个代码不安全,记一下,慢慢理解 -
wjm251:
time.ctime(1387425025)+8时区时显示'T ...
python时间处理 -
wjm251:
datetime.strftime("%H:%M:% ...
python时间处理 -
wjm251:
今天在邮件列表里头看到有人问碰到这种怎么办s = u'\xbe ...
python的str,unicode对象的encode和decode方法 -
wjm251:
一定要有自己的鉴别啊
native2ascii用法说明
写出来贴在这留个纪念,没看过class规范看着是比较抽象,,也没写注释,sorry
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class ParseClassFile
{
static class CLASS_ACC{
public final static int ACC_PUBLIC = 0x0001;//class&interface
public final static int ACC_FINAL = 0x0010;//class
public final static int ACC_SUPER = 0x0020;//class&interface--->special
public final static int ACC_INTERFACE = 0x0200;//all interface
public final static int ACC_ABSTRACT = 0x0400;//all interface ,some class
public final static Object[][] ACC = new Object[][]{
{0x0001,"public"},
{0x0010,"final"},
{0x0020,"invokespecial"},
{0x0200,"interface"},
{0x0400,"abstract"},
};
}
static class FIELD_ACC{
//头3个标志public,private protected在类中只能有一个
//接口中必须设置为public static final
//final 和volatile不能同时出现
public final static int ACC_PUBLIC = 0x0001;
public final static int ACC_PRIVATE = 0x0002;
public final static int ACC_PROTECTED = 0x0004;
public final static int ACC_STATIC = 0x0008;
public final static int ACC_FINAL = 0x0010;
public final static int ACC_VOLATILE = 0x0040;
public final static int ACC_TRANSIENT = 0x0080;
public final static Object[][] ACC = new Object[][]{
{0x0001,"public"},
{0x0002,"private"},
{0x0004,"protected"},
{0x0008,"static"},
{0x0010,"final"},
{0x0040,"volatile"},
{0x0080,"transient"}
};
}
static class METHOD_ACC
{
/**
* 类(不含接口)中声明的方法只能有public private protected中的一个
* 如果一个方法设置了abstract,则private static final synchronized,native及strict都不能有
* 接口中方法必须使用public abstract不能有其他
*
* 构造方法<init>可以只使用public private和protected,<clinit>只会考虑ACC_STRICT标志
*/
public final static int ACC_PUBLIC = 0x0001;
public final static int ACC_PRIVATE = 0x0002;
public final static int ACC_PROTECTED = 0x0004;
public final static int ACC_STATIC = 0x0008;
public final static int ACC_FINAL = 0x0010;
public final static int ACC_SYNCHRONIZED = 0x0020;
public final static int ACC_NATIVE = 0x0100;
public final static int ACC_ABSTRACT = 0x0400;
public final static int ACC_STRICT = 0x0800;
public final static Object[][] ACC = new Object[][]{
{0x0001,"public"},
{0x0002,"private"},
{0x0004,"protected"},
{0x0008,"static"},
{0x0010,"final"},
{0x0020,"synchronized"},
{0x0100,"native"},
{0x0400,"abstract"},
{0x0800,"strict"}
};
}
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException
{
File f = new File("bin\\a.class");
FileInputStream in = new FileInputStream(f);
printMagicNumber(in);
printVersion(in);
int count = printConstantPoolEntryNumber(in);
printConstants(in, count);
System.out.println("access flag:"+parseACC(readInt(in,2), CLASS_ACC.ACC));
System.out.println("this class: class ref="+readInt(in,2));
System.out.println("super class: class ref="+readInt(in,2));
printInterfaces(in);
printFields(in);
printMethods(in);
parseAttrbute(in);
System.out.println();
System.out.println("remain bytes:" + in.available());
}
private static void printMethods(FileInputStream in)throws IOException
{
int methodCount = readInt(in,2);
System.out.println("method count: "+methodCount);
for(int i=0;i<methodCount;i++)
{
String access = parseACC(readInt(in,2),METHOD_ACC.ACC);
System.out.print("method["+i+"]"+access+"name ref="+readInt(in,2)+",descriptor ref="+readInt(in,2));
parseAttrbute(in);
}
}
private static void printFields(FileInputStream in) throws IOException
{
int fieldCount = readInt(in,2);
System.out.println("field count: "+fieldCount);
for(int i=0;i<fieldCount;i++)
{
String access = parseACC(readInt(in,2),FIELD_ACC.ACC);
System.out.print("field["+i+"]"+access+"name ref="+readInt(in,2)+",descriptor ref="+readInt(in,2));
parseAttrbute(in);
}
}
public static String parseACC(int accessFlag,Object[][] accType) throws IOException
{
StringBuilder access = new StringBuilder("[");
for(Object[] o : accType)
{
if((accessFlag&(Integer)o[0])!=0)
{
access.append(o[1]+",");
}
}
access.append("]");
return access.toString();
}
public static void parseAttrbute(FileInputStream in) throws IOException
{
int attrcount = readInt(in,2);
System.out.print(",attr count="+attrcount);
for(int j=0;j<attrcount;j++)
{
System.out.print(",attrname ref="+readInt(in,2));
int attrLen = readInt(in,4);
System.out.println(",attrlen="+attrLen);
//TODO parse attribute
in.skip(attrLen);
}
}
private static void printInterfaces(FileInputStream in) throws IOException
{
int interfaceCount = readInt(in,2);
System.out.println("interface count: "+interfaceCount);
for(int i=0;i<interfaceCount;i++)
{
System.out.println("interface["+i+"] ref="+readInt(in,2));
}
}
private static void printVersion(FileInputStream in) throws IOException
{
System.out.println("minor_version:" + readInt(in, 2));
System.out.println("major_version:" + readInt(in, 2));
}
private static void printMagicNumber(FileInputStream in) throws IOException
{
System.out.print("magic number:");
for (int i = 1; i <= 4; i++)
{
System.out.print(Integer.toHexString(readInt(in, 1)));
}
System.out.println();
}
private static int printConstantPoolEntryNumber(FileInputStream in)
throws IOException
{
int counstNum = readInt(in, 2) - 1;
System.out.println("constant pool entrys number:" + counstNum);
return counstNum;
}
private static void printConstants(FileInputStream in, int length)
throws IOException
{
for (int i = 1; i <= length; i++)
{
int flagType = readInt(in, 1);
System.out.print("counstPool " + i + ":tag=" + flagType + ",");
switch (flagType)
{
case 1: // CONSTANT_Utf8
{
int len = readInt(in, 2);
byte[] str = new byte[len];
in.read(str);
System.out.println("String:"+new String(str,"UTF-8"));
break;
}
case 3://CONSTANT_Integer
System.out.println("int value="+readInt(in,4));
break;
case 4://CONSTANT_Float
//TODO
in.skip(1);
System.out.println();
break;
case 5://CONSTANT_Long
System.out.println("long value="+Long.toString(readLong(in,8)));
i++;
break;
case 6://CONSTANT_Double
//double型占两个常量池入口
//TODO
in.skip(8);
i++;
System.out.println();
break;
case 7: // CONSTANT_Class
{
int name_index_entry = readInt(in, 2);
System.out.println("ClassInfo,reference constPool "
+ name_index_entry);
break;
}
case 8:// CONSTANT_String
System.out.println("String,ref"
+ readInt(in, 2));
break;
case 9:// CONSTANT_Fieldref
{
System.out.println("field: classref="+readInt(in,2)+",method ref="+readInt(in,2));
break;
}
case 10:// CONSTANT_Methodref
{
System.out.println("method from class: classref="+readInt(in,2)+",method ref="+readInt(in,2));
break;
}
case 11:// CONSTANT_InterfaceMethodref
System.out.println("method from interface: classref="+readInt(in,2)+",method ref="+readInt(in,2));
break;
case 12:// CONSTANT_NameAndType
{
System.out.println("fieldName ref="+readInt(in,2)+",fieldDescriptor ref="+readInt(in,2));
break;
}
default:
throw new RuntimeException();
}
}
}
public static byte[] int2Bytes(int val)
{
byte bs[] = new byte[4];
bs[0] = (byte) (val >> 24);
bs[1] = (byte) (val >> 16);
bs[2] = (byte) (val >>8);
bs[3] = (byte) val;
return bs;
}
public static int readInt(InputStream in, int byteNum) throws IOException
{
byte[] x = new byte[byteNum];
in.read(x);
return bytes2Int(x);
}
public static long readLong(InputStream in, int byteNum) throws IOException
{
byte[] x = new byte[byteNum];
in.read(x);
return bytes2Long(x);
}
private static int bytes2Int(byte bs[])
{
int var = 0;
for (int i = 1; i <= bs.length; i++)
{
var += (bs[i - 1] & 255) << 8 * (bs.length - i);
}
return var;
}
private static long bytes2Long(byte bs[])
{
long var = 0;
for (int i = 1; i <= bs.length; i++)
{
var += (bs[i - 1] & 255) << 8 * (bs.length - i);
}
return var;
}
}
参考
《深入java虚拟机》
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class ParseClassFile
{
static class CLASS_ACC{
public final static int ACC_PUBLIC = 0x0001;//class&interface
public final static int ACC_FINAL = 0x0010;//class
public final static int ACC_SUPER = 0x0020;//class&interface--->special
public final static int ACC_INTERFACE = 0x0200;//all interface
public final static int ACC_ABSTRACT = 0x0400;//all interface ,some class
public final static Object[][] ACC = new Object[][]{
{0x0001,"public"},
{0x0010,"final"},
{0x0020,"invokespecial"},
{0x0200,"interface"},
{0x0400,"abstract"},
};
}
static class FIELD_ACC{
//头3个标志public,private protected在类中只能有一个
//接口中必须设置为public static final
//final 和volatile不能同时出现
public final static int ACC_PUBLIC = 0x0001;
public final static int ACC_PRIVATE = 0x0002;
public final static int ACC_PROTECTED = 0x0004;
public final static int ACC_STATIC = 0x0008;
public final static int ACC_FINAL = 0x0010;
public final static int ACC_VOLATILE = 0x0040;
public final static int ACC_TRANSIENT = 0x0080;
public final static Object[][] ACC = new Object[][]{
{0x0001,"public"},
{0x0002,"private"},
{0x0004,"protected"},
{0x0008,"static"},
{0x0010,"final"},
{0x0040,"volatile"},
{0x0080,"transient"}
};
}
static class METHOD_ACC
{
/**
* 类(不含接口)中声明的方法只能有public private protected中的一个
* 如果一个方法设置了abstract,则private static final synchronized,native及strict都不能有
* 接口中方法必须使用public abstract不能有其他
*
* 构造方法<init>可以只使用public private和protected,<clinit>只会考虑ACC_STRICT标志
*/
public final static int ACC_PUBLIC = 0x0001;
public final static int ACC_PRIVATE = 0x0002;
public final static int ACC_PROTECTED = 0x0004;
public final static int ACC_STATIC = 0x0008;
public final static int ACC_FINAL = 0x0010;
public final static int ACC_SYNCHRONIZED = 0x0020;
public final static int ACC_NATIVE = 0x0100;
public final static int ACC_ABSTRACT = 0x0400;
public final static int ACC_STRICT = 0x0800;
public final static Object[][] ACC = new Object[][]{
{0x0001,"public"},
{0x0002,"private"},
{0x0004,"protected"},
{0x0008,"static"},
{0x0010,"final"},
{0x0020,"synchronized"},
{0x0100,"native"},
{0x0400,"abstract"},
{0x0800,"strict"}
};
}
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException
{
File f = new File("bin\\a.class");
FileInputStream in = new FileInputStream(f);
printMagicNumber(in);
printVersion(in);
int count = printConstantPoolEntryNumber(in);
printConstants(in, count);
System.out.println("access flag:"+parseACC(readInt(in,2), CLASS_ACC.ACC));
System.out.println("this class: class ref="+readInt(in,2));
System.out.println("super class: class ref="+readInt(in,2));
printInterfaces(in);
printFields(in);
printMethods(in);
parseAttrbute(in);
System.out.println();
System.out.println("remain bytes:" + in.available());
}
private static void printMethods(FileInputStream in)throws IOException
{
int methodCount = readInt(in,2);
System.out.println("method count: "+methodCount);
for(int i=0;i<methodCount;i++)
{
String access = parseACC(readInt(in,2),METHOD_ACC.ACC);
System.out.print("method["+i+"]"+access+"name ref="+readInt(in,2)+",descriptor ref="+readInt(in,2));
parseAttrbute(in);
}
}
private static void printFields(FileInputStream in) throws IOException
{
int fieldCount = readInt(in,2);
System.out.println("field count: "+fieldCount);
for(int i=0;i<fieldCount;i++)
{
String access = parseACC(readInt(in,2),FIELD_ACC.ACC);
System.out.print("field["+i+"]"+access+"name ref="+readInt(in,2)+",descriptor ref="+readInt(in,2));
parseAttrbute(in);
}
}
public static String parseACC(int accessFlag,Object[][] accType) throws IOException
{
StringBuilder access = new StringBuilder("[");
for(Object[] o : accType)
{
if((accessFlag&(Integer)o[0])!=0)
{
access.append(o[1]+",");
}
}
access.append("]");
return access.toString();
}
public static void parseAttrbute(FileInputStream in) throws IOException
{
int attrcount = readInt(in,2);
System.out.print(",attr count="+attrcount);
for(int j=0;j<attrcount;j++)
{
System.out.print(",attrname ref="+readInt(in,2));
int attrLen = readInt(in,4);
System.out.println(",attrlen="+attrLen);
//TODO parse attribute
in.skip(attrLen);
}
}
private static void printInterfaces(FileInputStream in) throws IOException
{
int interfaceCount = readInt(in,2);
System.out.println("interface count: "+interfaceCount);
for(int i=0;i<interfaceCount;i++)
{
System.out.println("interface["+i+"] ref="+readInt(in,2));
}
}
private static void printVersion(FileInputStream in) throws IOException
{
System.out.println("minor_version:" + readInt(in, 2));
System.out.println("major_version:" + readInt(in, 2));
}
private static void printMagicNumber(FileInputStream in) throws IOException
{
System.out.print("magic number:");
for (int i = 1; i <= 4; i++)
{
System.out.print(Integer.toHexString(readInt(in, 1)));
}
System.out.println();
}
private static int printConstantPoolEntryNumber(FileInputStream in)
throws IOException
{
int counstNum = readInt(in, 2) - 1;
System.out.println("constant pool entrys number:" + counstNum);
return counstNum;
}
private static void printConstants(FileInputStream in, int length)
throws IOException
{
for (int i = 1; i <= length; i++)
{
int flagType = readInt(in, 1);
System.out.print("counstPool " + i + ":tag=" + flagType + ",");
switch (flagType)
{
case 1: // CONSTANT_Utf8
{
int len = readInt(in, 2);
byte[] str = new byte[len];
in.read(str);
System.out.println("String:"+new String(str,"UTF-8"));
break;
}
case 3://CONSTANT_Integer
System.out.println("int value="+readInt(in,4));
break;
case 4://CONSTANT_Float
//TODO
in.skip(1);
System.out.println();
break;
case 5://CONSTANT_Long
System.out.println("long value="+Long.toString(readLong(in,8)));
i++;
break;
case 6://CONSTANT_Double
//double型占两个常量池入口
//TODO
in.skip(8);
i++;
System.out.println();
break;
case 7: // CONSTANT_Class
{
int name_index_entry = readInt(in, 2);
System.out.println("ClassInfo,reference constPool "
+ name_index_entry);
break;
}
case 8:// CONSTANT_String
System.out.println("String,ref"
+ readInt(in, 2));
break;
case 9:// CONSTANT_Fieldref
{
System.out.println("field: classref="+readInt(in,2)+",method ref="+readInt(in,2));
break;
}
case 10:// CONSTANT_Methodref
{
System.out.println("method from class: classref="+readInt(in,2)+",method ref="+readInt(in,2));
break;
}
case 11:// CONSTANT_InterfaceMethodref
System.out.println("method from interface: classref="+readInt(in,2)+",method ref="+readInt(in,2));
break;
case 12:// CONSTANT_NameAndType
{
System.out.println("fieldName ref="+readInt(in,2)+",fieldDescriptor ref="+readInt(in,2));
break;
}
default:
throw new RuntimeException();
}
}
}
public static byte[] int2Bytes(int val)
{
byte bs[] = new byte[4];
bs[0] = (byte) (val >> 24);
bs[1] = (byte) (val >> 16);
bs[2] = (byte) (val >>8);
bs[3] = (byte) val;
return bs;
}
public static int readInt(InputStream in, int byteNum) throws IOException
{
byte[] x = new byte[byteNum];
in.read(x);
return bytes2Int(x);
}
public static long readLong(InputStream in, int byteNum) throws IOException
{
byte[] x = new byte[byteNum];
in.read(x);
return bytes2Long(x);
}
private static int bytes2Int(byte bs[])
{
int var = 0;
for (int i = 1; i <= bs.length; i++)
{
var += (bs[i - 1] & 255) << 8 * (bs.length - i);
}
return var;
}
private static long bytes2Long(byte bs[])
{
long var = 0;
for (int i = 1; i <= bs.length; i++)
{
var += (bs[i - 1] & 255) << 8 * (bs.length - i);
}
return var;
}
}
参考
《深入java虚拟机》
发表评论
-
<Java Concurrency in Practice>笔记2——关于几种新并发容器或类的通俗理解
2011-03-25 10:05 1066关于几种新并发容器或类的通俗理解 SynchronousQue ... -
<Java Concurrency in Practice>笔记1
2011-03-25 10:04 1038之前的部分都没有记录了,从这里开始,所看过的自己意识中并非理所 ... -
阿拉伯数字转换为拼音读法
2011-03-19 23:56 2500今天同学让看下这个题目,折腾了两个多小时,设计了个巨复杂的算法 ... -
<Java concurrency in practice>说这个代码不安全,记一下,慢慢理解
2011-03-12 23:02 1242class Holder { private int ... -
eclipse远程调试java
2011-02-24 10:29 1624有了远程调试,调试java代码就方便多了,不用在eclipse ... -
native2ascii用法说明
2011-01-11 22:00 3172native2ascii用法 这个实 ... -
万能的toString
2010-07-21 22:28 869在http://leon-a.iteye.com/blog/4 ... -
beanshell运行
2009-12-26 19:47 1263beanshell运行 就一个jar文件下载后放到jdk的ex ... -
jvm下的脚本们-beanshell,groovy,,,
2009-11-17 22:42 4321jvm下的脚本们 项目中用 ... -
show一下java中的volatile的作用
2009-09-06 09:20 1783具体作用就不多讲了,大概就是保证可见性和防止重排序。 其实很早 ...
相关推荐
在Java编程语言中,`.class`文件是Java字节码的...总的来说,`jd-gui`这样的class文件反编译工具为Java开发者提供了一个查看和理解已编译代码的窗口,提高了开发效率和学习能力,但在使用时需谨慎对待版权和隐私问题。
Java Class反编译工具是程序员在处理已编译的字节码文件时不可或缺的辅助工具。这类工具的主要功能是将`.class`文件转换回可读性强的`.java`源代码,帮助开发者理解或修改已有的Java程序,尤其在没有源代码的情况下...
为了查看和理解Class文件内部的源代码,我们就需要使用到反编译工具。本文将详细介绍Java Class文件反编译工具——jd-gui。 jd-gui是一个开源的Java反编译工具,由Jikes项目开发者创建。它允许开发者在图形用户界面...
标题中的"Java的class反编译工具"指的就是能够将.class文件转换回接近原始源代码形式的工具。这种工具帮助开发者了解已有的类库是如何工作的,或者在没有源代码的情况下修复bug。常见的Java Class反编译工具有JD-GUI...
通过反编译工具,开发者可以查看JAR内部的类文件,了解其功能和实现细节,而无需原始的源代码。 "无需安装,解压即用"的特点使得这个工具非常便捷。用户下载压缩包后,直接解压缩就可以开始使用,省去了复杂的安装...
反编译工具通过解析.class文件的字节码,将其还原成接近原始Java源代码的形式,帮助开发者理解已编译的代码。 二、jd-gui:便捷的反编译工具 "jd-gui"是一款小巧且易于使用的Java反编译工具,它提供了一个图形化的...
在Java编程环境中,"Class文件反编译工具"是一个至关重要的辅助工具,它允许开发者查看并理解已编译的.class文件中的源代码级信息。由于Java的编译过程将源代码(.java文件)转化为字节码(.class文件),在某些情况...
JD-GUI是一款强大的Java反编译工具,专用于将字节码(.class文件)转换回源代码(.java文件)。在Java开发中,有时我们可能需要查看或理解已编译的类文件内部实现,而原始的源代码不再可用。这时,JD-GUI就能发挥它...
"java class文件或jar文件反编译工具.rar"正是这样一个资源,包含了一个名为jd-gui.exe的反编译工具,可以帮助我们将这些二进制文件转换回可读的Java源代码。 jd-gui.exe是一个图形用户界面的Java反编译器,它由JDI...
这就是反编译工具如Xjad的重要性所在。Xjad是一款专门用于将Java class文件转换回源代码(.java文件)的工具,它使得开发者能够查看并理解已编译的Java代码,这对于学习、调试、分析或逆向工程非常有用。 反编译是...
2. **反编译原理**:反编译工具通过解析Class文件的字节码,将其转化为人类可读的源代码。这个过程涉及到对Java字节码的逆向工程,包括理解操作码、常量池引用、控制流结构等。 3. **JD-GUI特点**: - **直观界面*...
总之,代码反编译是软件开发中的一个重要辅助工具,jd-gui.exe作为一款便捷的反编译工具,为开发者提供了查看和理解.class文件源代码的能力。然而,正确使用和理解反编译的法律边界是每个开发者都应重视的。
Java反编译是编程领域中一个重要的技术环节,它允许开发者查看和理解已经编译成字节码(.class文件)的Java程序的原始源代码。这种能力在多种情况下非常有用,例如,当我们需要分析开源软件的实现细节,或者当我们...
需要注意的是,虽然反编译工具可以提供源码级别的信息,但它们并不能保证完全恢复原始的代码结构和变量名,因为这些信息在编译后并不保留。此外,使用反编译工具应尊重知识产权,仅用于合法的学习和研究目的,避免...
这些工具能够解析JAR文件中的.class文件,并将其转换为接近原始的Java源代码。虽然反编译的代码可能无法与原始源代码完全相同,但通常足以理解大部分逻辑。 JD-GUI 是一款图形用户界面的反编译工具,它允许用户直接...
然而,字节码并不是人类可以直接阅读的代码,因此反编译工具就显得尤为必要。 JD-GUI,作为压缩包中的主要文件,是一个图形用户界面的Java反编译器。它能够将.class文件转换回可读的Java源代码,帮助开发者分析或...
Java反编译工具是开发人员在处理Java字节码时不可或缺的辅助工具,它们能够将已编译的`.class`文件转换回接近原始的Java源代码形式。这在某些情况下非常有用,例如当源代码丢失或者需要查看第三方库的内部实现时。...
2. **高效反编译**:XJad具备强大的反编译引擎,能够准确地将Java字节码转换为源代码,尽管不如现代的反编译工具如JD-GUI、Procyon等那么完善,但在处理早期版本的Java Class文件时,XJad的表现依然出色。...