当前位置: 首页 > news >正文

解析class字节码文件获取魔数和版本号

写在前面

本文看下如何获取class字节码文件的魔数和版本号信息。

1:正文

需要对class字节码的结构有一定的了解,可以参考这篇文章 。

直接看代码:

package org.example;import java.math.BigInteger;public class TTTT {//取部分字节码:java.lang.Stringprivate static byte[] classData = {-54, -2, -70, -66, 0, 0, 0, 52, 2, 26, 3, 0, 0, -40, 0, 3, 0, 0, -37, -1, 3, 0, 0, -33, -1, 3, 0, 1, 0, 0, 8, 0,59, 8, 0, 83, 8, 0, 86, 8, 0, 87, 8, 0, 110, 8, 0, -83, 8, 0, -77, 8, 0, -49, 8, 0, -47, 1, 0, 3, 40, 41, 73, 1,0, 20, 40, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 59, 1, 0, 20, 40, 41,76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 1, 0, 3, 40, 41, 86, 1, 0, 3,40, 41, 90, 1, 0, 4, 40, 41, 91, 66, 1, 0, 4, 40, 41, 91, 67, 1, 0, 4, 40, 67, 41, 67, 1, 0, 21, 40, 68, 41, 76,106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 1, 0, 4, 40, 73, 41, 67, 1, 0, 4};public static void main(String[] args) {// 显示值是按照有符号数来展示的,为了获取原始的无符号数对应的值,需要与上0xFF,即11111111,这样就转换为无符号数了(不知道为啥啊,反正就这样!!!)。System.out.println("* byte字节码与运算原值(-54)换行后(-54 & 0x0FF):" + (-54 & 0x0FF));//校验魔数readAndCheckMagic();//校验版本号readAndCheckVersion();}/*** 前四个字节是魔术!!!* 校验魔数* <p>* 很多文件格式都会规定满足该格式的文件必须以某几个固定字节开头,这几个字节主要起到标识作用,叫作魔数(magic number)。* 例如;* PDF文件以4字节“%PDF”(0x25、0x50、0x44、0x46)开头,* ZIP文件以2字节“PK”(0x50、0x4B)开头* class文件以4字节“0xCAFEBABE”开头*/private static void readAndCheckMagic() {System.out.println("\r\n------------ 校验魔数 ------------");// 从class字节码中读取前四位,就是魔数,u4类型byte[] magic_byte = new byte[4];System.arraycopy(classData, 0, magic_byte, 0, 4);// 将4位byte字节转成16进制字符串String magicNumberInHex = new BigInteger(1, magic_byte).toString(16);System.out.println("class文件魔数16进制表示为:" + magicNumberInHex);// magicNumberInHex 是16进制的字符串,cafebabe,因为java中没有无符号整型,所以如果想要无符号只能放到更高位中long magic_unsigned_int32 = Long.parseLong(magicNumberInHex, 16);System.out.println("魔术转换为无符号表示(Java没有无符号数,所以转long来表示)magic_unsigned_int32:" + magic_unsigned_int32);//魔数比对,一种通过字符串比对,另外一种使用假设的无符号16进制比较。如果使用无符号比较需要将0xCAFEBABE & 0x0FFFFFFFFL与运算System.out.println("0xCAFEBABE & 0x0FFFFFFFFL(这样也可以转换为正整数表示):" + (0xCAFEBABE & 0xFFFFFFFFL));// 通过比较字节码中获取的和cafebabe的实际值,得出是否是一个class字节码文件(当然不一定合法,因为后续还有很多内容)if (magic_unsigned_int32 == (0xCAFEBABE & 0x0FFFFFFFFL)) {System.out.println("class字节码魔数无符号16进制数值一致校验通过");} else {System.out.println("class字节码魔数无符号16进制数值一致校验拒绝");}}/**** 校验版本号* <p>* 魔数之后是class文件的次版本号和主版本号,都是u2类型。假设某class文件的主版本号是M,次版本号是m,那么完整的版本号可以* 表示成“M.m”的形式。次版本号只在J2SE 1.2之前用过,从1.2开始基本上就没有什么用了(都是0)。主版本号在J2SE 1.2之前是45,* 从1.2开始,每次有大版本的Java版本发布,都会加1{45、46、47、48、49、50、51、52}*/private static void readAndCheckVersion() {System.out.println("\r\n------------ 校验版本号 ------------");//从class字节码第4位开始读取,读取2位byte[] minor_byte = new byte[2];// u2 5,6两个字节是minor version信息System.arraycopy(classData, 4, minor_byte, 0, 2);//将2位byte字节转成16进制字符串String minor_hex_str = new BigInteger(1, minor_byte).toString(16);System.out.println("小版本号16进制表示:" + minor_hex_str);//minor_unsigned_int32 转成无符号16进制int minor_unsigned_int32 = Integer.parseInt(minor_hex_str, 16);System.out.println("小版本号十进制整数表示:" + minor_unsigned_int32);//从class字节码第6位开始读取,读取2位byte[] major_byte = new byte[2];// u2 7,8两个字节是major version信息System.arraycopy(classData, 6, major_byte, 0, 2);//将2位byte字节转成16进制字符串String major_hex_str = new BigInteger(1, major_byte).toString(16);System.out.println("主版本号16进制表示:" + major_hex_str);//major_unsigned_int32 转成无符号16进制int major_unsigned_int32 = Integer.parseInt(major_hex_str, 16);System.out.println("主版本号整数表示:" + major_unsigned_int32);System.out.println("完整版本号:" + major_unsigned_int32 + "." + minor_unsigned_int32);}}

详细的看注释吧,有什么不明白的可留言!
运行如下:

* byte字节码与运算原值(-54)换行后(-54 & 0x0FF):202------------ 校验魔数 ------------
class文件魔数16进制表示为:cafebabe
魔术转换为无符号表示(Java没有无符号数,所以转long来表示)magic_unsigned_int32:3405691582
0xCAFEBABE & 0x0FFFFFFFFL(这样也可以转换为正整数表示):3405691582
class字节码魔数无符号16进制数值一致校验通过------------ 校验版本号 ------------
小版本号16进制表示:0
小版本号十进制整数表示:0
主版本号16进制表示:34
主版本号整数表示:52
完整版本号:52.0Process finished with exit code 0

写在后面

参考文章列表

class字节码文件结构是什么样子的? 。

相关文章:

解析class字节码文件获取魔数和版本号

写在前面 本文看下如何获取class字节码文件的魔数和版本号信息。 1&#xff1a;正文 需要对class字节码的结构有一定的了解&#xff0c;可以参考这篇文章 。 直接看代码&#xff1a; package org.example;import java.math.BigInteger;public class TTTT {//取部分字节码&…...

技术文档总结----思维导图

性能调优| ProcessOn免费在线作图,在线流程图,在线思维导图 mysql| ProcessOn免费在线作图,在线流程图,在线思维导图 kafka| ProcessOn免费在线作图,在线流程图,在线思维导图 mybatis缓存| ProcessOn免费在线作图,在线流程图,在线思维导图 java锁| ProcessOn免费在线作图,在…...

【iOS】—— retain\release实现原理和属性关键字

【iOS】—— retain\release实现原理和属性关键字 1. retain\reelase实现原理1.1 retain实现原理1.2 release实现原理 2. 属性关键字2.1 属性关键字的分类2.2 内存管理关键字2.2.1 weak2.2.2 assgin2.3.3 strong和copy 2.4 线程安全的关键字2.5 修饰变量的关键字2.5.1常量const…...

这一文,关于Java泛型的点点滴滴 一

作为一个 Java 程序员&#xff0c;用到泛型最多的&#xff0c;我估计应该就是这一行代码&#xff1a; List<String> list new ArrayList<>();这也是所有 Java 程序员的泛型之路开始的地方啊。 不过本文讲泛型&#xff0c;先不从这里开始讲&#xff0c;而是再往前…...

微信小程序之调查问卷

一、设计思路 1、界面 调查问卷又称调查表&#xff0c;是以问题的形式系统地记载调查内容的一种形式。微信小程序制作的调查问卷&#xff0c;可以在短时间内快速收集反馈信息。具体效果如下所示&#xff1a; 2、思路 此调查问卷采用服务器客户端的方式进行设计&#xff0c;服…...

基于Qt的视频剪辑

在Qt中进行视频剪辑可以通过多种方式实现&#xff0c;但通常需要使用一些额外的库来处理视频数据。以下是一些常见的方法和步骤&#xff1a; 使用FFmpeg FFmpeg是一个非常强大的多媒体框架&#xff0c;可以用来处理视频和音频数据。你可以使用FFmpeg的命令行工具或者其库来实现…...

electron 网页TodoList工具打包成win桌面应用exe

参考&#xff1a; electron安装&#xff08;支持win、mac、linux桌面应用&#xff09; https://blog.csdn.net/weixin_42357472/article/details/140643624 TodoList工具 https://blog.csdn.net/weixin_42357472/article/details/140618446 electron打包过程&#xff1a; 要将…...

数据结构之判断二叉树是否为搜索树(C/C++实现)

文章目录 判断二叉树是否为搜索树方法一&#xff1a;递归法方法二&#xff1a;中序遍历法总结 二叉树是一种非常常见的数据结构&#xff0c;它在计算机科学中有着广泛的应用。二叉搜索树&#xff08;Binary Search Tree&#xff0c;简称BST&#xff09;是二叉树的一种特殊形式&…...

golang长连接的误用

误用一&#xff1a;忘记读取响应的body 由于忘记读取响应的body导致创建大量处于TIME_WAIT状态的连接&#xff08;同时产生大量处于transport.go的readLoop和writeLoop的协程&#xff09; 在linux下运行下面的代码: package mainimport ("fmt""html"&qu…...

Springboot @Validate @Valid 基于复杂嵌套对象的参数校验示例

Springboot Validate Valid 基于复杂嵌套对象的参数校验示例 复杂对象 Data public class Object1 {Length(max 50,message "长度不能超过50位字符")NotBlank(message "名称不能为空")private String name;NotNull(message "不能为空")pri…...

算力共享下的,分级路由转发报文协议与通告

目录 网络双 SLA 约束 一、双SLA约束的定义与背景 二、双SLA约束的应用场景 三、双SLA约束的管理与实施 四、双SLA约束的优势与挑战 算力共享下的,分级路由转发报文协议与通告 基础设施即服务(IaaS)类 型算力资源 函数即服务(FaaS)类型算力服务 软件即服务(SaaS…...

滚动数组详解

滚动数组详解 何为滚动数组&#xff1f;滚动数组是如何优化空间的&#xff1f;交替滚动例题&#xff1a;来自某某轮廓线DP的题目 自我滚动(~~不如交替~~ 完结&#xff01;&#xff01;&#xff01; ( 宇宙免责任书&#xff1a;我用的是C) 何为滚动数组&#xff1f; 什么是滚动…...

C 语言动态链表

线性结构->顺序存储->动态链表 一、理论部分 从起源中理解事物&#xff0c;就是从本质上理解事物。 -杜勒鲁奇 动态链表是通过结点&#xff08;Node&#xff09;的集合来非连续地存储数据&#xff0c;结点之间通过指针相互连接。 动态链表本身就是一种动态分配内存的…...

【Leetcode】二十、记忆化搜索:零钱兑换

文章目录 1、记忆化搜索2、leetcode509&#xff1a;斐波那契数列3、leetcode322&#xff1a;零钱兑换 1、记忆化搜索 也叫备忘录&#xff0c;即把已经计算过的结果存下来&#xff0c;下次再遇到&#xff0c;就直接取&#xff0c;不用重新计算。目的是以减少重复计算。 以前面提…...

json数据格式 继续学习

1.定义 轻量级的数据交互格式&#xff0c;可以按照json数据格式去组织和封装数据。 本质是一个带有特定格式的字符串。 2.功能 负责不同编程语言中的数据传递和交互。 3.json数据格式转化 """ 演示json数据和python字典之间的转换 """ impor…...

gradle 构建项目添加版本信息

gradle 构建项目添加版本信息&#xff0c;打包使用 spring boot 的打包插件 build.gradle 配置文件 bootJar {manifest {attributes(Project-Name: project.name,Project-Version: project.version,"project-Vendor": "XXX Corp","Built-By": &…...

vue3 学习笔记17 -- 基于el-menu封装菜单

vue3 学习笔记17 – 基于el-menu封装菜单 前提条件&#xff1a;组件创建完成 配置路由 // src/router/index.ts import { createRouter, createWebHashHistory } from vue-router import type { RouteRecordRaw } from vue-router export const Layout () > import(/lay…...

使用 Redis 实现验证码、token 的存储,用自定义拦截器完成用户认证、并使用双重拦截器解决 token 刷新的问题

可以看一下我以前做过的笔记&#xff1a;黑马点评 短信登录部分 基于session实现登录流程 1.发送验证码 用户在提交手机号后&#xff0c;会校验手机号是否合法&#xff0c;如果不合法&#xff0c;则要求用户重新输入手机号 如果手机号合法&#xff0c;后台此时生成对应的验…...

反转链表 - 力扣(LeetCode)C语言

206. 反转链表 - 力扣&#xff08;LeetCode&#xff09;( 点击前面链接即可查看题目) /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode* reverseList(struct ListNode* head) {if(head NULL)…...

【Linux】进程间通信(1):进程通信概念与匿名管道

人与人之间是如何通信的&#xff1f;举个简单的例子&#xff0c;假如我是月老&#xff0c;我要为素不相识的但又渴望爱情的男女两方牵红线。我需要收集男方的信息告诉女方&#xff0c;收集女方的信息告诉男方&#xff0c;然后由男女双方来决定是否继续。对于他们而言&#xff0…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容&#xff1b;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容&#xff08;CL&#xff09;与匹配电容&#xff08;CL1、CL2&#xff09;的关系 2. 如何选择 CL1 和 CL…...

PHP 8.5 即将发布:管道操作符、强力调试

前不久&#xff0c;PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5&#xff01;作为 PHP 语言的又一次重要迭代&#xff0c;PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是&#xff0c;借助强大的本地开发环境 ServBay&am…...

手机平板能效生态设计指令EU 2023/1670标准解读

手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读&#xff0c;综合法规核心要求、最新修正及企业合规要点&#xff1a; 一、法规背景与目标 生效与强制时间 发布于2023年8月31日&#xff08;OJ公报&…...