首页 > 解决方案 > 如何使用字节码 ASM JAVA 中的方法包装变量

问题描述

我试图在遍历方法节点中的指令时使用 ASM 加密方法调用中的参数中的变量。

现在我已经尝试在方法调用的前一行(在实际的 java 代码中)使字符串被加密。

IE。如果该行是 Logger("This is a log",a)

我的算法所做的是,a = Project.Util.encode(a); 在记录器的前一行。示例代码如下。

if(abstractNode instanceof VarInsnNode) {
    VarInsnNode varnode = (VarInsnNode) abstractNode;
        insnList.add(new FieldInsnNode(GETSTATIC, "com/sample/Project", "Util", "Ljava/io/PrintStream;"));
        insnList.add(new VarInsnNode(ALOAD,varnode.var));
        insnList.add(new MethodInsnNode(INVOKEVIRTUAL, "java/io/PrintStream", "encode", "(Ljava/lang/String;)Ljava/lang/String;"));
       insnList.add(new VarInsnNode(ASTORE,varnode.var));
     }

我从方法调用描述中计算参数。每当我找到一个变量时,我都会通过改变它的值来进行编码并且在方法调用字节结构的末尾(通过向上遍历)我将这些指令粘贴到它们之前。

但我想像这样删除它的用法。相反,我想做这样的。

Logger("这是一个日志",encode(a));

考虑我将变量 a 作为抽象节点。我尝试在这个特定变量之前和之后添加指令。

 methodNode.instructions.insertBefore(abstractNode, new FieldInsnNode(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"));
 methodNode.instructions.insertBefore(abstractNode.getNext(),new MethodInsnNode(INVOKEVIRTUAL, "java/io/PrintStream", "encode", "(Ljava/lang/String;)Ljava/lang/String;"));

原来是失败,说堆栈中没有足够的空间。

请在这个观点上帮助我。

标签: javabytecodejava-bytecode-asmbytecode-manipulationjvm-bytecode

解决方案


推荐阅读