字节码编程ASM之生成变量并sout

news2024/12/22 9:20:19

写在前面

本文看下如何通过asm生成变量并sout。

1:代码

直接看代码吧,注释很详细,有不懂的,留言告诉我:

package com.dahuyuo.asmtest;

import org.objectweb.asm.*;
import org.objectweb.asm.commons.AdviceAdapter;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;

import static org.objectweb.asm.Opcodes.ASM5;

public class YY extends ClassLoader {

    public static void main(String[] args) throws Exception {
        ClassReader cr = new ClassReader("com.dahuyuo.asmtest.XX");
        ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS);
        cr.accept(new ClassVisitor(ASM5, cw) {
            public MethodVisitor visitMethod(int access, String name, String
                    descriptor, String signature, String[] exceptions) {
                // 方法过滤
                if (!"didi".equals(name)) {
                    return super.visitMethod(access, name, descriptor,
                            signature, exceptions);
                }
                MethodVisitor mv = super.visitMethod(access, name, descriptor,
                        signature, exceptions);
                return new AdviceAdapter(ASM5, mv, access, name, descriptor) {
                    protected void onMethodEnter() {
//                        super.onMethodEnter();
                        // 这里不管定义啥类型都可以用Type.LONG_TYPE,没搞懂是干啥的
                        int intVar1 = newLocal(Type.INT_TYPE); // 创建一个int类型的局部变量 相当于int var;
                        mv.visitLdcInsn(99); // 将常量99加载到操作数栈的栈顶
                        mv.visitVarInsn(ISTORE, intVar1); // 将栈顶值赋值给本地变量 int var = 99;
                        mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); // 将静态变量System.out压倒栈顶
                        mv.visitVarInsn(ILOAD, intVar1); // 将整数变量压到栈顶
                        mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(I)V", false); // 出栈System.out,整数变量,并调用sout(int)完成输出
//

//                        int intVar2 = newLocal(Type.INT_TYPE);
//                        mv.visitTypeInsn(NEW, "java/lang/String"); // new String()然后推到栈顶
//                        mv.visitInsn(DUP); // 复制栈顶元素
                        int nextLocal = this.nextLocal; // 获取当前可用的局部变量表位置??
                        mv.visitLdcInsn("pppp"); // 加载常量到栈顶
                        mv.visitVarInsn(ASTORE, nextLocal); // 将栈顶string对象复制给局部变量
//                        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/String", "<init>", "(Ljava/lang/String;)V", false); // 调用构造函数完成string对象创建
//                        mv.visitVarInsn(ASTORE, this.nextLocal);


                        mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); // 将静态变量System.out压倒栈顶
                        mv.visitVarInsn(ALOAD, nextLocal); // 将string变量压到栈顶
                        mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); // 出栈System.out,整数变量,并调用sout(string)完成输出
                    }

                    public void visitMaxs(int maxStack, int maxLocals) {
                        super.visitMaxs(maxStack, maxLocals);
                    }

                    protected void onMethodExit(int opcode) {
                        super.onMethodExit(opcode);
                    }
                };
            }
        }, ClassReader.EXPAND_FRAMES);
        // 获取后的字节码
        byte[] byteAfterInstrument = cw.toByteArray();


        outputClazz(byteAfterInstrument, "xxvv");

        // 测试方法
        Class<?> clazz = new
                YY().defineClass("com.dahuyuo.asmtest.XX", byteAfterInstrument, 0, byteAfterInstrument.length);
        Method didi = clazz.getMethod("didi");
        didi.invoke(clazz.newInstance());


    }

    private static void outputClazz(byte[] bytes, String className) {
        // 输出类字节码
        FileOutputStream out = null;
        try {
            String pathName = YY.class.getResource("/").getPath() + className + "_after_instrument.class";
            out = new FileOutputStream(new File(pathName));
            System.out.println("插桩后代码输出路径:" + pathName);
            out.write(bytes);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != out) try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

用来进行插桩的XX类如下:

public class XX {
  /*  public static void main(String[] args) {
        int a = 10;
        int b = 20;
        System.out.println(a + b);
    }*/

    public void didi() {

    }
}

运行测试:
在这里插入图片描述
查看生成的字节码:
在这里插入图片描述
就是我们要的效果。

写在后面

参考文章列表

JVM 虚拟机字节码指令表 。

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

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

相关文章

PE文件学习

一、介绍 PE文件&#xff0c;即Portable Executable文件&#xff0c;是一种标准的文件格式&#xff0c;主要用于微软的Windows操作系统上。这种格式被用来创建可执行程序&#xff08;如.exe文件&#xff09;、动态链接库&#xff08;.DLL文件&#xff09;、设备驱动&#xff0…

千万不要用国产BI,不然你会发现它性价比奇高——以奥威BI软件为例

在信息技术日新月异的今天&#xff0c;企业对于商业智能&#xff08;BI&#xff09;软件的选择往往陷入了一个误区&#xff1a;盲目追求国际品牌&#xff0c;却忽视了身边那些性价比极高的国产精品。如果你不慎踏入了“千万不要用国产BI”的陷阱&#xff0c;那么奥威BI软件将是…

豆包Marscode体验官,体验云编程和AI助手加持的快乐

我正在参加「豆包MarsCode初体验」征文活动&#xff0c;活动链接&#xff1a;https://juejin.cn/post/7384997062416252939?utm_sourcejuejin&utm_mediumpush&utm_campaigntiyanguan Marscode官网地址&#xff1a;工作台 - MarsCode 其实早在前不久&#xff0c;我就…

谷歌地图 | 路线优化 API 助力企业解锁物流新潜能

在当今竞争激烈的市场环境中&#xff0c;企业面临着越来越大的压力&#xff0c;需要提高运营效率、降低成本并满足不断增长的客户期望。对于依赖车队进行交付或服务的企业来说&#xff0c;这些挑战尤为艰巨。 近日&#xff0c; Google 地图平台路线优化 API 已经正式上线。路线…

服务器工具集合推荐

推荐一个朋友开源的服务器运维整合工具,目前的功能包括: ddns&#xff0c;rdp、ssh终端、ftp、http代理&#xff0c;支持在线文件编辑&#xff0c;文件管理&#xff0c;docker&#xff0c;进程&#xff0c;系统监控、wol唤醒&#xff0c;电脑远程开机&#xff0c;点对点&#…

【STM32】在标准库中使用DMA

1.MDA简介 DMA全称Direct Memory Access,直接存储区访问。 DMA传输将数据从一个地址空间复制到另一个地址空间。当CPU初始化这个传输动作&#xff0c;传输动作本身是由DMA控制器来实现和完成的。DMA传输方式无需CPU直接控制传输&#xff0c;也没有中断处理方式那样保留现场和…

科普文:Linux服务器性能调优之CPU调度策略和可调参数

概叙 进程 进程是操作系统虚拟出来的概念&#xff0c;用来组织计算机中的任务。计算机的核心是CPU&#xff0c;它承担了所有的计算任务&#xff1b;而操作系统是计算机的管理者&#xff0c;它负责任务的调度、资源的分配和管理&#xff0c;统领整个计算机硬件&#xff1b;应用…

Raylib 解决拖拽与绘制坐标,在GPU坐标与鼠标坐标不相同的解决办法

注意数字可以通过加减排列组合得出 原理&#xff0c;诞生于发现可以拖拽&#xff0c;数据加减&#xff0c;与左下角排列&#xff0c;发现坐标系可以按左下角为原点理解 int positionx 0 - draftx;int positiony 0 drafty; // 相对于左下角位置&#xff0c;水平方向就是当…

TensorRT-Int8量化详解

int8量化是利用int8乘法替换float32乘法实现性能加速的一种方法 对于常规模型有&#xff1a;y kx b&#xff0c;此时x、k、b都是float32, 对于kx的计算使用float32的乘法 对于int8模型有&#xff1a;y tofp32(toint8(k) * toint8(x)) b&#xff0c;其中int8 * int8结果为in…

软件安全测试之代码审计包括哪些内容?代码审计报告该如何获取?

在信息化时代&#xff0c;随着计算机技术的快速发展&#xff0c;软件产品已经成为了人们生活和工作中不可或缺的一部分。然而&#xff0c;随着软件产品的复杂性和应用范围的扩大&#xff0c;软件安全性问题日益凸显&#xff0c;给企业和个人带来了极大的风险。为了保障软件系统…

JAVA每日作业day7.4

ok了家人们今天学习了Date类和simpleDateformat类&#xff0c;话不多说我们一起看看吧 一.Date类 类 java.util.Date 表示特定的瞬间 ( 日期和时间 ) &#xff0c;精确到毫秒。 1.2 Date类的构造方法 public Date(): 用来创建当前系统时间对应的日期对象。 public Date(long …

BBA车主,千万别去试驾问界M9

文 | AUTO芯球 作者 | 雷慢&响铃 我劝你啊&#xff0c;千万别去试驾问界M9&#xff0c; 不然啊&#xff0c;可能1个小时50万就没了&#xff0c; 不信你看这个“大冤种”&#xff0c; 他曾经发誓打死不买电车&#xff0c; 考虑了三、四年换宝马X5&#xff0c; 结果谈完…

@react-google-maps/api实现谷歌地图嵌入React项目中,并且做到点击地图任意一处,获得它的经纬度

1.第一步要加入项目package.json中或者直接yarn install它都可以 "react-google-maps/api": "^2.19.3",2.加入项目中 import AMapLoader from amap/amap-jsapi-loader;import React, { PureComponent } from react; import { GoogleMap, LoadScript, Mar…

工业智能网关的作用有哪些?工业智能网关与传统网关的主要区别-天拓四方

工业智能网关是一种专为工业环境设计的网络设备&#xff0c;具备数据采集、传输、协议转换以及边缘计算等功能。它作为连接工业设备与互联网的关键枢纽&#xff0c;不仅实现了工业设备的互联互通&#xff0c;还通过对采集到的数据进行实时分析&#xff0c;为工业生产的智能化管…

AI墓地:738个倒闭AI项目的启示

近年来&#xff0c;人工智能技术迅猛发展&#xff0c;然而&#xff0c;不少AI项目却在市场上悄然消失。根据AI工具聚合网站“DANG”的统计&#xff0c;截至2024年6月&#xff0c;共有738个AI项目停运或停止维护。本文将探讨这些AI项目失败的原因&#xff0c;并分析当前AI初创企…

甲骨文首次将LLMs引入数据库,集成Llama 3和Mistral,和数据库高效对话

信息时代&#xff0c;数据为王。数据库作为数据存储&管理的一种方式&#xff0c;正在以势不可挡的趋势与AI结合。 前有OpenAI 收购了数据库初创公司 Rockset&#xff0c;引发广泛关注&#xff1b;Oracle公司&#xff08;甲骨文&#xff09;作为全球最大的信息管理软件及服…

维护合作伙伴关系与直接销售:SaaS渠道商如何解决2024运营难题?

随着科技的飞速发展和市场竞争的日益激烈&#xff0c;SaaS&#xff08;Software as a Service&#xff09;行业正步入一个充满挑战与机遇并存的新时代。对于SaaS渠道商而言&#xff0c;2024年无疑是一个考验其战略眼光与运营能力的关键年份。面对市场环境的快速变化、客户需求的…

猫咖老板教你一招解决猫浮毛问题,质量好的猫用空气净化器分享

作为一名猫咖店老板&#xff0c;我经常被朋友问到关于宠物空气净化器的各种问题。有人认为这是个神器&#xff0c;而有人则认为这完全是花钱买智商税。其实我刚开始对购买宠物空气净化器也持怀疑态度&#xff0c;心想这么多钱花下去真的有效吗&#xff1f;但使用后&#xff0c;…

从华为和特斯拉之争,看智能驾驶的未来

“一旦特斯拉完全解决自动驾驶问题并量产Optimus&#xff0c;任何空头都将被消灭&#xff0c;即使是比尔-盖茨也不例外。”7月2日&#xff0c;马斯克再次在社交媒体X上画下了这样的“大饼”。 与此同时&#xff0c;特斯拉的股价在最近的三个交易日也迎来了24%的涨幅&#xff0c…