详解JAVA字节码

news2024/11/25 18:55:12

目录

1.概述

 2.字节码文件构成

2.1.魔数

2.2.版本号

2.3.常量池

2.4.访问标志 

2.5.索引

2.6.字段表

2.7.方法表

3.字节码指令

3.1.概述

3.2.指令分类

3.2.1.加载存储指令

3.2.2.运算指令

3.2.3.其他指令

3.3.完整指令工作流程

4.字节码保护


1.概述

以往的编程语言是直接编译为计算机可识别并直接执行的机器码,但不同平台(机器)的指令集不同,编译出来的机器码不同,一个平台编译出来的机器码在另一个平台上可能无法正常运行。JAVA为了实现“write once run anywhere”的效果,先将JAVA代码编译为平台无关的.class文件(字节码文件),不论什么平台编译出来的字节码都是一样的,然后用适配不同平台的JVM来加载字节码文件,将字节码文件翻译给对应平台来执行。

字节码文件是个二进制文件,由JVM定义字节码文件的规范,任何满足这种规范的class文件都会被JVM加载运行。字节码规范规定字节码应该具有以下基本结构:

 2.字节码文件构成

2.1.魔数

字节码的前4个字节是魔数,所有字节码文件的魔数是固定的,4个byte合起来是cafebabe,用来标识该文件是JAVA的class文件。

2.2.版本号

字节码中记录编译使用的JDK版本,字节码的第5、6位表示次版本号,第7、8位表示主版本号:

查表可以得,示例中的版本号为JDK12。

2.3.常量池

常量池存放两大类常量:

  • 字面量,如文本字符串、fnal的常量值等
  • 符号引用,类和接口的全限定名、字段的名称和描述符、方法的名称和描述符

字节码中存放有常量池,使用java -verbose命令可以反编译得到常量池信息。

2.4.访问标志 

常量池结束后的两个字节,描述了该Class是类还是接口,以及是否被public、abstart、final等修饰符修饰。

2.5.索引

字节码文件中的索引分为三类:

  • 类索引
  • 父类索引
  • 接口索引集合

类索引:

访问标志后的两个字节,描述的是当前类的全限定名,这两个字节保存的值为常量池中的索引值,根据索引值就能在常量池中找到这个类的全限定名

父类索引:

当前类名后的两个字节描述父类的全限定名,同上,保存的也是常量池中的索引值。

接口索引集合:

父类名称后为两字节的接口计数器,描述了该类或父类实现的接口数量。紧接着的n个字节是所有接口名称的字符串常量的索引值。

2.6.字段表

用来记录成员变量,分为两部分:

  • 计数器,记录成员变量的个数。
  • 数据区,记录变量的具体内容。

2.7.方法表

记录方法,分为两部分:

  • 计数器,记录方法的个数
  •  数据区,记录方法的具体内容

属性列表中记录了方法的具体内容:

  • Code,源代码对应的]VM指令操作码
  • LineNumberTable,行号表,将Code区的操作码和源代码中的行号对应

3.字节码指令

3.1.概述

字节码指令在栈里面的每个栈帧中操作局部变量表进行对操作数栈的压栈出栈,从而完成方法中编写的一系列内容,变量表是“菜篮”;操作数栈是“砧板”。 

3.2.指令分类

3.2.1.加载存储指令

用于变量对于操作数栈的压栈、出栈。

  • 用于将数据在栈帧中的局部变量表和操作数栈之间来回传输
  • 将一个局部变量加载到操作栈: iload、lload、fload、dload、aload等
  • 将一个数值从操作数栈存储到局部变量表: istore、Istore、fstore、dstore、astore等
  • 将一个常量加载到操作数栈: bipush、sipush、ldc、ldc_w、ldc2 w、aconst null、iconst m1等

3.2.2.运算指令

用于进行运算的指令。

  •  iadd、isub、imul、idiv等类型转换指令
  • i2b、i2l、i2s等对象/数组创建与访问指令
  • new、newarray、getfield等操作数栈管理指令
  • pop、dup等

3.2.3.其他指令

  •  lfeq、goto等方法调用和返回指令
  •  invokevirtual、ireturn等异常处理指令
  • athrow同步控制指令
  •  monitorenter、monitorexit

3.3.完整指令工作流程

以下面代码为例展示一个完整的指令工作流程:

public class Sum {
    private int base = 10;
    public long add(int toAdd){
        this .base += toAdd;
        return this.base;
    }
}

反编译查看源码:

 

整体步骤如下:

  • aload 0 将索引为0的局部变量压栈
  • dup 复制栈顶值并压栈
  • getfeld 取出栈顶对象引用,获取其成员变量并压栈
  • iload_1 将索引为1 int型局部变量压栈
  • iacd 取出栈顶两个int型值相加,结来压栈
  • puteld 将栈顶两个元素取出 (值和对象引用) ,将值赋给该对象宇段
  • i2l 将栈顶int型值取出转为long型压栈lreturn 将栈顶long型元素取出返回

4.字节码保护

防止字节码文件被反编译为.java文件,一般有两种手段:

  • 字节码保护
  • 字节码混淆

字节码保护:

对字节码进行加密使其不再遵循JVM的规范,JVM加载之前先解密。

字节码混淆:

被混淆代码依然遵循JVM制定的规范,变量命名和程序流程上进行等效替换,使得程序的可读性变差,使得代码难以被理解和重用,达到保护代码的效果。

常用的字节码混淆器:ProGuard

下载地址:https://www.guardsquare.com/en/products/proguard

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/385174.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

浅析安科瑞能耗监测云平台在公共建筑上的应用及未来发展趋势

摘要:文章以每年发布的上海市国家机关办公建筑和大型公共建筑能耗监测及分析报告变化为切入点,分析了历年能耗分析报告的内容和功能变化;介绍了上海市国家机关办公建筑和大型公共建筑能耗监测平台发展和应用历程;揭示了当下显现的…

MOV压敏电阻应用推荐及选型要点说明

ESD器件-MOV压敏电阻是一种非线性的电阻元器件产品,具有瞬态电压抑制功能,能够吸收电路中多余的电流,可保护一些敏感电路及其他电子产品设备的电路不受ESD、雷击瞬态浪涌电流的危害。对于它的一些应用范围,优恩小编在这里举例说明…

2.SpringSecurity源码的初探

SpringSecurity源码的初探 一、SpringSecurity中的核心组件 在SpringSecurity中的jar分为4个,作用分别为 jar作用spring-security-coreSpringSecurity的核心jar包,认证和授权的核心代码都在这里面spring-security-config如果使用Spring Security XML名称…

【python】深入了解Selenium-PageObject

1、PageObject 定义 Page Object(简称PO)模式,是Selenium实战中最为流行,并且是自动化测试中最为熟悉和推崇的一种设计模式。在设计自动化测试时,把页面元素和元素的操作方法按照页面抽象出来,分离成一定的对象,然后再…

MySQL - 索引 与 事务

前言 本篇介绍MySQL的索引与事务,了解底层索引B树的基本思想, 了解事务的4大特征, 隔离性解决事务并发等问题; 如有错误,请在评论区指正,让我们一起交流,共同进步! 文章目录前言1. 数据库索引1.1 B树1.2 B树2. 事务总…

Linux -- 查看进程 top命令 详解

我们上篇介绍了, Linux 中的进程等概念,那么,在Linux 中如何查看进程呢 ??我们常用到的有两个命令, PS 和 top 两个命令,今天先来介绍下 top 命令~!top 命令 :主要是 交…

Unity 入门精要00---Unity提供的基础变量和宏以及一些基础知识

头文件引入: XXPROGRAM ... #include "UnityCG.cginc"; ... ENDXX 常用的结构体(在UnityCg.cginc文件中):在顶点着色器输入和输出时十分好用 。 关于如何使用这些结构体,可在Unity安装文件目录/Editor…

解压缩工具:Bandizip 中文

bandizip是一款可靠和快速的压缩软件,它可以解压RAR、7Z、ZIP、ISO等数十种格式,也可以压缩7Z、ZIP、ISO等好几种常用格式,在压缩文件方面毫不逊色于winrar,适用于多核心压缩、快速拖放、高速压缩等功能,采用了先进快速…

csapp第二章 --- 信息的表示和处理

本章重点纲要 目录 2.1 数据存储 2.1.1 进制 2.1.2 数据在内存的存储方式---大小端 2.1.3 C语言的一些知识 2.2 整数表示 2.2.1 二进制表示整数 2.2.2 扩展、截断 2.3 整数运算 2.3.1 加减法与溢出 2.3.2 逆元和补码的非 2.3.3乘法 2.4浮点数 2.4.1 IEEE规则 2.…

2023年中职组网络安全竞赛——综合渗透测试解析

综合渗透测试 题目如下: PS:需求环境可私信博主,求个三连吧! 解析如下: 通过本地PC中的渗透测试平台KALI2020对服务器场景进行渗透攻击,获取到RSYNC服务所开放的端口,将RSYNC服务开放的端口数值进行MD5加密后作为FLAG提交(如MD5加密前:812);

spark性能调优(二):内存

Memory 一、spark内存简介二、堆内内存 or 堆外内存?三、如何用好RDD Cache?四、OOM怎么办?一、spark内存简介 spark 2.0后,基本上spark内存的管理就已经自动化了,内存出现问题基本上是一些数据问题。比如数据倾斜 spark.executor.memory是绝对值,指定了executor进程的JVM…

毕业设计 基于stm32舞台彩灯控制器设计app控制系统

基于stm32舞台彩灯控制器设计app控制1、项目简介1.1 系统构成1.2 系统功能2、部分电路设计2.1 STM32F103C8T6核心系统电路设计2.2 WS2812RGB彩灯电路设计3、部分代码展示3.1 控制WS2812显示颜色3.2 设置RGB灯的颜色,角度,亮度实物图1、项目简介 选题指导…

Pluma 插件管理框架

1. 概述 Pluma 是一个用 C 开发的可用于管理插件的开源架构,其官网地址为:http://pluma-framework.sourceforge.net/。该架构是个轻量级架构,非常易于理解。 Pluma 架构有以下基本概念: 1)插件的外在行为体现为一个…

JavaSE:集合框架

为什么用集合框架如果不知道需要多少对象,或者用较为复杂的方式存储对象,可以用集合框架集合框架包含的内容ArrayList实践.size().add(Object o) .add(int index, Object o).get(int index).contains(Object o).remove(Object o) .remove(int…

高精度电流源如何设计出来

随着科技的不断进度,高精度电流源在自动测试/测量以及各种应用中承担着重要的作用。然而想要更高精度的指标参数,就需要电流源仪器研发得更完善。众所周知,高精度电流源是电子实验中重要的测试仪器,能够广泛应用在电化学、电光源、…

深入理解Windows操作系统机制(一)

我是荔园微风,作为一名在IT界整整25年的老兵,今天我们来重新审视一下Windows这个我们熟悉的不能再熟悉的系统。我们每天都在用Windows操作系统,但是其实我们每天直接在打交道的并不是Windows操作系统的内核,而是Windows操作系统的…

pytorch入门7--自动求导和神经网络

深度学习网上自学学了10多天了,看了很多大神的课总是很快被劝退。终于,遇到了一位对小白友好的刘二大人,先附上链接,需要者自取:https://b23.tv/RHlDxbc。 下面是课程笔记。 一、自动求导 举例说明自动求导。 torch中的…

Python 数据库连接 + 创建库表+ 插入【内含代码实例】

人生苦短 我用python Python其他实用资料:点击此处跳转文末名片获取 数据库连接 连接数据库前,请先确认以下事项: 您已经创建了数据库 TESTDB.在TESTDB数据库中您已经创建了表 EMPLOYEEEMPLOYEE表字段为 FIRST_NAME, LAST_NAME, AGE, SEX 和 INCOME。连…

前端css整理

如何水平垂直居中一个盒子? 1.已知高度:子盒子设置 display: inline-block; 父盒子设置 line-height 等于高度实现垂直居中;使用 text-align:center实现水平居中 2.父盒子 display:flex; align-items:center;justify-content:center; 3.定位&…

自动驾驶决策规划-控制方向学习资料总结(附相关资料的链接)

项目仓库 欢迎访问我的Github主页 项目名称说明chhCpp学习C仓库chhRobotics学习自动驾驶、控制理论相关仓库(python实现)chhRobotics_CPP学习自动驾驶、控制理论相关仓库(c实现)chhML 、chh-MachineLearning学习机器学习仓库chhRL学习强化学习仓库chhTricks存放一些有意思的t…