gpt4 book ai didi

java - 转换调用方法参数

转载 作者:太空宇宙 更新时间:2023-11-04 14:52:50 25 4
gpt4 key购买 nike

我试图确保动态加载的类通过我的类转换器运行,为此,我需要在将字节码加载到类中之前修改字节码

我想要做的是确定是否调用了defineClass,并在调用defineClass之前对字节数组参数调用我的字节码转换方法

但是我无法确定每个参数从哪里开始,它们的顺序很清晰,但我不知道如何知道哪个参数从哪里开始?

这是我用 ASMifier 创建的示例

//The first parameter
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1);
//second parameter, byte array, this is what I am looking for!!
mv.visitVarInsn(ALOAD, 4);
//third parameter
mv.visitInsn(ICONST_0);
//fourth parameter
mv.visitVarInsn(ALOAD, 4);
mv.visitInsn(ARRAYLENGTH);
//fifth parameter
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getProtectionDomain", "()Ljava/security/ProtectionDomain;");
mv.visitMethodInsn(INVOKEVIRTUAL, "b", "defineClass", "(Ljava/lang/String;[BIILjava/security/ProtectionDomain;)Ljava/lang/Class;");

如何确定哪些指令正在加载作为参数提供给 DefineClass 的字节数组,以便通过我的转换器运行它并使用返回值?

我看不到参数之间的清晰分离,也找不到任何与此相关的文档..

我不明白 JVM 如何知道参数何时开始和参数何时结束..

我可以轻松提取字节数组参数索引是什么,但是如何知道我可以找到加载字节数组的字节码?

最佳答案

有两种方法:

  1. 跟踪将某些值放入堆栈的指令(例如使用 ASM 字节码操作框架中的 SourceInterpreter)
  2. 在使用这些值时访问堆栈上的值(例如,在defineClass方法的INVOKEVIRTUAL之前)

第二种方法更容易实现,因为方法descriptor tells you每个方法参数使用什么堆栈槽。然后,您只需从堆栈中加载值,复制它们以供自己使用,然后将它们放回原来的位置。

ASM字节码框架提供LocalVariablesSorter帮助器,可以轻松地在字节码中引入新的局部变量。

关于java - 转换调用方法参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23558106/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com