美文网首页
jvm-sandbox反向学习

jvm-sandbox反向学习

作者: huiwq1990 | 来源:发表于2018-02-02 20:16 被阅读0次

    前言

    学习某系统时,大哥跟我说正向流程和反向流程都需要了解(当然这里是因为正向太难了,涉及到使用asm操作字节码,正向我做不到啊!)。阿里最近开源的jvm-sandbox让我再一次跪拜。

    基本原理

    sandbox的基本原理是利用Java的Instrument做jvm级别的AOP。Sandbox将代码执行过程分为如下几种:


    image.png

    AOP的作用是在这些点植入控制代码,当程序运行到植入点时(即事件发生),通过调用事件监听器EventListenerHandlers,调用用户自定义行为。

    Event控制

    为了方便控制切入的代码,sandbox提供active、frozen等功能,可以方便打开和关闭对于功能。简单点说就是:
    1、用户自定义事件会分配一个唯一id,即listenerid。
    2、当自定义的Module激活时,把它放入全局的globalEventListenerMap中;冻结是就移除。
    3、AOP植入的代码里会把listenerid也植入进入,在Event的处理流程中,如果没有找到对应的Listener,响应功能就不会执行。

    模块加载

    sandbox的命令行会转为http请求,使用内置的jetty实现命令处理。如查看sandbox的信息接口

    curl localhost:34023/sandbox/module/http/info/version
    

    模块处理主要是在ModuleHttpServlet实现。

    DUMP

    由于sandbox的Spy类的package是java开头的,所以需要改一下。SpyUtils2把Spy类改为不是java开头。

    package de;
    
    import com.alibaba.jvm.sandbox.api.ProcessControlException;
    import com.alibaba.jvm.sandbox.api.event.Event;
    import com.alibaba.jvm.sandbox.api.listener.EventListener;
    import com.alibaba.jvm.sandbox.core.CoreConfigure;
    import com.alibaba.jvm.sandbox.core.enhance.weaver.EventListenerHandlers;
    import com.alibaba.jvm.sandbox.core.util.SpyUtils2;
    import com.alibaba.jvm.sandbox.spy.Spy;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public abstract class Clock {
        private final SimpleDateFormat clockDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    
        final String formatDate(Date date) {
            return this.clockDateFormat.format(date);
        }
    
        final Date nowDate() {
            return new Date();
        }
    
        final String report() {
            this.checkState();
            return this.formatDate(this.nowDate());
        }
    
        abstract void checkState();
    
        abstract void delay() throws InterruptedException;
    
        final void loopReport() throws InterruptedException {
            do {
                try {
                    System.out.println(this.report());
                }
                catch (Throwable throwable) {
                    throwable.printStackTrace();
                }
                this.delay();
            } while (true);
        }
    
        public static void main(String[] arrstring) throws Throwable {
    
            // 初始化coremodule
            CoreConfigure.toConfigure("","");
    
            // 时间类型
            Event.Type[] eventTypeArray = new Event.Type[1];
            eventTypeArray[0] =  Event.Type.THROWS;
    
            // 激活listen,listenerid = 1
            EventListenerHandlers.getSingleton()
                    .active(1,  new EventListener() {
                                @Override
                                public void onEvent(Event event) throws Throwable {
                                    // 立即返回
                                    ProcessControlException.throwReturnImmediately(null);
                                }
                            },
                            // 指定监听的事件为抛出异常
                          eventTypeArray );
    
            // 初始化spy类
            SpyUtils2.init();
    
            // 调用clock
            new BrokenClock().loopReport();
        }
    
        static class BrokenClock extends Clock {
            @Override
            void checkState() {
                try {
                    Spy.Ret ret = Spy.spyMethodOnBefore((Object[])new Object[0], (int)1, (int)4, (String)"Clock$BrokenClock", (String)"checkState", (String)"()V", (Object)this);
                    int n = ret.state;
                    if (n == 1) return;
                    if (n != 2) {
                        throw new IllegalStateException();
                    }
                    throw (Throwable)ret.respond;
                }
                catch (Throwable throwable) {
                    try {
                        Spy.Ret ret = Spy.spyMethodOnThrows((Throwable) throwable, (int) 1);
                        int n = ret.state;
                        if (n == 1) return;
                        if (n == 2) throw (Throwable) ret.respond;
    //                throw throwable;
                    }catch (Throwable tt){
                        tt.printStackTrace();
                    }
                }
            }
    
            @Override
            void delay() throws InterruptedException {
                Thread.sleep(10000L);
            }
    
            BrokenClock() {
            }
        }
    
    }
    

    相关文章

      网友评论

          本文标题:jvm-sandbox反向学习

          本文链接:https://www.haomeiwen.com/subject/dcnezxtx.html