java是一种类型安全的语言,它有四类称为安全沙箱机制的安全机制来保证语言的安全性,这四类安全沙箱分别是:

本篇博客主要介绍“.class文件检验器”的基本原理;如需了解其它几类安全机制可以通过上面的博客链接进入查看。

简介

jvm的.class文件检验器用于检查.class文件是否拥有合法的内存结构,这种检查是有必要的,因为java的.class文件可能来自本机,也可能来自网络,可能是你自己编译的文件,也可能是别人篡改过的文件。而对于jvm来说,一个.class文件就是一个字节序列,它不会过问字节序列的来源,只会校验字节序列的结构是否正确。

.class文件检验器保证安全的措施就是检验.class文件字节码的健壮性,比如某个.class文件是被恶意篡改过的,这个.class文件中包含一个方法,该方法有一条goto指令,直接跳到方法外部去执行未知的代码,如果执行该方法,很可能会导致jvm崩溃。所以,由.class文件检验器检查字节码的健壮性是很有必要的。

虽然.class文件检验器检查字节码能保证程序的健壮性,然后这是需要牺牲一些性能的;为了将这种影响降到最低,.class文件检验器会在字节码执行之前完成大部分的检验工作,也就是说,.class文件检验器会在字节码执行前而不是执行中进行检查,而且这种检查只会进行一次。比如每次遇到一条跳转指令.class文件检验器都会确认该跳转指令跳转到了另外一条合法指令,而该指令是是在同一方法的字节流中的。

.class文件检验器会进行四次独立的扫描来保证字节码的合法性。第一趟扫描在类装载时进行,这次会检查.class文件的内部结构,以保证它能被安全的编译;第二趟和第三趟扫描是在连接时进行的,这时会检查.class文件的数据定义是否遵从了java语言的语义规范,还会检查字节码的完整性;第四趟扫描是在解析符号引用时进行的,这次会检查.class文件所引用的字段、方法和类是否存在。

第一趟扫描

在.class文件被装载时,会进行第一次扫描,这时.class文件检验器会检查每一条字节序列,看它是否符合java class文件的基本结构。首先,检验器会检查.class文件是否以魔数0XCAFEBABY开头,这个魔数的作用是为了区分一些明显错误的或被破坏的.class文件。然后,检验器会检查.class文件的主版本号和次版本号,这个版本号必须在jvm所支持的范围之内,比如我用java8编译编译的.class文件放在java6的jvm内执行会抛出java.lang.UnsupportedClassVersionError,因为java6不支持java8的一些新特性比如lambda表达式,所以不能去执行java8的编译器编译的字节码;然后java一般都是向后兼容的,比如java8的jvm是能执行java6编译的.class文件的。第一趟扫描主要是检查.class文件是否遵从了java class文件的固定格式,这样才能字节码编译成方法区内的内部数据结构。

第二趟扫描

第二趟扫描会进行数据类型的语义检查,它不会再去检查.class文件的二进制数据了,而是会去检查方法区中定义的数据结构。类中定义的字段、方法和方法描述符等在.class文件中都会存储为一个字符串,检验器会检查这些字符串是否符合java规范;检验器还会检查类本身是否符合java语言规范,比如java语言规定除了Object类外所有类都必须有一个父类;检查器还会检查被final修饰的类(比如String.class)是否被继承,同样也会检查被final修饰的方法是否被覆盖,如果出现错误会抛出java.lang.VerifyError。检验器还会检查常量池里定义的常量是否合法,它会检查常量的索引会指向正确的常量池条目。

第三趟扫描

第三趟扫描会进行字节码验证,字节码检查会确认字节码的操作码的正确性,也会确保操作数栈包含正确的数值和类型,还会检查类的方法被调用时会传入正确的参数和参数类型。检验器在第三趟扫描会进行大量的操作,比如会检验所有的操作码都有一个合法的操作数等,在这趟扫描过后,它需要保证.class文件的字节码流可以被jvm安全地执行。然后检验器并不能检查出所有的安全问题,比如“停机问题”它就不能检查出来。停机问题是一个著名的计算机领域问题,即不能写出一个程序,用它来判断作为其输入的某个程序在执行时是否会停机。

第四趟扫描

第四趟扫描是在符号的动态连接时进行检查,检验器会检查符号引用是否合法;因为这次扫描需要检查该class类所引用的类,所以这是可能需要装载新的类;然而为了节约内存并保证程序正确性,jvm会使用延迟加载的策略来装载类,即直到类被程序真正使用时才会去装载。如果一个jvm实现为了加快装载速度预先装载了类,它还是会表现为延迟装载。比如jvm在预装载某个类时发现这个类不存在,它并不会马上抛出NoClassDefFoundError,而是直到这个缺少的类被程序使用时才抛出异常。如果jvm进行预先连接,第四次扫描会紧接着第三次扫描立刻执行;而如果jvm进行延迟连接(即在某个引用第一次执行时才连接),那么第四趟扫描可能在第三趟扫描之后很久才执行(甚至不执行)。

java安全沙箱(二)之.class文件检验器的更多相关文章

  1. java IO(二)大文件复制

    package cn.sasa.demo3; import java.io.FileInputStream; import java.io.FileOutputStream; import java. ...

  2. java nio 通道(二)

    本文章来源于我的个人博客: java nio 通道(二) 一,文件通道 文件通道总是堵塞式的,因此不能被置于非堵塞模式. FileChannel对象是线程安全的.多个进程能够在同一个实例上并发调用方法 ...

  3. java jvm学习笔记三(class文件检验器)

    欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 前面的学习我们知道了class文件被类装载器所装载,但是在装载class文件之前或之后,class文件实际上还需要被校验 ...

  4. java之jvm学习笔记三(Class文件检验器)

    java之jvm学习笔记三(Class文件检验器) 前面的学习我们知道了class文件被类装载器所装载,但是在装载class文件之前或之后,class文件实际上还需要被校验,这就是今天的学习主题,cl ...

  5. java安全沙箱(四)之安全管理器及Java API

    java是一种类型安全的语言,它有四类称为安全沙箱机制的安全机制来保证语言的安全性,这四类安全沙箱分别是: 类加载体系 .class文件检验器 内置于Java虚拟机(及语言)的安全特性 安全管理器及J ...

  6. java安全沙箱(三)之内置于Java虚拟机(及语言)的安全特性

    java是一种类型安全的语言,它有四类称为安全沙箱机制的安全机制来保证语言的安全性,这四类安全沙箱分别是: 类加载体系 .class文件检验器 内置于Java虚拟机(及语言)的安全特性 安全管理器及J ...

  7. java安全沙箱(一)之ClassLoader双亲委派机制

    java是一种类型安全的语言,它有四类称为安全沙箱机制的安全机制来保证语言的安全性,这四类安全沙箱分别是: 类加载体系 .class文件检验器 内置于Java虚拟机(及语言)的安全特性 安全管理器及J ...

  8. Java 验证码、二维码

    Java 验证码.二维码 资源 需要:   jelly-core-1.7.0.GA.jar网站:   http://lychie.github.io/products.html将下载下来的 jelly ...

  9. JavaWeb学习记录(二十三)——文件上传与下载

    一.导入jar包

随机推荐

  1. Linux手动释放缓存的方法

    Linux释放内存的命令:syncecho 1 > /proc/sys/vm/drop_caches drop_caches的值可以是0-3之间的数字,代表不同的含义:0:不释放(系统默认值)1 ...

  2. CentOS 安装 Wine

    1. 下载安装包 Wine的中文官网可以下载到最新稳定和开发版本的Wine安装包,根据不同需求可以自行下载 2. 解压安装包,编译前检查 根据不同的平台选择不同的编译选项: For 32-Bit Sy ...

  3. 与考试相关的JS方法

    var IsChange = 0;var ensure = 0;var timeCounter = (function () {//考试剩余时间 倒计时 var int; //var total = ...

  4. springmvc 自定义注解 以及自定义注解的解析

    1,自定义注解名字 @Target({ElementType.TYPE, ElementType.METHOD})   //类名或方法上@Retention(RetentionPolicy.RUNTI ...

  5. js 事件冒泡

    一. 什么是事件的冒泡:      在一个对象上触发某类事件(比如单击onclick事件),如果此对象定义了此事件的处理程序,那么此事件就会调用这个程序,如果没有定义此事件处理程序或者事件返回true ...

  6. UVA1103

    题意:输入以16进制的矩阵,先转换成2进制,之后输出形成的图案. 思路:先处理掉无关图案的0,之后一个图案一个图案的遍历,识别图案的方法就是有多少个圈圈.找到一个就全部标记为-1.并且记录圆圈的数目. ...

  7. 创建js对象的属性和方法

    按照如下的创建对象的方法,可以节省内存.记录一下方便日后使用 <!Doctype html><html> <head> <title></titl ...

  8. Android ui 测试课堂笔记

    开始接触Android ui测试了,笔记如下 模拟器 Genemotion , the fastest android simulator in the world Android ui 测试工具 S ...

  9. sql 查询执行的详细时间profile

    1.查看profile的设置 SHOW VARIABLES LIKE '%profil%' 结果如下:profiling OFF 为关闭状态 2.开启profile 结果: 3.执行需要执行的sql ...

  10. Kindle DXG和Win10 64bits无法连接的问题

    直入主题:换根数据线. 不要觉得答案简单,我就是不负责任的在调侃. 在得出这条答案之前,我的思路是,既然插上线以后,kindle的充电指示灯会亮,那就应该不是线的问题. 所以实际的过程是我安装了驱动之 ...