果然啊,内容越往后面,就越来越往安全上转移了,转移了有木有,看来得开始制定新的学习计划,这再往后学没神马用啊,或者说短时间用不上。写完这期,开始找找新的学习路线。
这节介绍的是字节码的效验,严格来讲和“ClassLoader学习”这个题目有点不贴切,因为介绍的偏重于
效验器(verifier)。不过还是能学到不少东西。
先回顾一下
基本知识,在执行一个java文件的时候一般的步骤是:
javac Hello.java -> Hello.class
java Hello
(上面两行,忘记的或者记不清的,去面壁去!)
大家好,我刚面壁回来,给大家继续讲解:
如果执行命令 javac Hello.java -verbose,我们可以回顾下前面学习的知识,
打印出的消息是:
D:\code>javac Hello.java -verbose
[解析开始时间 Hello.java]
[解析已完成时间 30ms]
[源文件的搜索路径: .,C:\Program Files\Java\jdk1.6.0_29\lib\dt.jar,C:\Program Fi
les\Java\jdk1.6.0_29\lib\tools.jar]
[类文件的搜索路径: C:\Program Files\Java\jdk1.6.0_29\jre\lib\resources.jar,C:\P
rogram Files\Java\jdk1.6.0_29\jre\lib\rt.jar,C:\Program Files\Java\jdk1.6.0_29\j
re\lib\sunrsasign.jar,C:\Program Files\Java\jdk1.6.0_29\jre\lib\jsse.jar,C:\Prog
ram Files\Java\jdk1.6.0_29\jre\lib\jce.jar,C:\Program Files\Java\jdk1.6.0_29\jre
\lib\charsets.jar,C:\Program Files\Java\jdk1.6.0_29\jre\lib\modules\jdk.boot.jar
,C:\Program Files\Java\jdk1.6.0_29\jre\classes,C:\Program Files\Java\jdk1.6.0_29
\jre\lib\ext\dnsns.jar,C:\Program Files\Java\jdk1.6.0_29\jre\lib\ext\localedata.
jar,C:\Program Files\Java\jdk1.6.0_29\jre\lib\ext\sunjce_provider.jar,C:\Program
Files\Java\jdk1.6.0_29\jre\lib\ext\sunmscapi.jar,C:\Program Files\Java\jdk1.6.0
_29\jre\lib\ext\sunpkcs11.jar,.,C:\Program Files\Java\jdk1.6.0_29\lib\dt.jar,C:\
Program Files\Java\jdk1.6.0_29\lib\tools.jar]
[正在装入 java\lang\Object.class(java\lang:Object.class)]
[正在装入 java\lang\String.class(java\lang:String.class)]
[
正在检查 Hello]
[正在装入 java\lang\System.class(java\lang:System.class)]
[正在装入 java\io\PrintStream.class(java\io:PrintStream.class)]
[正在装入 java\io\FilterOutputStream.class(java\io:FilterOutputStream.class)]
[正在装入 java\io\OutputStream.class(java\io:OutputStream.class)]
[已写入 Hello.class]
[总时间 234ms]
代码就是一个Hello World。通过输出,我们可以看见前面学过得加载类的过程。
然后使用java Hello就可以输出Hello World了。
本章的开始部分引入这个命令: java
-noverify Hello。
该命令特别之处就是在执行Hello的时候使用非正式的-noverify选项来钝化效验。
那么,我们就先来看看效验,都要
效验什么东西:
- 变量要在使用之前进行初始化。
- 方法调用与对象引用类型之间要匹配。
- 访问私有数据和方法的规则没有被违反。
- 对本地变量的访问都在运行时堆栈内。
- 运行时堆栈没有溢出。
如果以上这些检查中任何一条没有通过,那么该类就被认为遭到了破坏,并且不予加载。
肯定很多人有疑问了,在javac Hello.java的过程中,如果你违反了规则,就不会得到Hello.class,(这事
编译器都做了)那还要效验器来干嘛?因为,一个具有汇编程序经验的人,可以很容易的制造出这样的字节码出来,然后送给虚拟机来执行。所以效验器是很有必要的,要记住,效验器总是在防范被故意篡改的类文件,而不仅仅只是检查编译器产生的类文件。
为了深入了解效验器的工作,也为了了解java字节码的载入原理,我们继续来看下面的代码:
static int fun(){
int m;
int n;
int m = 1;
int n = 2;
int r = m + n;
return r;
}
这个方法被编译以后会生成16进制的.class文件。
要了解编译后的数据,我们要借助javap工具,来查看助记(mnemonic)格式的字节码。
javap -c VerifierTest
得到:
0 | iconst_1 |
1 | istore_0 |
2 | iconst_2 |
3 | istore_1 |
4 | iload_0 |
5 | iload_1 |
6 | iadd |
7 | istore_2 |
8 | iload_2 |
9 | ireturn |
那么如果我们把
int n = 2 替换成 int m = 2,也就是
istore_1改成istore_0; 使得n没有被初始化。我们就要修改16进制的class文件。先列出代码对应的16进制数:
0 | iconst_1 | 04 |
1 | istore_0 | 3B |
2 | iconst_2 | 05 |
3 | istore_1 | 3C |
4 | iload_0 | 1A |
5 | iload_1 | 1B |
6 | iadd | 60 |
7 | istore_2 | 3D |
8 | iload_2 | 1C |
9 | ireturn | AC |
使用16进制数编辑器,将
3C改为3B。这样执行VerifierTest程序,我们会得到java.lang.VerifyError的错误。
没错,虚拟机发现了我们的修改。
如果加入刚才的java -noverify VerifierTest参数,那么程序就可以产生输出了,为15102330,一个随机数,典型的输出错误。
所以,可以看出效验器果然给我们提供了很好的安全机制。
分享到:
相关推荐
在Java Web应用中,类加载...通过分析`web_classloader_test`,我们可以学习到如何理解和调试Web应用的类加载问题,以及如何利用类加载器的特性来实现特定的功能。这个示例对于理解Java Web应用的运行机制非常有价值。
3. 类加载器:学习不同的类加载器,如Bootstrap ClassLoader,Extension ClassLoader和App ClassLoader。 4. 垃圾回收:深入理解垃圾回收机制,如分代收集,可达性分析,以及不同GC算法,如Serial、Parallel、CMS和...
这个“java之jvm学习笔记五(实践写自己的类装载器)”很可能是对这一主题的详细探讨。 类装载器在Java中的主要职责是动态加载类到JVM中。Java的类装载器分为三个基本层次:启动类装载器(Bootstrap ClassLoader)、...
【Java学习笔记整理】 Java是一种广泛使用的编程语言,它不仅是一种语言,还是一个软件开发平台和运行环境。Java分为三个主要版本:Java标准版(JSE)、Java缩微版(JME)和Java企业版(JEE)。JSE主要用于桌面应用...
丛书名: 学习笔记 出版社:清华大学出版社 ISBN:9787302282082 上架时间:2012-5-9 出版日期:2012 年5月 开本:16开 页码:564 版次:1-1 所属分类:计算机 > 软件与程序设计 > JAVA(J#) > Java 编辑推荐 ...
### Java学习笔记知识点总结 #### 一、JVM与内存管理 **1.1 JVM基本概念** - **JVM(Java Virtual Machine)**: Java虚拟机是执行Java字节码的虚拟机,它提供了运行Java程序所需的环境。 **1.2 线程** - **线程...
它可以在不修改原有代码的情况下,为类添加额外的功能,如日志记录、事务管理、性能监控等。这种技术在插件框架、代理服务和调试工具中广泛应用。 总结起来,Java的类加载机制保证了程序的稳定运行,而ASM库则提供...
### 深入Java虚拟机JVM类加载学习笔记 #### 一、Classloader机制解析 在Java虚拟机(JVM)中,类加载器(ClassLoader)是负责将类的`.class`文件加载到内存中的重要组件。理解类加载器的工作原理对于深入掌握JVM以及...
根据提供的文件信息,这里将对Java学习笔记中的关键知识点进行详细阐述,主要涉及Java语言的基础概念、面向对象编程思想的应用以及Java类加载器的工作原理等内容。 ### Java学习基础 Java是一种广泛使用的高级编程...
这一过程涉及到类加载机制,包括Bootstrap ClassLoader、Extension ClassLoader、App ClassLoader和Custom ClassLoader,它们按照特定的层次关系和加载顺序加载类,确保类的唯一性。 类执行机制中,JVM基于栈的架构...
### J2EE-JDBC学习笔记知识点详述 #### JDBC驱动注册的三种方式 在Java开发中,使用JDBC(Java Database Connectivity)与数据库进行交互前,必须先注册对应的数据库驱动。J2EE环境下,通常有以下三种注册方式: ...
### 安卓逆向学习笔记之ART定制方案比较和流程 #### 一、概述 本文档旨在探讨Android Runtime (ART)环境下,针对不同ART定制方案的对比分析,并介绍实现逆向工程过程中的具体步骤与技巧。逆向工程是研究软件内部...
### 安卓逆向学习笔记之FART主动调用组件设计和源码分析 #### 一、概述 本文档旨在探讨安卓逆向工程中的一个重要工具——FART(Find And Replace Tool),并着重介绍如何利用该工具进行主动调用组件的设计与源码...
### Spring Boot 学习笔记之热部署与代码变更检测 #### 概述 Spring Boot 是一个基于 Spring 的框架,旨在简化新 Spring 应用程序的初始设置和开发过程。Spring Boot 的目标是允许开发者“只是运行”,即尽可能...
本文将根据"JVM性能学习笔记思维导图"的主题,详细阐述JVM的主要组成部分,性能调优的关键点以及相关的工具与实践策略。** 1. **JVM结构与内存模型** - **类装载器(ClassLoader)**:负责加载类文件,确保类在运行...
### 安卓逆向学习笔记之使用frida改进FART #### 一、FART工具原理及工作流程 FART(Find And Replace Tool)是一种针对Android应用进行逆向工程的工具,主要用于查找并替换Android应用中的指定代码或数据。本文档...
Java学习笔记JDK6课件第16章深入讲解了反射机制,这是Java语言中一个强大的特性,允许我们在运行时动态地获取类的信息并进行操作。反射的核心是`java.lang.Class`类,它代表了Java应用程序运行时加载的类或接口实例...
这份"Java学习笔记_内存管理.pdf"很可能是详细解析了Java如何进行内存分配、垃圾回收以及内存泄漏等相关概念。下面,我们将深入探讨Java内存管理的一些核心知识点。 1. **Java内存模型**: - **堆内存(Heap)**:...
3. **ClassLoader层次结构** - **Bootstrap ClassLoader**:加载JVM基础库,如`java.util.*`, `java.io.*`等。 - **Extension ClassLoader**:加载JVM扩展类,如`javax.*`开头的类,存在于`lib/ext`目录。 - **...
- JVM类加载器包括Bootstrap ClassLoader、Extension ClassLoader和Application ClassLoader,分别负责加载Java核心库、扩展库和应用程序类库。 8. Java中的异常处理 - Java使用try、catch、finally关键字来处理...