上一节我们看了一个简单的例子,我们通过直接改变二进制的class文件,改变程序的行为,
这一节继续上面的例子看一些其他的情况,用前面的HelloWorld为例
先看java 文件:
public class HelloWorld{ public static void main(String [] arvgs){ System.out.println("hello world"); } }
它的class文件
00000000h: CA FE BA BE 00 00 00 2E 00 1D 0A 00 06 00 0F 09 ; 漱壕............ 00000010h: 00 10 00 11 08 00 12 0A 00 13 00 14 07 00 15 07 ; ................ 00000020h: 00 16 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 ; .....<init>...() 00000030h: 56 01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E ; V...Code...LineN 00000040h: 75 6D 62 65 72 54 61 62 6C 65 01 00 04 6D 61 69 ; umberTable...mai 00000050h: 6E 01 00 16 28 5B 4C 6A 61 76 61 2F 6C 61 6E 67 ; n...([Ljava/lang 00000060h: 2F 53 74 72 69 6E 67 3B 29 56 01 00 0A 53 6F 75 ; /String;)V...Sou 00000070h: 72 63 65 46 69 6C 65 01 00 0F 48 65 6C 6C 6F 57 ; rceFile...HelloW 00000080h: 6F 72 6C 64 2E 6A 61 76 61 0C 00 07 00 08 07 00 ; orld.java....... 00000090h: 17 0C 00 18 00 19 01 00 0B 68 65 6C 6C 6F 20 77 ; .........hello w 000000a0h: 6F 72 6C 64 07 00 1A 0C 00 1B 00 1C 01 00 0A 48 ; orld...........H 000000b0h: 65 6C 6C 6F 57 6F 72 6C 64 01 00 10 6A 61 76 61 ; elloWorld...java 000000c0h: 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 01 00 10 6A ; /lang/Object...j 000000d0h: 61 76 61 2F 6C 61 6E 67 2F 53 79 73 74 65 6D 01 ; ava/lang/System. 000000e0h: 00 03 6F 75 74 01 00 15 4C 6A 61 76 61 2F 69 6F ; ..out...Ljava/io 000000f0h: 2F 50 72 69 6E 74 53 74 72 65 61 6D 3B 01 00 13 ; /PrintStream;... 00000100h: 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 ; java/io/PrintStr 00000110h: 65 61 6D 01 00 07 70 72 69 6E 74 6C 6E 01 00 15 ; eam...println... 00000120h: 28 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 ; (Ljava/lang/Stri 00000130h: 6E 67 3B 29 56 00 21 00 05 00 06 00 00 00 00 00 ; ng;)V.!......... 00000140h: 02 00 01 00 07 00 08 00 01 00 09 00 00 00 1D 00 ; ................ 00000150h: 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 01 ; .......*?.?... 00000160h: 00 0A 00 00 00 06 00 01 00 00 00 01 00 09 00 0B ; ................ 00000170h: 00 0C 00 01 00 09 00 00 00 25 00 02 00 01 00 00 ; .........%...... 00000180h: 00 09 B2 00 02 12 03 B6 00 04 B1 00 00 00 01 00 ; ..?...?.?.... 00000190h: 0A 00 00 00 0A 00 02 00 00 00 03 00 08 00 04 00 ; ................ 000001a0h: 01 00 0D 00 00 00 02 00 0E ; .........
找到第18号常量池,它是一个constant_utf8类型,在第 000000a0h 行 bytes=0X 68 65 6C 6C 6F 20 77 6F 72 6C 64表示的正好是我们要输出的内容,“hello world”,其中0X6F 表示 0,现在我们在0X6F 之前增加4个字节的 0x6F ,如下:
00000000h: CA FE BA BE 00 00 00 2E 00 1D 0A 00 06 00 0F 09 ; 漱壕............ 00000010h: 00 10 00 11 08 00 12 0A 00 13 00 14 07 00 15 07 ; ................ 00000020h: 00 16 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 ; .....<init>...() 00000030h: 56 01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E ; V...Code...LineN 00000040h: 75 6D 62 65 72 54 61 62 6C 65 01 00 04 6D 61 69 ; umberTable...mai 00000050h: 6E 01 00 16 28 5B 4C 6A 61 76 61 2F 6C 61 6E 67 ; n...([Ljava/lang 00000060h: 2F 53 74 72 69 6E 67 3B 29 56 01 00 0A 53 6F 75 ; /String;)V...Sou 00000070h: 72 63 65 46 69 6C 65 01 00 0F 48 65 6C 6C 6F 57 ; rceFile...HelloW 00000080h: 6F 72 6C 64 2E 6A 61 76 61 0C 00 07 00 08 07 00 ; orld.java....... 00000090h: 17 0C 00 18 00 19 01 00 0B 68 65 6C 6C 6F 20 77 ; .........hello w 000000a0h: 6F 6F 6F 6F 6F 72 6C 64 07 00 1A 0C 00 1B 00 1C ; ooooorld........ 000000b0h: 01 00 0A 48 65 6C 6C 6F 57 6F 72 6C 64 01 00 10 ; ...HelloWorld... 000000c0h: 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 ; java/lang/Object 000000d0h: 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 53 79 73 ; ...java/lang/Sys 000000e0h: 74 65 6D 01 00 03 6F 75 74 01 00 15 4C 6A 61 76 ; tem...out...Ljav 000000f0h: 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 65 61 6D ; a/io/PrintStream 00000100h: 3B 01 00 13 6A 61 76 61 2F 69 6F 2F 50 72 69 6E ; ;...java/io/Prin 00000110h: 74 53 74 72 65 61 6D 01 00 07 70 72 69 6E 74 6C ; tStream...printl 00000120h: 6E 01 00 15 28 4C 6A 61 76 61 2F 6C 61 6E 67 2F ; n...(Ljava/lang/ 00000130h: 53 74 72 69 6E 67 3B 29 56 00 21 00 05 00 06 00 ; String;)V.!..... 00000140h: 00 00 00 00 02 00 01 00 07 00 08 00 01 00 09 00 ; ................ 00000150h: 00 00 1D 00 01 00 01 00 00 00 05 2A B7 00 01 B1 ; ...........*?.? 00000160h: 00 00 00 01 00 0A 00 00 00 06 00 01 00 00 00 01 ; ................ 00000170h: 00 09 00 0B 00 0C 00 01 00 09 00 00 00 25 00 02 ; .............%.. 00000180h: 00 01 00 00 00 09 B2 00 02 12 03 B6 00 04 B1 00 ; ......?...?.? 00000190h: 00 00 01 00 0A 00 00 00 0A 00 02 00 00 00 03 00 ; ................ 000001a0h: 08 00 04 00 01 00 0D 00 00 00 02 00 0E ; .............
其他不改变,运行如下:
可以看到错误提醒tag 111 非法,为什么呢,回顾前面的知识,看第18号常量池:
第18个常量:tag=0X 01,为一个constant_UTF8类型(utf8编码的字符串),根据它的定义后面的长度可变,length=0X00 0B表示后面有11个字节属于它的内容:bytes=0X 68 65 6C 6C 6F 20 77 6F 6f 6f 6f ,再往下为另外一个常量,tag=0X6F =111,而class 文件只定义了 tag=1,3,4...11,12.。11种类型(没有2),所以会找不到tag=111,那怎么样才能想程序中多输出字符呢,其实很简单,只是需要将第18号常量的长度增加4个,由0X0B ---》0X0F 。即如下:主要看 000000a0h 行 和 00000070h 行
00000000h: CA FE BA BE 00 00 00 2E 00 1D 0A 00 06 00 0F 09 ; 漱壕............ 00000010h: 00 10 00 11 08 00 12 0A 00 13 00 14 07 00 15 07 ; ................ 00000020h: 00 16 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 ; .....<init>...() 00000030h: 56 01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E ; V...Code...LineN 00000040h: 75 6D 62 65 72 54 61 62 6C 65 01 00 04 6D 61 69 ; umberTable...mai 00000050h: 6E 01 00 16 28 5B 4C 6A 61 76 61 2F 6C 61 6E 67 ; n...([Ljava/lang 00000060h: 2F 53 74 72 69 6E 67 3B 29 56 01 00 0A 53 6F 75 ; /String;)V...Sou 00000070h: 72 63 65 46 69 6C 65 01 00 0F 48 65 6C 6C 6F 57 ; rceFile...HelloW 00000080h: 6F 72 6C 64 2E 6A 61 76 61 0C 00 07 00 08 07 00 ; orld.java....... 00000090h: 17 0C 00 18 00 19 01 00 0F 68 65 6C 6C 6F 20 77 ; .........hello w 000000a0h: 6F 6F 6F 6F 6F 72 6C 64 07 00 1A 0C 00 1B 00 1C ; ooooorld........ 000000b0h: 01 00 0A 48 65 6C 6C 6F 57 6F 72 6C 64 01 00 10 ; ...HelloWorld... 000000c0h: 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 ; java/lang/Object 000000d0h: 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 53 79 73 ; ...java/lang/Sys 000000e0h: 74 65 6D 01 00 03 6F 75 74 01 00 15 4C 6A 61 76 ; tem...out...Ljav 000000f0h: 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 65 61 6D ; a/io/PrintStream 00000100h: 3B 01 00 13 6A 61 76 61 2F 69 6F 2F 50 72 69 6E ; ;...java/io/Prin 00000110h: 74 53 74 72 65 61 6D 01 00 07 70 72 69 6E 74 6C ; tStream...printl 00000120h: 6E 01 00 15 28 4C 6A 61 76 61 2F 6C 61 6E 67 2F ; n...(Ljava/lang/ 00000130h: 53 74 72 69 6E 67 3B 29 56 00 21 00 05 00 06 00 ; String;)V.!..... 00000140h: 00 00 00 00 02 00 01 00 07 00 08 00 01 00 09 00 ; ................ 00000150h: 00 00 1D 00 01 00 01 00 00 00 05 2A B7 00 01 B1 ; ...........*?.? 00000160h: 00 00 00 01 00 0A 00 00 00 06 00 01 00 00 00 01 ; ................ 00000170h: 00 09 00 0B 00 0C 00 01 00 09 00 00 00 25 00 02 ; .............%.. 00000180h: 00 01 00 00 00 09 B2 00 02 12 03 B6 00 04 B1 00 ; ......?...?.? 00000190h: 00 00 01 00 0A 00 00 00 0A 00 02 00 00 00 03 00 ; ................ 000001a0h: 08 00 04 00 01 00 0D 00 00 00 02 00 0E ; .............
再运行:
本站支持 pay for your wishes
相关推荐
2. **找到并修改class文件**:在解压后的目录中找到需要修改的class文件,使用反编译工具(如jd-gui或jd-core-java)查看其源代码,理解并进行必要的修改。修改完成后,需要使用Java编译器(javac)重新编译修改过的...
在Java编程语言中,`class`文件是程序的二...综上所述,`class文件编译器.zip`可能包含了与Java编译相关的工具、教程或示例,涵盖了从源代码到可执行字节码的整个过程,对于学习和理解Java编译机制是非常有价值的资源。
首先,反编译Class文件是为了能理解那些无法直接获取源代码的二进制文件的运行逻辑。尽管Java是开源的,但有些库或组件可能出于安全或商业原因并未公开源代码。在这种情况下,反编译工具就显得尤为重要。 在Eclipse...
#### 二、JVM加载Class文件的过程分析 在深入探讨之前,我们首先了解Java类加载器(ClassLoader)的基本概念。Java类加载器是JVM的重要组成部分之一,它负责查找并加载类文件到JVM的内存空间中。Java程序的运行依赖...
将class文件打包成jar文件是Java开发中常见的需求,尤其在使用WebService的SOAP协议时,为了实现远程调用,往往需要将本地的类文件(.class)打包成jar包进行分发。本文将深入探讨这一过程,包括手动压缩和利用...
本压缩包文件提供了两个示例项目,分别展示了JDK动态代理和CGLib动态代理的实现,帮助我们理解这两种技术的工作原理以及它们生成的class文件结构。 首先,我们来详细了解JDK动态代理。JDK动态代理基于Java的接口...
总的来说,ClassFinal作为一款Java class文件安全加密工具,为开发者提供了一种简单、高效的代码保护方案,尤其适合于那些重视代码安全但又不想改动大量代码的企业级项目。其兼容性和易用性使其在Java开发领域具有...
#### 二、Class文件主要内容解析 1. **Magic Number (魔数)** - 魔数是Class文件的前四个字节,值为`0xCAFEBABE`。它的主要功能是标识该文件为合法的Class文件,便于JVM快速识别和加载。 2. **Version Numbers ...
java修改class文件使用的jclasslib.jar、javassist.jar等等文件。相关步骤、还有一个idea项目示例。(当时找了好久的jclasslib.jar文件,最后才找到一个可用的)
1. **`.class` 文件**:Java 编译器编译 `.java` 源代码文件后产生的二进制文件,包含了 Java 字节码,可以在 Java 虚拟机 (JVM) 上运行。 2. **`jar` 命令**:Java 提供的一个工具,用于将多个 `.class` 文件和其他...
2. **运行Proguard**:打开`proguardgui.bat`,导入配置文件,设置输入目录(包含原始class文件的目录),输出目录(混淆后的class文件输出位置)以及库文件(如JRE或第三方库)。 3. **混淆过程**:点击运行按钮,...
加载编译后的class文件,我们可以使用自定义的ClassLoader。自定义ClassLoader的典型实现会重写`findClass`方法,以便从特定位置(例如文件系统、网络或内存)查找类的字节码。下面是一个简化的例子: ```java ...
2. 使用Java程序根据编号对class文件内容进行修改: 这一步需要编程实现。一个常见的库用于操作.class文件的是“jasmin”或“javassist”。在这里,我们将使用Java编程语言来实现。假设你已经有了一个名为`Main....
这就引出了我们今天要讨论的主题——"Class文件反编译工具"。 反编译工具的主要作用是将Java的`Class`文件转换回可读的源代码(Java源代码),以便开发者理解或调试已编译的代码。这在某些情况下非常有用,比如当...
`.class`文件是Java编译器将源代码(`.java`)编译后的二进制表示,包含了程序的字节码,是Java虚拟机(JVM)运行的基础。在本篇文章中,我们将探讨如何在MyEclipse这款强大的Java集成开发环境中直接打开和查看`.class`...
### 如何使用Java命令将Class文件打包成JAR包 在Java开发中,将多个`.class`文件打包成一个`.jar`文件是常见的需求,这不仅便于管理代码,也利于软件的分发与运行。本文将详细介绍如何通过Java命令行工具`jar`,将...
下面是一个简单的自定义Gradle插件示例,展示了如何使用ByteBuddy修改编译后的class文件: 1. 创建一个新的Gradle插件项目,包含以下目录结构: ``` my-plugin/ ├── src/main/groovy │ └── ...
Java字节码是Java程序编译后的产物,它以`.class`文件的形式存在,是Java虚拟机(JVM)能够理解和执行的二进制代码。本文将深入解析Java字节码的格式,帮助你理解其背后的运行机制。 1. **Java字节码结构** Java...
《使用jclasslib修改Java Class文件内容》 在Java编程世界中,编译后的类文件(.class)是程序的基础,它们包含了字节码指令,是JVM运行时的直接执行对象。然而,通常情况下,我们并不直接操作这些类文件,而是通过...