@使用javap反编译Java字节码文件
在Sun公司提供的JDK中,就已经内置了Java字节码文件反编译工具javap.exe(位于JDK安装目录的bin文件夹下)。
我们可以在dos窗口中使用javap来反汇编指定的Java字节码文件。在使用javap的相关dos命令之前,你必须确保已经将JDK安装目录\bin添加到环境变量path中。
接着,我们就可以使用javap来反编译指定的Java字节码文件了。在此之前,我们先通过javap的帮助命令javap -help查看javap相关指令的用法。
C:\Users\winner_0715>javap -help
用法: javap <options> <classes>
其中, 可能的选项包括:
-help --help -? 输出此用法消息
-version 版本信息
-v -verbose 输出附加信息
-l 输出行号和本地变量表
-public 仅显示公共类和成员
-protected 显示受保护的/公共类和成员
-package 显示程序包/受保护的/公共类
和成员 (默认)
-p -private 显示所有类和成员
-c 对代码进行反汇编
-s 输出内部类型签名
-sysinfo 显示正在处理的类的
系统信息 (路径, 大小, 日期, MD5 散列)
-constants 显示最终常量
-classpath <path> 指定查找用户类文件的位置
-cp <path> 指定查找用户类文件的位置
-bootclasspath <path> 覆盖引导类文件的位置
从上述内容我们可以知道,javap的使用命令格式为javap 选项参数 类名,其中选项参数可以有多个,中间用空格隔开,也可以一个都没有。下面我们编写如下源代码文件(包名test,类名Person),并将其编译为Person.class字节码文件。
package test; public class Person {
public Person(String name, int age, boolean gender, String address) {
this.name = name;
this.age = age;
this.gender = gender;
this.address = address;
} // private修饰符
private String name;
// 默认无访问修饰符(即下面所说的package、friendly)
int age;
// protected修饰符
protected boolean gender;
// public修饰符
public String address; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public void sayHi() {
System.out.println("Hello, my name is " + this.name);
}
}
接着将包名文件夹test及Person.class放置在D:\java
目录下。以便于我们使用javap命令进行测试。
在执行命令之前,我们需要将dos窗口的当前工作目录变更为D:\java\test
。
1、使用不带任何选项参数的命令:javap Person
D:\java\test>javap Person
警告: 二进制文件Person包含test.Person
Compiled from "Person.java"
public class test.Person {
int age;
protected boolean gender;
public java.lang.String address;
public test.Person(java.lang.String, int, boolean, java.lang.String);
public java.lang.String getName();
public void setName(java.lang.String);
public void sayHi();
}
javap Person和javap -package Person的显示结果一样,因为-package选项参数是默认的,用于显示package(不带任何访问修饰符,即我们常说的friendly)、protected、public修饰的类或成员。不会显示私有成员的属性
备注:在dos下进入工作目录D:\java,然后使用命令javap test.Person也可以实现上述操作。下同。
2、使用命令:javap -public Person显示public修饰的类或成员。
D:\java\test>javap -public Person
警告: 二进制文件Person包含test.Person
Compiled from "Person.java"
public class test.Person {
public java.lang.String address;
public test.Person(java.lang.String, int, boolean, java.lang.String);
public java.lang.String getName();
public void setName(java.lang.String);
public void sayHi();
}
与此类似,选项参数-protected用于显示protected以上访问级别(protected、public)的类或成员;选项参数-private用于显示private以上访问级别,也就是所有的类或成员。
3、使用命令:javap -public -l Person显示public修饰的类或成员,并显示行号表格和本地变量表格。
D:\java\test>javap -public -l Person
警告: 二进制文件Person包含test.Person
Compiled from "Person.java"
public class test.Person {
public java.lang.String address; public test.Person(java.lang.String, int, boolean, java.lang.String);
LineNumberTable:
line 4: 0
line 5: 4
line 6: 9
line 7: 14
line 8: 19
line 9: 25
LocalVariableTable:
Start Length Slot Name Signature
0 26 0 this Ltest/Person;
0 26 1 name Ljava/lang/String;
0 26 2 age I
0 26 3 gender Z
0 26 4 address Ljava/lang/String; public java.lang.String getName();
LineNumberTable:
line 21: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Ltest/Person; public void setName(java.lang.String);
LineNumberTable:
line 25: 0
line 26: 5
LocalVariableTable:
Start Length Slot Name Signature
0 6 0 this Ltest/Person;
0 6 1 name Ljava/lang/String; public void sayHi();
LineNumberTable:
line 29: 0
line 30: 28
LocalVariableTable:
Start Length Slot Name Signature
0 29 0 this Ltest/Person;
4、使用命令:javap -c Person显示Person.class反汇编出的字节码命令。
D:\java\test>javap -c Person
警告: 二进制文件Person包含test.Person
Compiled from "Person.java"
public class test.Person {
int age; protected boolean gender; public java.lang.String address; public test.Person(java.lang.String, int, boolean, java.lang.String);
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: aload_1
6: putfield #2 // Field name:Ljava/lang/String;
9: aload_0
10: iload_2
11: putfield #3 // Field age:I
14: aload_0
15: iload_3
16: putfield #4 // Field gender:Z
19: aload_0
20: aload 4
22: putfield #5 // Field address:Ljava/lang/String;
25: return public java.lang.String getName();
Code:
0: aload_0
1: getfield #2 // Field name:Ljava/lang/String;
4: areturn public void setName(java.lang.String);
Code:
0: aload_0
1: aload_1
2: putfield #2 // Field name:Ljava/lang/String;
5: return public void sayHi();
Code:
0: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
3: new #7 // class java/lang/StringBuilder
6: dup
7: invokespecial #8 // Method java/lang/StringBuilder."<init>":()V
10: ldc #9 // String Hello, my name is
12: invokevirtual #10 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
15: aload_0
16: getfield #2 // Field name:Ljava/lang/String;
19: invokevirtual #10 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
22: invokevirtual #11 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
25: invokevirtual #12 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
28: return
}
由于选项参数之间组合较多,因此其他选项参数不再一一截图赘述,仅在下面使用文字进行说明:
- -classpath <pathlist>
- 手动指定用户class字节码文件的存放目录,javap程序将在此目录下查找class文件,多个路径以英文分号分隔。例如:javap -classpath D:\java\test Person(即使DOS窗口的当前工作目录为其他任意路径,该命令均可正确执行)。
- -s
- 打印变量的内部类型签名,例如:javap -classpath D:\java\test -s Person。
- -extdirs <dirs>
- 指定javap搜索已安装的java扩展的位置,默认的java扩展的位置为jre\lib\ext。例如:javap -classpath D:\java\test -extdirs D:\java\myext Person
- -bootclasspath <pathlist>
- 指定使用Java底层类加载器(bootstrap class loader)加载的字节码文件的位置。例如:javap -classpath D:\java\test -bootclasspath D:\java\core Person
- -verbose
- 打印方法参数和本地变量的数量以及栈区大小。
- -J<flag>
- 使用javap.exe来执行java.exe虚拟机的相关命令,例如javap -J-version相当于java -version,可以有多个命令,中间以空格隔开。
@使用javap反编译Java字节码文件的更多相关文章
- 使用uncompyle2直接反编译python字节码文件pyo/pyc
update:在Mac OS X版的September 10, 2014版(5.0.9-1)中发现安装目录中的src.zip已更换位置至WingIDE.app/Contents/Resources/b ...
- Android反编译(一)之反编译JAVA源码
Android反编译(一) 之反编译JAVA源码 [目录] 1.工具 2.反编译步骤 3.实例 4.装X技巧 1.工具 1).dex反编译JAR工具 dex2jar http://code.go ...
- OpenJDK源码研究笔记(八)-详细解析如何读取Java字节码文件(.class)
在上一篇OpenJDK源码研究笔记(七)–Java字节码文件(.class)的结构中,我们大致了解了Java字节码文件的结构. 本篇详细地介绍了如何读取.class文件的大部分细节. 1.构造文件 ...
- OpenJDK源码研究笔记(七)–Java字节码文件(.class)的结构
最近在看OpenJDK源码的过程中,顺便看了Java编译器(javac)的源码. 为了理解javac的源码,需要先搞懂Java字节码文件(.class)的结构. 于是,我就认真看了下OpenJDK中J ...
- 【synchronized锁】通过synchronized锁 反编译查看字节码指令分析synchronized关键字修饰方法与代码块的区别
前提: 首先要铺垫几个前置的知识: Java中的锁如sychronize锁是对象锁,Java对象头中具有标识位,当对象锁升级为重量级锁时,重量级锁的标识位会指向监视器monitor, 而每个Java对 ...
- java字节码文件 helloworld
Java代码 \\A.java public class A{} 1 2 1 2 javac A.java \\得到 A.class javap -v A.class 下面是javap工具帮我们生成的 ...
- python反编译之字节码
如果你曾经写过或者用过 Python,你可能已经习惯了看到 Python 源代码文件:它们的名称以.Py 结尾.你可能还见过另一种类型的文件是 .pyc 结尾的,它们就是 Python "字 ...
- java字节码文件
查看字节码文件: javap -verbose HellloWorld.class
- 查看 java 中的编译的字节码文件
javap -c Atomicity ---------- javap -c 产生的字节码文件---------- Compiled from "Atomicity.java" p ...
随机推荐
- 安卓使用WebView清除缓存
原文:https://blog.csdn.net/liwei123liwei123/article/details/52624826 Android 清除WebView缓存 最近项目中需要用WebVi ...
- scala windows 安装
下载 https://downloads.lightbend.com/scala/2.11.11/scala-2.11.11.msi 第一步:设置 右击我的电脑,单击"属性",进入 ...
- DotNetOpenAuth实践之WCF资源服务器配置
系列目录: DotNetOpenAuth实践系列(源码在这里) 上一篇我们写了一个OAuth2的认证服务器,我们也获取到access_token,那么这个token怎么使用呢,我们现在就来揭开 一般获 ...
- js封装插件【组件】三种方式,含es6新特性。
1.先来说一下我使用到的es6的Object.assign.在jq里合并对象用的是extend方法,用来处理默认参数和传入参数做合并.es6里为我们提供了Object.assign,但是ie下全部撂倒 ...
- logstash收集nginx日志
(1)安装nginx 1.安装nginx yum install epel-release -y yum install nginx -y 2.修改日志文件格式为json #vim /etc/ngin ...
- Spark 源码解析 : DAGScheduler中的DAG划分与提交
一.Spark 运行架构 Spark 运行架构如下图: 各个RDD之间存在着依赖关系,这些依赖关系形成有向无环图DAG,DAGScheduler对这些依赖关系形成的DAG,进行Stage划分,划分的规 ...
- 洛谷P1558 色板游戏 [线段树]
题目传送门 色板游戏 题目背景 阿宝上学了,今天老师拿来了一块很长的涂色板. 题目描述 色板长度为L,L是一个正整数,所以我们可以均匀地将它划分成L块1厘米长的小方格.并从左到右标记为1, 2, .. ...
- Kail Linux渗透测试教程之免杀Payload生成工具Veil
Kail Linux渗透测试教程之免杀Payload生成工具Veil 免杀Payload生成工具——Veil Kail Linux渗透测试教程之免杀Payload生成工具Veil,Veil是一款利用M ...
- open -python操作文件
一打开文件 二操作文件 三关闭文件 open(文件,模式,编码),打开文件----->0101010(以二进制的方式打开)------>编码(open默认utf-8编码)------> ...
- android remoteView
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha remoteView 可以在 appWidget 和 notification 中 使 ...