使用字节码检测读取Java Socket连接值

时间:2016-12-19 15:39:52

标签: java bytecode instrumentation java-bytecode-asm

我正在尝试使用ASM在解释器中读取java.net.Socket连接方法参数。我不知道如何使用字节码检测读取方法参数的值。请帮我解决一下这个。

public class SocketClassVisitor extends ClassVisitor {

    public SocketClassVisitor(ClassVisitor cv) {
        super(Opcodes.ASM5, cv);
    }

    @Override
    public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
        MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);

        return new SocketConnectSiteVisitor(mv, name, desc);
    }

    public static void sleep() {
        System.out.println("SLEEP IS CALLED!!!!!!!!!");
    }

    public static void onSocketConnect(SocketAddress endpoint, int timeout) {
        System.out.println("onSocketConnect IS CALLED!!!!!!!!!");
    }

    /**
     *   * bootstrap method for invokeDynamic support   
     */
    public static CallSite bootstrap(MethodHandles.Lookup caller, String name, MethodType type)
    throws NoSuchMethodException, IllegalAccessException {
        MethodHandles.Lookup lookup = MethodHandles.lookup();
        Class thisClass = lookup.lookupClass();
        MethodHandle methodHandle = lookup.findStatic(thisClass, name, type);
        return new ConstantCallSite(methodHandle.asType(type));
    }

    private class SocketConnectSiteVisitor extends MethodVisitor {
        private String methodName;
        private String desc;

        public SocketConnectSiteVisitor(MethodVisitor mv, String methodName, String desc) {
            super(Opcodes.ASM5, mv);
            this.methodName = methodName;
            this.desc = desc;
        }

        @Override
        public void visitCode() {
            if ("connect".equals(methodName) && "(Ljava/net/SocketAddress;I)V".equals(desc)) {

                mv.visitVarInsn(Opcodes.ILOAD, 2);
                mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);

                mv.visitInsn(Opcodes.AASTORE);

                mv.visitVarInsn(Opcodes.ALOAD, 1);
                mv.visitInsn(Opcodes.AASTORE);

                this.visitLdcInsn("java/net/Socket");
                this.visitLdcInsn(this.methodName);

                mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getType(SocketClassVisitor.class).getInternalName(),
                    "onSocketConnect", "(Ljava/net/SocketAddress;I)V", false);
                System.out.println("VisitCode visitMethodInsn with args");

                super.visitCode();
            }
        }
    }
}

当我尝试从测试程序调用Socket.connect时,JVM会因错误而崩溃 有问题的框架: j java.net.Socket.connect(Ljava / net / SocketAddress; I)V + 1

0 个答案:

没有答案