使用javassist修改class文件

合集下载

Javassist用法详解

Javassist用法详解

Javassist⽤法详解⽬录概述ClassPoolCtClassCtMthodCtFieldCtConstructorClassPathClassLoader⽰例创建Class⽂件调⽤⽣成的类对象修改现有的类对象概述Java字节码以⼆进制的形式存储在.class⽂件中,每⼀个.class⽂件包含⼀个Java类或接⼝。

Javaassist就是⼀个⽤来处理Java字节码的类库。

它可以在⼀个已经编译好的类中添加新的⽅法,或者是修改已有的⽅法,并且不需要对字节码⽅⾯有深⼊的了解。

同时也可以通过完全⼿动的⽅式⽣成⼀个新的类对象。

Maven依赖⽅式:<dependency><groupId>org.javassist</groupId><artifactId>javassist</artifactId><version>3.27.0-GA</version></dependency>Gradle依赖⽅式:implementation 'org.javassist:javassist:3.27.0-GA'ClassPoolClassPool是CtClass对象的容器,它按需读取类⽂件来构造CtClass对象,并且保存CtClass对象以便以后使⽤。

从实现的⾓度来看,ClassPool 是⼀个存储 CtClass 的 Hash 表,类的名称作为 Hash 表的 key。

ClassPool 的 get() 函数⽤于从 Hash 表中查找 key 对应的 CtClass 对象。

如果没有找到,get() 函数会创建并返回⼀个新的 CtClass 对象,这个新对象会保存在 Hash 表中。

需要注意的是ClassPool会在内存中维护所有被它创建过的CtClass,当CtClass数量过多时,会占⽤⼤量的内存,API中给出的解决⽅案是重新创建ClassPool 或有意识的调⽤CtClass的detach()⽅法以释放内存。

javaassist替换类路径

javaassist替换类路径

javaassist替换类路径使用Javaassist替换类路径Java是一种广泛使用的编程语言,它具有强大的功能和灵活的特性。

在Java开发过程中,有时我们需要对类进行动态修改或增强。

这时,Javaassist(Java Programming Assistant)就是一个非常有用的工具。

Javaassist是一个开源的Java字节码编辑器库,它提供了一组API,可以在运行时修改或生成Java字节码。

通过使用Javaassist,我们可以实现在运行时动态修改类的行为,而无需修改源代码。

Javaassist的一个常见应用场景是替换类路径。

类路径是指在Java 虚拟机(JVM)上运行Java程序时,用于查找类文件的路径。

在某些情况下,我们可能需要将程序中某个类的类路径替换为另一个类路径,以实现一些特定的需求。

而Javaassist提供了相应的API,可以帮助我们实现这一目标。

下面我们将介绍如何使用Javaassist替换类路径。

我们需要在项目中引入Javaassist的库文件。

可以通过在项目的构建文件(如Maven的pom.xml)中添加相应的依赖项来实现。

引入Javaassist后,我们就可以在代码中使用Javaassist提供的API 了。

下面是替换类路径的示例代码:```import javassist.ClassPool;import javassist.CtClass;import javassist.LoaderClassPath;public class ClassPathReplacer {public static void replaceClassPath(String className, String newClassPath) throws Exception {ClassPool classPool = ClassPool.getDefault();classPool.insertClassPath(newLoaderClassPath(ClassLoader.getSystemClassLoader()));CtClass ctClass = classPool.get(className);ctClass.defrost();ctClass.replaceClassName(className, newClassPath);ctClass.writeFile();}}```在上面的示例代码中,我们首先创建了一个ClassPool对象,它是Javaassist的核心类之一。

借助jclasslib与javassist修改java+class字节码

借助jclasslib与javassist修改java+class字节码

有时候,我们在没有java源程序的情况下,想改变.CLASS文件的部分内容输出或者改变跳转流,怎么办呢?介绍2个java hacker的工具javassist 以及jclasslib。

下载javassist-3.1RC2和jclasslib_windows_3_0。

解压后,将2个JAR 加入classpath内。

jclasslib_windows_3_0.exe在JAVA_HOME/lib下安装原文件HelloWorld.javapackage com.unmi;public class HelloWorld{public static void main(String[] args){System.out.println("Hello,gorld!");}}想修改输出的”hello world”,用jclasslib.exe 检测可以看到属于常量池的23。

如下代码就针对23 做调整。

package com.unmi;import javassist.ClassPool;import javassist.CtClass;import javassist.CtMethod;import java.io.*;import org.gjt.jclasslib.io.ClassFileWriter;import org.gjt.jclasslib.structures.CPInfo;import org.gjt.jclasslib.structures.ClassFile;import org.gjt.jclasslib.structures.constants.ConstantStringInfo;import org.gjt.jclasslib.structures.constants.ConstantUtf8Info;public class JclasslibTest {public static void main(String[] args) throws Exception {{String filePath = "D:\\java_proj\\com\\unmi\\HelloWorld.class";FileInputStream fis = new FileInputStream(filePath);DataInput di = new DataInputStream(fis);ClassFile cf = new ClassFile();cf.read(di);CPInfo[] infos = cf.getConstantPool();int count = infos.length;for (int i = 0; i < count; i++) {if (infos[i] != null) {System.out.print(i);System.out.print(" = ");System.out.print(infos[i].getVerbose());System.out.print(" = ");System.out.println(infos[i].getTagVerbose());if(i == 23){ConstantUtf8Info uInfo = (ConstantUtf8Info)infos[i];uInfo.setString("china alibaba ");}}}cf.setConstantPool(infos);fis.close();File f = new File(filePath + "c");ClassFileWriter.writeToFile(f, cf);}}}D:\java_proj>javac -cp %CLASSPATH%;. com/unmi/JclasslibTest.javaD:\java_proj>java com.unmi.JclasslibTest1 = com/unmi/HelloWorld = CONSTANT_Class_info2 = com/unmi/HelloWorld = CONSTANT_Utf8_info3 = java/lang/Object = CONSTANT_Class_info4 = java/lang/Object = CONSTANT_Utf8_info5 = <init> = CONSTANT_Utf8_info6 = ()V = CONSTANT_Utf8_info7 = Code = CONSTANT_Utf8_info8 = java/lang/Object.<init> = CONSTANT_Methodref_info9 = <init>()V = CONSTANT_NameAndType_info10 = LineNumberTable = CONSTANT_Utf8_info11 = LocalVariableTable = CONSTANT_Utf8_info12 = this = CONSTANT_Utf8_info13 = Lcom/unmi/HelloWorld; = CONSTANT_Utf8_info14 = main = CONSTANT_Utf8_info15 = ([Ljava/lang/String;)V = CONSTANT_Utf8_info16 = java/lang/System.out = CONSTANT_Fieldref_info17 = java/lang/System = CONSTANT_Class_info18 = java/lang/System = CONSTANT_Utf8_info19 = outLjava/io/PrintStream; = CONSTANT_NameAndType_info20 = out = CONSTANT_Utf8_info21 = Ljava/io/PrintStream; = CONSTANT_Utf8_info22 = Hello,gorld! = CONSTANT_String_info23 = Hello,gorld! = CONSTANT_Utf8_info24 = java/io/PrintStream.println = CONSTANT_Methodref_info25 = java/io/PrintStream = CONSTANT_Class_info26 = java/io/PrintStream = CONSTANT_Utf8_info27 = println(Ljava/lang/String;)V = CONSTANT_NameAndType_info28 = println = CONSTANT_Utf8_info29 = (Ljava/lang/String;)V = CONSTANT_Utf8_info30 = args = CONSTANT_Utf8_info31 = [Ljava/lang/String; = CONSTANT_Utf8_info32 = SourceFile = CONSTANT_Utf8_info33 = HelloWorld.java = CONSTANT_Utf8_info更改生成的HelloWorld.classc 为HelloWorld.class执行输出为D:\java_proj>java com.unmi.HelloWorldchina alibaba 另外,也可以修改if 语句跳转Jclasslib 观测到jvm op code 如下现在想更改>= 为<,怎么办?查询Opcode Mnemonics by Opcode/docs/books/jvms/second_edition/html/Mnemonics.doc.html 并查到>= 的操作码为0xA1所以只要用Ultraedit 修改0xA1 为0xA2 就可以了。

javassist使用流程

javassist使用流程

javassist使用流程javassist是一个开源的Java字节码编辑器库,它提供了一种在运行时修改类文件的方式,可以动态地创建、编辑和修改Java类。

使用javassist可以实现一些在编译时无法完成的操作,比如动态生成类、修改类的行为等。

下面将介绍javassist的使用流程。

1. 引入javassist库首先需要在项目中引入javassist库。

可以通过Maven或手动下载jar包的方式引入。

在引入后,就可以在代码中使用javassist的功能了。

2. 创建ClassPoolClassPool是javassist的核心类,它用于管理被修改的类。

通过ClassPool可以获取要修改的类的CtClass对象,以及创建新的类。

可以通过以下代码创建ClassPool对象:```ClassPool classPool = ClassPool.getDefault();```3. 获取要修改的类通过ClassPool的get方法可以获取要修改的类的CtClass对象。

get方法的参数可以是类的全限定名,也可以是Class对象。

例如,获取ng.String类的CtClass对象可以使用以下代码:```CtClass stringClass = classPool.get("ng.String");```4. 修改类的行为获取到要修改的类的CtClass对象后,就可以对类的行为进行修改了。

可以使用CtClass提供的一系列方法来添加、修改或删除类的成员、方法和字段。

以下是一些常用的示例操作:- 添加方法:```CtMethod newMethod = CtNewMethod.make("public void newMethod() { System.out.println(\"This is a new method.\"); }", ctClass);ctClass.addMethod(newMethod);```- 修改方法:```CtMethod method = ctClass.getDeclaredMethod("methodName");method.insertBefore("{ System.out.println(\"This is insertedbefore the method.\"); }");```- 删除方法:```CtMethod method = ctClass.getDeclaredMethod("methodName");ctClass.removeMethod(method);```- 添加字段:```CtField newField = new CtField(CtClass.intType, "newField", ctClass);ctClass.addField(newField);```- 修改字段:```CtField field = ctClass.getDeclaredField("fieldName");field.setModifiers(Modifier.PRIVATE);```- 删除字段:```CtField field = ctClass.getDeclaredField("fieldName"); ctClass.removeField(field);```5. 生成修改后的类在对类进行修改后,需要将修改后的类写回到磁盘上,或者在内存中动态加载。

javassist使用全解析

javassist使用全解析

javassist使⽤全解析Java 字节码以⼆进制的形式存储在 .class ⽂件中,每⼀个 .class ⽂件包含⼀个 Java 类或接⼝。

Javaassist 就是⼀个⽤来处理 Java 字节码的类库。

它可以在⼀个已经编译好的类中添加新的⽅法,或者是修改已有的⽅法,并且不需要对字节码⽅⾯有深⼊的了解。

同时也可以去⽣成⼀个新的类对象,通过完全⼿动的⽅式。

1. 使⽤ Javassist 创建⼀个 class ⽂件⾸先需要引⼊jar包:<dependency><groupId>org.javassist</groupId><artifactId>javassist</artifactId><version>3.25.0-GA</version></dependency>编写创建对象的类:package com.rickiyang.learn.javassist;import javassist.*;/*** @author rickiyang* @date 2019-08-06* @Desc*/public class CreatePerson {/*** 创建⼀个Person 对象** @throws Exception*/public static void createPseson() throws Exception {ClassPool pool = ClassPool.getDefault();// 1. 创建⼀个空类CtClass cc = pool.makeClass("com.rickiyang.learn.javassist.Person");// 2. 新增⼀个字段 private String name;// 字段名为nameCtField param = new CtField(pool.get("ng.String"), "name", cc);// 访问级别是 privateparam.setModifiers(Modifier.PRIVATE);// 初始值是 "xiaoming"cc.addField(param, CtField.Initializer.constant("xiaoming"));// 3. ⽣成 getter、setter ⽅法cc.addMethod(CtNewMethod.setter("setName", param));cc.addMethod(CtNewMethod.getter("getName", param));// 4. 添加⽆参的构造函数CtConstructor cons = new CtConstructor(new CtClass[]{}, cc);cons.setBody("{name = \"xiaohong\";}");cc.addConstructor(cons);// 5. 添加有参的构造函数cons = new CtConstructor(new CtClass[]{pool.get("ng.String")}, cc);// $0=this / $1,$2,$3... 代表⽅法参数cons.setBody("{$ = $1;}");cc.addConstructor(cons);// 6. 创建⼀个名为printName⽅法,⽆参数,⽆返回值,输出name值CtMethod ctMethod = new CtMethod(CtClass.voidType, "printName", new CtClass[]{}, cc);ctMethod.setModifiers(Modifier.PUBLIC);ctMethod.setBody("{System.out.println(name);}");cc.addMethod(ctMethod);//这⾥会将这个创建的类对象编译为.class⽂件cc.writeFile("/Users/yangyue/workspace/springboot-learn/java-agent/src/main/java/");}public static void main(String[] args) {try {createPseson();} catch (Exception e) {e.printStackTrace();}}}执⾏上⾯的 main 函数之后,会在指定的⽬录内⽣成 Person.class ⽂件://// Source code recreated from a .class file by IntelliJ IDEA// (powered by Fernflower decompiler)//package com.rickiyang.learn.javassist;public class Person {private String name = "xiaoming";public void setName(String var1) { = var1;}public String getName() {return ;}public Person() { = "xiaohong";}public Person(String var1) { = var1;}public void printName() {System.out.println();}}跟咱们预想的⼀样。

java修改class文件

java修改class文件

java修改class⽂件最近因为⼯作需要修改class⽂件中⼀个变量的值,特此记录2、找到要修改的变量所在的地址3、创建⼀个java⼯程、并且将jclasslib.jar导⼊、执⾏以下代码即可1package .c;23import java.io.*;4import org.gjt.jclasslib.io.ClassFileWriter;5import org.gjt.jclasslib.structures.CPInfo;6import org.gjt.jclasslib.structures.ClassFile;7import org.gjt.jclasslib.structures.constants.ConstantUtf8Info;89public class Main {10public static void main(String[] args) throws Exception {1112 String filePath = "C:\\Main.class";13 FileInputStream fis = new FileInputStream(filePath);14 DataInput di = new DataInputStream(fis);15 ClassFile cf = new ClassFile();16 cf.read(di);17 CPInfo[] infos = cf.getConstantPool();1819int count = infos.length;20for (int i = 0; i < count; i++) {21if (infos[i] != null) {22 System.out.print(i);23 System.out.print(" = ");24 System.out.print(infos[i].getVerbose());25 System.out.print(" = ");26 System.out.println(infos[i].getTagVerbose());27if (i == 21) {//刚刚找到的是21位置28 ConstantUtf8Info uInfo = (ConstantUtf8Info) infos[i]; //刚刚那⾥是CONSTANT_Utf-8_info所以这⾥要⽤这个29 uInfo.setBytes("baidu".getBytes());30 infos[i] = uInfo;31 }32 }33 }34//这种⽅式也可以,⼀样的35/* if(infos[count] != null) {36 ConstantUtf8Info uInfo = (ConstantUtf8Info) infos[i]; //刚刚那⾥是CONSTANT_Utf-8_info所以这⾥要⽤这个37 uInfo.setBytes("baidu".getBytes());38 infos[count] = uInfo;39 }*/4041 cf.setConstantPool(infos);42 fis.close();43 File f = new File(filePath);44 ClassFileWriter.writeToFile(f, cf);45 }46 }。

javassist jar 修改 方法

javassist jar 修改 方法

javassist jar 修改方法摘要:1.简介2.javassist 是什么3.如何使用javassist 修改jar 包4.修改方法5.总结正文:1.简介在Java 开发中,我们有时需要对jar 包进行一些修改,例如添加、删除或修改类、方法等。

javassist 是一个Java 字节码修改框架,它可以帮助我们轻松地实现这些操作。

2.javassist 是什么Javassist 是一个强大的Java 字节码修改工具,它可以让Java 程序在运行时动态地修改类和字节码。

它支持对类、方法、字段等进行操作,提供了丰富的API 供开发者使用。

3.如何使用javassist 修改jar 包要使用javassist 修改jar 包,首先需要将jar 包转换为Class 文件,然后使用Javassist 的API 对Class 文件进行修改。

接下来,将修改后的Class 文件重新打包成jar 包。

具体步骤如下:a.将jar 包转换为Class 文件使用`jar2class`工具将jar 包转换为Class 文件,例如:`jar2class -x input.jar output`。

b.使用Javassist 修改Class 文件使用Javassist 的API 对Class 文件进行修改,例如:```javaClassPool pool = new ClassPool();pool.appendClassPath(new File("input.jar"));CtClass ctClass = pool.getCtClass("com.example.ClassName");// 修改方法CtMethod method = ctClass.getDeclaredMethod("methodName");method.setBody("{System.out.println("修改后的方法实现");}");// 添加方法CtMethod newMethod = CtMethod.make(Modifier.PUBLIC, ctClass, "newMethodName", new CtClass[]{}, "{}");ctClass.addMethod(newMethod);// 删除字段ctClass.removeField("fieldName");// 修改字段ctClass.getField("fieldName").setModifiers(Modifier.PRIVATE);// 保存修改后的Class 文件ctClass.writeFile("output.class");```c.将修改后的Class 文件重新打包成jar 包使用`jar`命令将修改后的Class 文件打包成jar 包,例如:`jar cvf output.jar output.class`。

javassist jar 修改 方法

javassist jar 修改 方法

javassist jar 修改方法【实用版3篇】目录(篇1)1.Javassist 简介2.Javassist 的功能3.如何使用 Javassist 修改 jar 文件中的方法4.注意事项和局限性正文(篇1)一、Javassist 简介Javassist(Java Class File Processor)是一个开源的 Java 字节码处理工具,它可以对 Java 字节码进行编辑、修改、生成等操作。

使用Javassist,我们可以在保持 Java 代码不变的情况下,修改其行为。

这对于一些需要对已有代码进行定制,但又不想修改原有代码的情况非常有用。

二、Javassist 的功能Javassist 的主要功能有:1.读取和修改 Java 类文件的字节码。

2.生成新的 Java 类文件。

3.动态地创建和修改 Java 类的行为。

4.为 Java 类添加、删除或修改方法、字段等。

三、如何使用 Javassist 修改 jar 文件中的方法下面是一个使用 Javassist 修改 jar 文件中的方法的简单示例:1.首先,需要导入 Javassist 相关的库。

```javaimport javassist.ClassPool;import javassist.CtClass;import javassist.CtMethod;import javassist.Modifier;import java.io.File;import java.io.FileInputStream;import java.io.IOException;```2.然后,创建一个 ClassPool 实例,用于加载和修改类文件。

```javaClassPool pool = new ClassPool();```3.指定要修改的 jar 文件路径,并加载到 ClassPool 中。

```javaFile jarFile = new File("path/to/your/jarfile.jar"); FileInputStream fis = new FileInputStream(jarFile); pool.open(fis, "jar");```4.通过 ClassPool 实例,获取需要修改的方法所在的类。

javassist使用流程

javassist使用流程

javassist使用流程Javassist使用流程简介Javassist是一个用于Java字节码操作的开源库,它能够动态地编辑字节码,并且支持在运行时生成、修改和转换Java类文件。

本文将详细介绍Javassist的使用流程,帮助读者快速上手。

安装1.在项目的构建文件中,添加Javassist的依赖。

2.执行构建命令,下载并安装Javassist。

常用功能以下是Javassist的一些常用功能,你可以根据需求选择合适的功能进行使用。

1. 类加载与获取•利用ClassPool类加载目标类文件。

•通过CtClass获取目标类的属性、方法等信息。

•使用ClassPool创建新的类。

2. 类修改与生成•新建ClassPool实例。

•调用makeClass()方法创建一个新的类。

•使用CtClass的相关方法对类进行修改,如添加字段、删除方法等。

3. 代码注入与修改•使用CtClass的addMethod()方法添加新方法。

•通过CtMethod对象获取方法体,使用insertBefore()和insertAfter()方法进行代码注入。

•使用CtMethod的setBody()方法修改方法体。

4. 方法重命名与删除•使用CtMethod的setName()方法对方法进行重命名。

•使用CtClass的removeMethod()方法删除方法。

5. 字段修改与生成•使用CtField类创建新字段,并通过CtClass的addField()方法将其添加到类中。

•调用CtField对象的相关方法对字段进行修改,如修改访问修饰符、修改字段名等。

使用示例以下示例演示了如何使用Javassist对一个类进行修改,在其原有的hello()方法前后注入日志输出代码。

// 导入相关类和方法import ;import ;import ;// 获取目标类ClassPool pool = ();CtClass targetClass = ("");// 获取目标方法CtMethod targetMethod = ("hello");// 在方法前插入代码String beforeCode = "(\"Before method\");"; (beforeCode);// 在方法后插入代码String afterCode = "(\"After method\");"; (afterCode);总结Javassist是一款强大的动态字节码操作库,可以在运行时对Java类进行修改和生成。

javassist jar 修改 方法

javassist jar 修改 方法

javassist jar 修改方法【原创实用版3篇】目录(篇1)1.Javassist 简介2.Javassist 的功能3.如何使用 Javassist 修改 Java 类4.使用 Javassist 修改方法的实例正文(篇1)一、Javassist 简介Javassist 是一个开源的 Java 字节码操作工具,它可以在运行时修改 Java 类的结构和行为。

通过使用 Javassist,开发者可以在不修改源代码的情况下,对 Java 类的字节码进行操作,实现诸如添加、删除、修改类成员等高级功能。

二、Javassist 的功能Javassist 提供了丰富的 API,可以实现以下功能:1.创建新的 Java 类2.修改现有 Java 类的字节码3.添加或删除类成员4.修改类成员的访问权限5.修改类成员的类型6.添加或删除构造方法7.添加或删除静态方法8.添加或删除实例方法9.修改方法的参数列表10.修改方法的返回值类型三、如何使用 Javassist 修改 Java 类使用 Javassist 修改 Java 类的步骤如下:1.引入 Javassist 依赖2.加载需要修改的 Java 类3.获取类的字节码4.对字节码进行操作5.将修改后的字节码写回类文件下面是一个简单的示例,演示如何使用 Javassist 修改 Java 类的方法:```javaimport javassist.*;public class JavassistDemo {public static void main(String[] args) {try {// 加载需要修改的 Java 类Class<?> clazz =ClassLoader.getSystemClassLoader().loadClass("com.example.MyCla ss");// 获取类的字节码byte[] byteCode =clazz.getProtectionDomain().getCode();// 创建一个方法处理器,用于修改方法MethodHandler methodHandler = new MethodHandler() {@Overridepublic void visit(MethodVisitor mv, int access, String name, String desc, Code code) {// 修改方法的访问权限mv.visit(access, name, desc, code);// 修改方法的返回值类型code.getReturnType().set(Code.Type.INT);}};// 对字节码进行操作CodeTransformer transformer = new CodeTransformer(methodHandler);byte[] modifiedByteCode =transformer.transform(byteCode, clazz);// 将修改后的字节码写回类文件clazz.getProtectionDomain().setCode(modifiedByteCode);// 重新加载修改后的类Class<?> modifiedClazz =ClassLoader.getSystemClassLoader().loadClass("com.example.MyClass");// 创建一个实例,并调用修改后的方法Object instance = modifiedClazz.newInstance();Method method =modifiedClazz.getMethod("myMethod");int result = (Integer) method.invoke(instance);System.out.println("Result: " + result);} catch (Exception e) {e.printStackTrace();}}}```四、使用 Javassist 修改方法的实例在上述示例中,我们使用 Javassist 修改了名为"myMethod"的方法,将其返回类型从原本的 String 修改为 Integer。

javaassist修改方法

javaassist修改方法

javaassist修改方法使用Javaassist修改方法Javaassist是一个强大的Java字节码操作库,可以在运行时修改已经编译好的字节码文件,进而改变程序的行为。

本文将介绍如何使用Javaassist修改方法。

Javaassist的基本概念在开始介绍Javaassist的使用之前,我们先来了解一下Javaassist 的基本概念。

Javaassist是由Javassist Class Pool类、CtClass类、CtMethod类等组成的,其中Class Pool类用于加载字节码文件,CtClass类用于表示一个类,CtMethod类用于表示一个方法。

使用Javaassist修改方法的步骤使用Javaassist修改方法的步骤如下:1. 创建一个ClassPool对象,用于加载字节码文件。

2. 使用ClassPool对象的get方法加载待修改的类。

3. 使用CtClass类的getDeclaredMethod方法获取待修改的方法。

4. 使用CtMethod类的insertBefore或insertAfter方法在方法的前面或后面插入代码。

5. 使用CtMethod类的toBytecode方法将修改后的字节码文件转换为字节数组。

6. 使用CtClass类的writeFile方法将修改后的字节码文件写入磁盘。

下面我们将通过一个示例来演示使用Javaassist修改方法的过程。

示例:修改方法的参数假设我们有一个类Calculator,其中有一个方法add,用于计算两个数的和。

现在我们希望在方法的前面打印出方法的参数和返回值,可以使用Javaassist来实现这个需求。

我们需要在pom.xml文件中添加Javaassist的依赖:```<dependency><groupId>org.javassist</groupId><artifactId>javassist</artifactId><version>3.27.0-GA</version></dependency>```然后,我们创建一个类Calculator:```javapublic class Calculator {public int add(int a, int b) {return a + b;}}```接下来,我们使用Javaassist修改add方法的代码:```javaimport javassist.*;public class ModifyMethodExample {public static void main(String[] args) throws Exception {// 创建一个ClassPool对象ClassPool classPool = ClassPool.getDefault();// 使用ClassPool对象的get方法加载待修改的类CtClass ctClass = classPool.get("Calculator");// 使用CtClass类的getDeclaredMethod方法获取待修改的方法CtMethod addMethod = ctClass.getDeclaredMethod("add");// 使用CtMethod类的insertBefore方法在方法的前面插入代码addMethod.insertBefore("{ System.out.println(\"参数a=\" + $1); System.out.println(\"参数b=\" + $2); }");// 使用CtMethod类的insertAfter方法在方法的后面插入代码addMethod.insertAfter("{ System.out.println(\"返回值=\" + $_); }");// 使用CtMethod类的toBytecode方法将修改后的字节码文件转换为字节数组byte[] bytecode = addMethod.toBytecode();// 使用CtClass类的writeFile方法将修改后的字节码文件写入磁盘ctClass.writeFile();}}```运行上述代码后,Javaassist会在add方法的前面插入打印参数的代码,以及在方法的后面插入打印返回值的代码。

java 修改 class方法

java 修改 class方法

java 修改 class方法
在Java中,你不能直接修改已经编译的`.class`文件。

这是因为Java是一种静态类型语言,编译后的`.class`文件包含了完整的类型信息,这些信息在运行时是不可变的。

然而,有几种方法可以间接地"修改"类的方法:
1. 字节码操作库:你可以使用像ASM或Javassist这样的字节码操作库来读取、修改和重新编译类的字节码。

这些库允许你在类加载到JVM之前修改其字节码,从而实现方法的修改。

2. 动态代理:你可以使用Java的动态代理来"修改"类的方法。

动态代理允许你创建一个实现了特定接口的新类,该类在运行时将调用你提供的处理程序。

通过这种方式,你可以拦截方法调用并改变其行为。

3. Aspect Oriented Programming (AOP):AOP是一种编程范式,允许程序员定义跨多个类的横切关注点,如日志、事务管理和安全。

通过使用像Spring AOP这样的框架,你可以定义切面来拦截方法调用,并在调用前后执行特定的代码。

这些方法都有其优点和局限性,并且通常更适用于大型应用程序或框架开发,而不是日常的编码工作。

如果你只是想改变类的方法行为,通常更好的做法是直接修改源代码,然后重新编译和部署它。

javassist jar 修改 方法

javassist jar 修改 方法

javassist jar 修改方法在软件开发过程中,我们经常会遇到需要修改已编译代码的情况。

使用Java编程语言时,有许多方式可以达到这一目的,其中之一是使用javassist jar库。

javassist是一个用于在运行时编辑字节码的Java库。

通过使用javassist,我们可以在不重新编译代码的情况下修改已编译的Java类。

接下来,我将介绍如何使用javassist jar库来修改方法。

首先,确保已经将javassist jar库添加到项目的构建路径中。

你可以从Maven 仓库或其他可靠的源获取该库。

下载并将其添加到项目的classpath中。

接下来,我们需要创建一个简单的Java类,用于演示如何使用javassist来修改方法:```javapublic class MyClass {public static void main(String[] args) {System.out.println("Hello, World!");}public void originalMethod() {System.out.println("This is the original method.");}}```接下来,我们将使用javassist来修改上述类中的方法。

我们将修改`originalMethod`方法,使其输出修改后的消息。

以下是实现此目的的代码示例:```javaimport javassist.*;public class MyClassModifier {public static void main(String[] args) {try {// 获取类池ClassPool classPool = ClassPool.getDefault();// 获取要修改的类CtClass ctClass = classPool.get("MyClass");// 获取要修改的方法CtMethod ctMethod = ctClass.getDeclaredMethod("originalMethod");// 修改方法实现ctMethod.setBody("{ System.out.println(\"This is the modified method.\"); }");// 保存修改后的类ctClass.writeFile();System.out.println("Method Modified Successfully!");} catch (Exception e) {e.printStackTrace();}}}```在上述示例代码中,我们使用了javassist的各种类和方法,以获取要修改的类、方法,并将其实现更改为我们所需的内容。

使用javassist?实现直接修改class文件中的方法

使用javassist?实现直接修改class文件中的方法

使用javassist 实现直接修改class文件中的方法使用javassist 可以实现直接修改class文件中的方法,javassist是jboss的一个子项目,其主要的优点,在于简单,而且快速。

直接使用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类。

下面是例子:1.要修改的class文件的代码,当然正常情况下你是看不到的package com.ms.xbox.halo.reach;public class For_test {public final boolean output(){return false;}public static void main(String[] args) {// TODO Auto-generated method stubString strAaa="输出结果";System.out.println(strAaa);}}2.随便建一个java工程,引入javassist的jar包,编译环境我用的1.4版本jdk,修改代码如下import javassist.*;public class test {public static void main(String args[]) throws Exception{ClassPool cp = ClassPool.getDefault();//获得类文件名CtClass cc = cp.get("com.ms.xbox.halo.reach.For_test");//获得要修改的方法名CtMethod m = cc.getDeclaredMethod("output");//这里是将返回结果改成truem.insertBefore("return true;");cc.writeFile();}}3.执行java test,用反编译工具(这里用的是jd-gui),再去看看文件夹 com\ms box\halo\reach下的类For_test,方法output已经被修改了package com.ms.xbox.halo.reach;public class For_test {public final boolean output(){return true;return false;}public static void main(String[] args) {// TODO Auto-generated method stubString strAaa="输出结果";System.out.println(strAaa);}}当然javassist 还有很多的功能,可以修改类中方法的属性,新增加方法,修改已有方法的程序体,上面只是一个很简单的例子.感谢能看完全文,javassist jar包的下载地址:/project/jboss/Javassist/3.11.0.GA/javassist-3.11.GA.zip。

javassistjar修改方法

javassistjar修改方法

javassistjar修改方法要修改一个方法,首先需要获取到对应的类。

可以使用以下代码来获取类:```javaClassPool pool = ClassPool.getDefault(;```一旦我们获得了要修改的类,就可以使用以下代码来获取要修改的方法:```javaCtMethod ctMethod = ctClass.getDeclaredMethod("myMethod");```上述代码中,"myMethod"是要修改的方法的名称。

一旦我们获取到了要修改的方法,我们可以使用以下代码来修改方法的实现:```javactMethod.setBody("{ System.out.println(\"Modifiedmethod\"); }");```上述代码中,我们使用了一个字符串来表示新的方法实现。

可以在字符串中编写任意的Java代码来实现期望的修改。

最后,我们需要将修改后的类保存到磁盘上或加载到内存中。

以下代码演示了如何将修改后的类保存到磁盘上:```javactClass.writeFile(;```上述代码将修改后的类保存到默认的输出目录中。

除了修改方法实现外,我们还可以使用javassist库进行其他类型的修改,如添加新的方法、修改字段、添加注解等。

在使用javassist库时,需要注意以下几点:1. 如果要修改的类在类路径上,则ClassPool.getDefault(方法将返回一个默认的ClassPool实例,该实例将类路径中的类。

如果要修改的类不在类路径上,则需要使用ClassPool对象的insertClassPath(方法设置类路径。

2.进行类的修改后,需要注意可能会破坏类的结构。

因此,在修改类之前,最好先备份原始的类文件,以防修改后无法恢复。

3.在修改类时,需要谨慎操作,确保修改后的类仍然是有效且可用的。

使用javassist修改class文件

使用javassist修改class文件

使用javassist修改class文件Firestorm是一个用JAVA写的代码生成工具,可以替你节省很多的代码量,可以说同类软件中功能最强的一个。

Firestorm是一个用JAVA写的代码生成工具,可以替你节省很多的代码量,可以说同类软件中功能最强的一个。

你可以在网上下载到最新的2.3试用版本,同时网站会发给你一个试用的license文件。

既然是试用,那么在使用上肯定有一定的限制。

主要限制有3个:1.只能最多生成5张表的DAO;2.有时间限制;3.不能自己定制代码生成;为了能够更好的试用这个软件,我得改改它,去掉这些限制。

将firestorm.jar打开后,可以看到它使用了混淆器进行代码保护,不同于大多数的混淆器生成的文件,它的class和package大部分都是以关键字来命名,所以如果你用JAD之类的工具把它反编译后是不能再把它编译成功,编译器会提示出错误。

反编译后,找到几个有关注册的关键文件,发现它使用的是数字签名技术来做的保护,所以想逆向找出注册码的计算方法是不可行的了,只能通过修改文件的方法来破解。

通常我们是先反编译,然后再修改反编译后生成的原文件,最后再重新编译。

但是由于文件名和包名的关系我们无法进行编译,除非把它的这些‘非法'的文件名和包名全部改成符合java语言规范的名称,由于类,包众多,互相调用也很频繁,所以这种方法几乎不可能的。

另外一种方法就是使用softice之类的调试软件来破解,不过这个脱离JAVA的范畴,这里不做讨论。

还有一种方法可能很少有人用,就是先反编译得到原文件,然后找到关键的方法后修改它的字节码,也就是class文件,这中方法往往需要你知道一些有关CLASS文件格式方面的知识(如果没有也不用担心),有许多的处理字节码的工具可以帮助你,比较流行的这类工具主要有:的BCEL; 的javassist;的asm。

都是出身名门哈。

这3个工具各有特点,这次我选用javassist,因为它修改class文件最方便,甚至不需要懂得字节码和class文件格式。

Javassist入门手册

Javassist入门手册

Javassist入门手册Author : Shigeru ChibaTranslator : 吕承纲1. 读写字节码Javassist是一个Java字节码操作类库, Java字节码被保存在一个被称为class文件的二进制文件中,每个类文件都包含一个Java类或接口。

Javassist.CtClass是类文件的抽象代表。

一个CtClass(编译时类)对象负责处理一个类文件。

下面是个简单的例子:ClassPool pool = ClassPool.getDefault();CtClass cc = pool.get("test.Rectangle");cc.setSuperclass(pool.get("test.Point"));cc.writeFile();程序首先获取一个ClassPool对象,此对象通过Javassist控制字节码的修改。

ClassPool对象是代表类文件的CtClass对象的容器。

它读取类文件来构建CtClass对象,并且记录对象结构,以便于后面的访问。

要修改一个类的定义,用于必须首先通过ClassPool的get()方法来得到代表这个类的CtClass对象。

如上所述,我们从ClassPool对象中获取代表类test.Rectangle的CtClass对象,并赋值给变量cc。

getDefault()方法用于搜索默认的系统路径并返回ClassPool对象。

从实现的角度看,ClassPool就是CtClass对象的哈希表,以类名称作为键值。

ClassPool的get()方法通过指定的键值来搜寻CtClass对象。

通过ClassPool获取到的CtClass对象可被修改(后面将展示如何修改CtClass)。

在上面的例子中,类test.Rectangle的父类被修改为test.Point。

这个变化将会通过CtClass的writeFile()方法调用最终实现。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

本文由beikexiami贡献 doc1。

使用 javassist 修改 class 文件 Firestorm 是一个用 JAVA 写的代码生成工具,可以替你节省很多的代码量,可以说同类软件中功能最强 的一个。

 Firestorm 是一个用 JAVA 写的代码生成工具,可以替你节省很多的代码量,可以说同类软件中功能最强 的一个。

 你可以在网上下载到最新的 2.3 试用版本,同时网站会发给你一个试用的 license 文件。

既然是试用, 那么在使用上肯定有一定的限制。

主要限制有 3 个: 1.只能最多生成 5 张表的 DAO; 2.有时间限制; 3.不能自己定制代码生成; 为了能够更好的试用这个软件,我得改改它,去掉这些限制。

将 firestorm.jar 打开后,可以看到它使用 了 混淆器进行代码保护, 不同于大多数的混淆器生成的文件, 它的 class 和 package 大部分都是以关键字来 命名, 所以如果你用 JAD 之类的工具把它反编译后是不能再把它编译成功,编译器会提示出错误。

 反编译后,找到几个有关注册的关键文件,发现它使用的是数字签名技术来做的保护,所以想逆向找出 注册码的计算方法是不可行的了,只能通过修改文件的方法来破解。

通常我们是先反编译,然后再修改 反编译后生成的原文件,最后再重新编译。

但是由于文件名和包名的关系我们无法进行编译,除非把它的 这些‘非法'的文件名和包名全部改成符合 java 语言规范的名称,由于类,包众多,互相调用也很 频繁,所以这种方法几乎不可能的。

 另外一种方法就是使用 softice 之类的调试软件来破解,不过这个脱离 JAVA 的范畴,这里不做讨论。

 还有一种方法可能很少有人用,就是先反编译得到原文件,然后找到关键的方法后修改它的字节码, 也就是 class 文件,这中方法往往需要你知道一些有关 CLASS 文件格式方面的知识(如果没有也不用担 心), 有许多的处理字节码的工具可以帮助你,比较流行的这类工具主要有:apache.org 的 BCEL; jboss.com 的 javassist;objectweb.org 的 asm。

都是出身名门哈。

这 3 个工具各有特点, 这次我选用 javassist,因为它修改 class 文件最方便,甚至不需要懂得字节码和 class 文件格式。

 让我们来看看具体步骤: step1: 下载并安装 FIRESTORM。

 step2: 反编译 jar 文件,阅读代码,找到关键的方法。

当然,我这里写出来,你就不用再麻烦了。

(其实这步 是最 麻烦的)。

 找到 com.codefutures.if.if 文件中的方法 public static boolean a(java.security.PublicKey publickey, byte abyte0[], byte abyte1[]) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException, java.security.InvalidKeyException, java.security.SignatureException { java.security.Signature java.security.Signature.getInstance("SHA1withDSA", "SUN"); signature.initVerify(publickey); signature.update(abyte0); return signature.verify(abyte1); } 这个方法是对公钥进行检验,修改的思路就是直接让他返回一个 true. signature = step2: 收到 firestorm.license 文件后不要急着安装,先修改如下: <custom-codegen>no</custom-codegen> 改为 <custom-codegen>yes</custom-codegen> <restriction>5</restriction> 改为 <restriction>none</restriction> <expiry-date>[日期]</expiry-date> 改为 <expiry-date>never</expiry-date> 修改后放到 firestorm 的安装路径的 license 目录。

step3: 修改 com.codefutures.if.if 的 class 文件.这里我们需要写一个小程序来完成实现: import javassist.ClassPool; import javassist.CtClass; import javassist.CtMethod; public class Test { public static void main(String[] args) throws Exception { ClassPool pool = ClassPool.getDefault(); //设置目标类的路径,确保能够找到需要修改的类,这里我指向 firestorm.jar //解包后的路径 pool.insertClassPath("d:/work/firestorm/firestorm") ; //获得要修改的类 CtClass cc = pool.get("com.codefutures.if.if"); //设置方法需要的参数 CtClass[] param = new CtClass[3] ; param[0] = pool.get("java.security.PublicKey") ; param[1] = pool.get("byte[]") ; param[2] = pool.get("byte[]") ; //得到方法 CtMethod m = cc.getDeclaredMethod("a", param); //插入新的代码 m.insertBefore("{return true ;}") ; //保存到文件里 cc.writeFile() ; } } 修改完后,你可以反编译修改过的的 class 文件,看看代码是否加入成功。

step4: 将所有的 class 文件重新打包成 firestorm.jar,然后替换 [firestorm 安装路径]/lib/firestorm.jar,再启动 firestorm 即可。

一、直接修改字节码 要查看“return false”对应字节码需要使用 JClassLib 工具,JClassLib 有一个可视 化的界面,方便我们查看类的变量、方法、静态数据等,如下图: 这个 a 方法(也许实际名称就是 sendsms)的字节码如下: 0 aload_0 1 invokestatic #42 <javax/microedition/io/Connector.open> 4 checkcast #11 <javax/wireless/messaging/MessageConnection> 7 dup 8 astore_2 9 ldc #61 <text> 11 invokeinterface #48 <javax/wireless/messaging/MessageConnection.newMessage> count 2 16 checkcast #12 <javax/wireless/messaging/TextMessage> 19 astore_3 20 aload_2 21 invokestatic #29 24 ifne 34 (+10) 27 aload_3 28 invokestatic #29 31 ifeq 36 (+5) 34 iconst_0 35 ireturn 36 aload_3 37 aload_0 38 invokeinterface #50 <javax/wireless/messaging/TextMessage.setAddress> count 2 43 aload_3 44 aload_1 45 invokeinterface #51 <javax/wireless/messaging/TextMessage.setPayloadText> count 2 50 aload_2 51 aload_3 52 invokeinterface #49 <javax/wireless/messaging/MessageConnection.send> count 2 57 aload_2 58 invokeinterface #47 <javax/wireless/messaging/MessageConnection.close> count 1 63 iconst_1 64 ireturn 65 pop 66 iconst_0 67 ireturn 通过查找 JVM 指令集, 0x03 iconst_0 int 型 1 推送至栈顶 ,0xac ireturn 的 将 int 型 0 推送至栈顶 , 0x04 iconst_1 将 从当前方法返回 int,很明显,63-67 行就是对应 return true; JVM INSTR pop ; return false; 这 5 行对应的 16 进制值是: 0x04,0xAC,0x57,0x03,0xAC,于是, 16 进制编辑器打开, 用 查找 04AC5703AC 的位置,果然不负众望,接下来你知道怎么做了吧,把 0x03 这个位置的值 换成 0x04,那么这个 return false 不就变成 return true 了,呵呵。

JVM 指令集及各指令的详细使用说明 1. 指令码 助记符 2. 0x00 nop 说明 什么都不做 将 int 型-1 推送至栈顶 将 int 型 0 推送至栈顶 将 int 型 1 推送至栈顶 将 int 型 2 推送至栈顶 将 int 型 3 推送至栈顶 将 int 型 4 推送至栈顶 将 int 型 5 推送至栈顶 将 long 型 0 推送至栈顶 将 long 型 1 推送至栈顶 将 float 型 0 推送至栈顶 将 float 型 1 推送至栈顶 将 float 型 2 推送至栈顶 将 double 型 0 推送至栈顶 将 double 型 1 推送至栈顶 将单字节的常量值(-128 ̄127)推送至栈顶 将一个短整型常量值(-32768 ̄32767)推送至栈顶 将 int, float 或 String 型常量值从常量池中推送至栈顶 将 int, float 或 String 型常量值从常量池中推送至栈顶(宽索引) 将 long 或 double 型常量值从常量池中推送至栈顶(宽索引) 将指定的 int 型本地变量推送至栈顶 将指定的 long 型本地变量推送至栈顶 将指定的 float 型本地变量推送至栈顶 将指定的 double 型本地变量推送至栈顶 将指定的引用类型本地变量推送至栈顶 将第一个 int 型本地变量推送至栈顶 将第二个 int 型本地变量推送至栈顶 将第三个 int 型本地变量推送至栈顶 3. 0x01 aconst_null 将 null 推送至栈顶 4. 0x02 iconst_m1 5. 0x03 iconst_0 6. 0x04 iconst_1 7. 0x05 iconst_2 8. 0x06 iconst_3 9. 0x07 iconst_4 10. 0x08 iconst_5 11. 0x09 lconst_0 12. 0x0a lconst_1 13. 0x0b fconst_0 14. 0x0c fconst_1 15. 0x0d fconst_2 16. 0x0e dconst_0 17. 0x0f dconst_1 18. 0x10 bipush 19. 0x11 sipush 20. 0x12 ldc 21. 0x13 ldc_w 22. 0x14 ldc2_w 23. 0x15 iload 24. 0x16 lload 25. 0x17 fload 26. 0x18 dload 27. 0x19 aload 28. 0x1a iload_0 29. 0x1b iload_1 30. 0x1c iload_2 31. 0x1d iload_3 32. 0x1e lload_0 33. 0x1f lload_1 34. 0x20 lload_2 35. 0x21 lload_3 36. 0x22 fload_0 37. 0x23 fload_1 38. 0x24 fload_2 39. 0x25 fload_3 40. 0x26 dload_0 41. 0x27 dload_1 42. 0x28 dload_2 43. 0x29 dload_3 44. 0x2a aload_0 45. 0x2b aload_1 46. 0x2c aload_2 47. 0x2d aload_3 48. 0x2e iaload 49. 0x2f laload 50. 0x30 faload 51. 0x31 daload 52. 0x32 aaload 53. 0x33 baload 54. 0x34 caload 55. 0x35 saload 56. 0x36 istore 57. 0x37 lstore 58. 0x38 fstore 59. 0x39 dstore 60. 0x3a astore 61. 0x3b istore_0 62. 0x3c istore_1 63. 0x3d istore_2 64. 0x3e istore_3 65. 0x3f lstore_0 66. 0x40 lstore_1 67. 0x41 lstore_2 68. 0x42 lstore_3 69. 0x43 fstore_0 70. 0x44 fstore_1 71. 0x45 fstore_2 72. 0x46 fstore_3 73. 0x47 dstore_0 74. 0x48 dstore_1 将第四个 int 型本地变量推送至栈顶 将第一个 long 型本地变量推送至栈顶 将第二个 long 型本地变量推送至栈顶 将第三个 long 型本地变量推送至栈顶 将第四个 long 型本地变量推送至栈顶 将第一个 float 型本地变量推送至栈顶 将第二个 float 型本地变量推送至栈顶 将第三个 float 型本地变量推送至栈顶 将第四个 float 型本地变量推送至栈顶 将第一个 double 型本地变量推送至栈顶 将第二个 double 型本地变量推送至栈顶 将第三个 double 型本地变量推送至栈顶 将第四个 double 型本地变量推送至栈顶 将第一个引用类型本地变量推送至栈顶 将第二个引用类型本地变量推送至栈顶 将第三个引用类型本地变量推送至栈顶 将第四个引用类型本地变量推送至栈顶 将 int 型数组指定索引的值推送至栈顶 将 long 型数组指定索引的值推送至栈顶 将 float 型数组指定索引的值推送至栈顶 将 double 型数组指定索引的值推送至栈顶 将引用型数组指定索引的值推送至栈顶 将 boolean 或 byte 型数组指定索引的值推送至栈顶 将 char 型数组指定索引的值推送至栈顶 将 short 型数组指定索引的值推送至栈顶 将栈顶 int 型数值存入指定本地变量 将栈顶 long 型数值存入指定本地变量 将栈顶 float 型数值存入指定本地变量 将栈顶 double 型数值存入指定本地变量 将栈顶引用型数值存入指定本地变量 将栈顶 int 型数值存入第一个本地变量 将栈顶 int 型数值存入第二个本地变量 将栈顶 int 型数值存入第三个本地变量 将栈顶 int 型数值存入第四个本地变量 将栈顶 long 型数值存入第一个本地变量 将栈顶 long 型数值存入第二个本地变量 将栈顶 long 型数值存入第三个本地变量 将栈顶 long 型数值存入第四个本地变量 将栈顶 float 型数值存入第一个本地变量 将栈顶 float 型数值存入第二个本地变量 将栈顶 float 型数值存入第三个本地变量 将栈顶 float 型数值存入第四个本地变量 将栈顶 double 型数值存入第一个本地变量 将栈顶 double 型数值存入第二个本地变量 75. 0x49 dstore_2 76. 0x4a dstore_3 77. 0x4b astore_0 78. 0x4c astore_1 79. 0x4d astore_2 80. 0x4e astore_3 81. 0x4f iastore 82. 0x50 lastore 83. 0x51 fastore 84. 0x52 dastore 85. 0x53 aastore 86. 0x54 bastore 87. 0x55 castore 88. 0x56 sastore 89. 0x57 pop 90. 0x58 pop2 91. 0x59 dup 92. 0x5a dup_x1 93. 0x5b dup_x2 94. 0x5c dup2 顶 95. 0x5d dup2_x1 96. 0x5e dup2_x2 97. 0x5f swap 98. 0x60 iadd 99. 0x61 ladd 100. 0x62 fadd 101. 0x63 dadd 102. 0x64 isub 103. 0x65 lsub 104. 0x66 fsub 105. 0x67 dsub 106. 0x68 imul 107. 0x69 lmul 108. 0x6a fmul 109. 0x6b dmul 110. 0x6c idiv 111. 0x6d ldiv 112. 0x6e fdiv 113. 0x6f ddiv 114. 0x70 irem 115. 0x71 lrem 116. 0x72 frem 117. 0x73 drem 将栈顶 double 型数值存入第三个本地变量 将栈顶 double 型数值存入第四个本地变量 将栈顶引用型数值存入第一个本地变量 将栈顶引用型数值存入第二个本地变量 将栈顶引用型数值存入第三个本地变量 将栈顶引用型数值存入第四个本地变量 将栈顶 int 型数值存入指定数组的指定索引位置 将栈顶 long 型数值存入指定数组的指定索引位置 将栈顶 float 型数值存入指定数组的指定索引位置 将栈顶 double 型数值存入指定数组的指定索引位置 将栈顶引用型数值存入指定数组的指定索引位置 将栈顶 boolean 或 byte 型数值存入指定数组的指定索引位置 将栈顶 char 型数值存入指定数组的指定索引位置 将栈顶 short 型数值存入指定数组的指定索引位置 将栈顶数值弹出 (数值不能是 long 或 double 类型的) 将栈顶的一个(long 或 double 类型的)或两个数值弹出(其它) 复制栈顶数值并将复制值压入栈顶 复制栈顶数值并将两个复制值压入栈顶 复制栈顶数值并将三个(或两个)复制值压入栈顶 复制栈顶一个(long 或 double 类型的)或两个(其它)数值并将复制值压入栈 <待补充> <待补充> 将栈最顶端的两个数值互换(数值不能是 long 或 double 类型的) 将栈顶两 int 型数值相加并将结果压入栈顶 将栈顶两 long 型数值相加并将结果压入栈顶 将栈顶两 float 型数值相加并将结果压入栈顶 将栈顶两 double 型数值相加并将结果压入栈顶 将栈顶两 int 型数值相减并将结果压入栈顶 将栈顶两 long 型数值相减并将结果压入栈顶 将栈顶两 float 型数值相减并将结果压入栈顶 将栈顶两 double 型数值相减并将结果压入栈顶 将栈顶两 int 型数值相乘并将结果压入栈顶 将栈顶两 long 型数值相乘并将结果压入栈顶 将栈顶两 float 型数值相乘并将结果压入栈顶 将栈顶两 double 型数值相乘并将结果压入栈顶 将栈顶两 int 型数值相除并将结果压入栈顶 将栈顶两 long 型数值相除并将结果压入栈顶 将栈顶两 float 型数值相除并将结果压入栈顶 将栈顶两 double 型数值相除并将结果压入栈顶 将栈顶两 int 型数值作取模运算并将结果压入栈顶 将栈顶两 long 型数值作取模运算并将结果压入栈顶 将栈顶两 float 型数值作取模运算并将结果压入栈顶 将栈顶两 double 型数值作取模运算并将结果压入栈顶 118. 0x74 ineg 119. 0x75 lneg 120. 0x76 fneg 121. 0x77 dneg 122. 0x78 ishl 123. 0x79 lshl 124. 0x7a ishr 125. 0x7b lshr 126. 0x7c iushr 127. 0x7d lushr 128. 0x7e iand 129. 0x7f land 130. 0x80 ior 131. 0x81 lor 132. 0x82 ixor 133. 0x83 lxor 134. 0x84 iinc 135. 0x85 i2l 136. 0x86 i2f 137. 0x87 i2d 138. 0x88 l2i 139. 0x89 l2f 140. 0x8a l2d 141. 0x8b f2i 142. 0x8c f2l 143. 0x8d f2d 144. 0x8e d2i 145. 0x8f d2l 146. 0x90 d2f 147. 0x91 i2b 148. 0x92 i2c 149. 0x93 i2s 150. 0x94 lcmp 151. 0x95 fcmpl 将栈顶 int 型数值取负并将结果压入栈顶 将栈顶 long 型数值取负并将结果压入栈顶 将栈顶 float 型数值取负并将结果压入栈顶 将栈顶 double 型数值取负并将结果压入栈顶 将 int 型数值左移位指定位数并将结果压入栈顶 将 long 型数值左移位指定位数并将结果压入栈顶 将 int 型数值右(符号)移位指定位数并将结果压入栈顶 将 long 型数值右(符号)移位指定位数并将结果压入栈顶 将 int 型数值右(无符号)移位指定位数并将结果压入栈顶 将 long 型数值右(无符号)移位指定位数并将结果压入栈顶 将栈顶两 int 型数值作“按位与”并将结果压入栈顶 将栈顶两 long 型数值作“按位与”并将结果压入栈顶 将栈顶两 int 型数值作“按位或”并将结果压入栈顶 将栈顶两 long 型数值作“按位或”并将结果压入栈顶 将栈顶两 int 型数值作“按位异或”并将结果压入栈顶 将栈顶两 long 型数值作“按位异或”并将结果压入栈顶 将指定 int 型变量增加指定值(i++, i--, i+=2) 将栈顶 int 型数值强制转换成 long 型数值并将结果压入栈顶 将栈顶 int 型数值强制转换成 float 型数值并将结果压入栈顶 将栈顶 int 型数值强制转换成 double 型数值并将结果压入栈顶 将栈顶 long 型数值强制转换成 int 型数值并将结果压入栈顶 将栈顶 long 型数值强制转换成 float 型数值并将结果压入栈顶 将栈顶 long 型数值强制转换成 double 型数值并将结果压入栈顶 将栈顶 float 型数值强制转换成 int 型数值并将结果压入栈顶 将栈顶 float 型数值强制转换成 long 型数值并将结果压入栈顶 将栈顶 float 型数值强制转换成 double 型数值并将结果压入栈顶 将栈顶 double 型数值强制转换成 int 型数值并将结果压入栈顶 将栈顶 double 型数值强制转换成 long 型数值并将结果压入栈顶 将栈顶 double 型数值强制转换成 float 型数值并将结果压入栈顶 将栈顶 int 型数值强制转换成 byte 型数值并将结果压入栈顶 将栈顶 int 型数值强制转换成 char 型数值并将结果压入栈顶 将栈顶 int 型数值强制转换成 short 型数值并将结果压入栈顶 比较栈顶两 long 型数值大小,并将结果(1,0,-1)压入栈顶 比较栈顶两 float 型数值大小,并将结果(1,0,-1)压入栈顶;当其中一 比较栈顶两 float 型数值大小,并将结果(1,0,-1)压入栈顶;当其中一 比较栈顶两 double 型数值大小,并将结果(1,0,-1)压入栈顶;当其中一 比较栈顶两 double 型数值大小,并将结果(1,0,-1)压入栈顶;当其中一 当栈顶 int 型数值等于 0 时跳转 当栈顶 int 型数值不等于 0 时跳转 当栈顶 int 型数值小于 0 时跳转 个数值为 NaN 时,将-1 压入栈顶 152. 0x96 fcmpg 个数值为 NaN 时,将 1 压入栈顶 153. 0x97 dcmpl 个数值为 NaN 时,将-1 压入栈顶 154. 0x98 dcmpg 个数值为 NaN 时,将 1 压入栈顶 155. 0x99 ifeq 156. 0x9a ifne 157. 0x9b iflt 158. 0x9c ifge 159. 0x9d ifgt 160. 0x9e ifle 当栈顶 int 型数值大于等于 0 时跳转 当栈顶 int 型数值大于 0 时跳转 当栈顶 int 型数值小于等于 0 时跳转 比较栈顶两 int 型数值大小,当结果等于 0 时跳转 比较栈顶两 int 型数值大小,当结果不等于 0 时跳转 比较栈顶两 int 型数值大小,当结果小于 0 时跳转 比较栈顶两 int 型数值大小,当结果大于等于 0 时跳转 比较栈顶两 int 型数值大小,当结果大于 0 时跳转 比较栈顶两 int 型数值大小,当结果小于等于 0 时跳转 比较栈顶两引用型数值,当结果相等时跳转 比较栈顶两引用型数值,当结果不相等时跳转 161. 0x9f if_icmpeq 162. 0xa0 if_icmpne 163. 0xa1 if_icmplt 164. 0xa2 if_icmpge 165. 0xa3 if_icmpgt 166. 0xa4 if_icmple 167. 0xa5 if_acmpeq 168. 0xa6 if_acmpne 169. 0xa7 goto 170. 0xa8 jsr 171. 0xa9 ret 无条件跳转 跳转至指定 16 位 offset 位置,并将 jsr 下一条指令地址压入栈顶 返回至本地变量指定的 index 的指令位置(一般与 jsr, jsr_w 联合使用) 用于 switch 条件跳转,case 值连续(可变长度指令) 用于 switch 条件跳转,case 值不连续(可变长度指令) 172. 0xaa tableswitch 173. 0xab lookupswitch 174. 0xac ireturn 175. 0xad lreturn 176. 0xae freturn 177. 0xaf dreturn 178. 0xb0 areturn 179. 0xb1 return 180. 0xb2 getstatic 181. 0xb3 putstatic 182. 0xb4 getfield 183. 0xb5 putfield 从当前方法返回 int 从当前方法返回 long 从当前方法返回 float 从当前方法返回 double 从当前方法返回对象引用 从当前方法返回 void 获取指定类的静态域,并将其值压入栈顶 为指定的类的静态域赋值 获取指定类的实例域,并将其值压入栈顶 为指定的类的实例域赋值 调用实例方法 调用超类构造方法,实例初始化方法,私有方法 调用静态方法 184. 0xb6 invokevirtual 185. 0xb7 invokespecial 186. 0xb8 invokestatic 187. 0xb9 invokeinterface 调用接口方法 188. 0xba -189. 0xbb new 190. 0xbc newarray 入栈顶 191. 0xbd anewarray 创建一个引用型(如类,接口,数组)的数组,并将其引用值压入栈顶 将栈顶的异常抛出 检验类型转换,检验未通过将抛出 ClassCastException 获得对象的锁,用于同步方法或同步块 释放对象的锁,用于同步方法或同步块 192. 0xbe arraylength 获得数组的长度值并压入栈顶 193. 0xbf athrow 194. 0xc0 checkcast 创建一个对象,并将其引用值压入栈顶 创建一个指定原始类型(如 int, float, char…)的数组,并将其引用值压 195. 0xc1 instanceof 检验对象是否是指定的类的实例, 如果是将 1 压入栈顶, 否则将 0 压入栈顶 196. 0xc2 monitorenter 197. 0xc3 monitorexit 198. 0xc4 wide <待补充> 199. 0xc5 multianewarray 创建指定类型和指定维度的多维数组(执行该指令时,操作栈中必须包 含各维度的长度值),并将其引用值压入栈顶 200. 0xc6 ifnull 201. 0xc7 ifnonnull 202. 0xc8 goto_w 203. 0xc9 jsr_w 为 null 时跳转 不为 null 时跳转 无条件跳转(宽索引) 跳转至指定 32 位 offset 位置,并将 jsr_w 下一条指令地址压入栈顶。

相关文档
最新文档