/*
 * Copyright 2017-2018 Baidu Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.fuxi.javaagent.hook.file;

import com.fuxi.javaagent.HookHandler;
import com.fuxi.javaagent.hook.AbstractClassHook;
import com.fuxi.javaagent.plugin.checker.CheckParameter;
import com.fuxi.javaagent.plugin.js.engine.JSContext;
import com.fuxi.javaagent.plugin.js.engine.JSContextFactory;
import org.mozilla.javascript.Scriptable;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.AdviceAdapter;
import org.objectweb.asm.commons.Method;

import java.io.File;
import java.io.IOException;

/**
 * Created by zhuming01 on 5/16/17.
 * All rights reserved
 */
public class FileHook extends AbstractClassHook {
    /**
     * (none-javadoc)
     *
     * @see com.fuxi.javaagent.hook.AbstractClassHook#getType()
     */
    @Override
    public String getType() {
        return "directory";
    }

    /**
     * (none-javadoc)
     *
     * @see com.fuxi.javaagent.hook.AbstractClassHook#isClassMatched(String)
     */
    @Override
    public boolean isClassMatched(String className) {
        return "java/io/File".equals(className);
    }

    /**
     * (none-javadoc)
     *
     * @see com.fuxi.javaagent.hook.AbstractClassHook#hookMethod(int, String, String, String, String[], MethodVisitor)
     */
    @Override
    public MethodVisitor hookMethod(int access, String name, String desc, String signature, String[] exceptions, MethodVisitor mv) {
        if (name.equals("listFiles")) {
            return new AdviceAdapter(Opcodes.ASM5, mv, access, name, desc) {
                @Override
                protected void onMethodEnter() {
                    loadThis();
                    invokeStatic(Type.getType(FileHook.class),
                            new Method("checkListFiles", "(Ljava/io/File;)V"));
                }
            };
        }
        return mv;
    }

    /**
     * 列出文件列表方法hook点
     *
     * @param file 文件对象
     */
    public static void checkListFiles(File file) {
        if (file != null) {
            JSContext cx = JSContextFactory.enterAndInitContext();
            Scriptable params = cx.newObject(cx.getScope());
            params.put("path", params, file.getPath());
            try {
                params.put("realpath", params, file.getCanonicalPath());
            } catch (IOException e) {
                params.put("realpath", params, file.getAbsolutePath());
            }

            HookHandler.doCheck(CheckParameter.Type.DIRECTORY, params);
        }
    }

}

@@ -667,24 +667,65 @@
 ookHandler;%0A
+import com.fuxi.javaagent.config.Config;%0A
 import com.f
@@ -934,16 +934,59 @@
 actory;%0A
+import com.fuxi.javaagent.tool.StackTrace;%0A
 import o
@@ -1262,16 +1262,39 @@
 ception;
+%0Aimport java.util.List;
 %0A%0A/**%0A *
@@ -2728,24 +2728,84 @@
  != null) %7B%0A
+            Scriptable params = null;%0A            try %7B%0A    
             
@@ -2867,34 +2867,27 @@
             
-Scriptable
+   
  params = cx
@@ -2909,24 +2909,28 @@
 etScope());%0A
+    
             
@@ -2965,32 +2965,355 @@
 ile.getPath());%0A
+                List%3CString%3E stackInfo = StackTrace.getStackTraceArray(Config.REFLECTION_STACK_START_INDEX,%0A                        Config.getConfig().getPluginMaxStack());%0A                Scriptable stackArray = cx.newArray(cx.getScope(), stackInfo.toArray());%0A                params.put(%22stack%22, params, stackArray);%0A    
             try 
@@ -3306,32 +3306,36 @@
           try %7B%0A
+    
                 
@@ -3403,16 +3403,20 @@
         
+    
 %7D catch 
@@ -3429,24 +3429,28 @@
 eption e) %7B%0A
+    
             
@@ -3517,27 +3517,175 @@
             
+ 
-%7D%0A%0A
+   %7D%0A            %7D catch (Throwable t) %7B%0A                HookHandler.LOGGER.warn(t.getMessage());%0A            %7D%0A            if (params != null) %7B%0A    
             
@@ -3744,16 +3744,30 @@
 arams);%0A
+            %7D%0A
         

add stack param for java directory check