思路来源:https://blog.csdn.net/u011335423/article/details/80592715
上面的博主提到只需要修改Class.forName为1个参数就行,我是费了半天劲,
思路1.有luaj的源码包,但是不知道咋编译成jar【失败】
思路2.网上有说把某jar文件提取需要的class文件并解密为java,然后修改完后编译成class,再压缩回去,但是我发现压缩回去后,连反编译jar的软件都是别不出来.java文件了。【失败】
思路3.困得很,睡一觉。【成功】
我睡了1个小时,后来突然脑袋灵光了,看看是怎么我能不能写个类之类的把他给替换掉?说干就干,追了第一步,就发现了奥秘,在调用JsePlatform.standardGlobals()
的时候standardGlobals
这个方法里面有如下代码
Globals globals = new Globals();
globals.load(new JseBaseLib());
globals.load(new PackageLib());
globals.load(new Bit32Lib());
globals.load(new TableLib());
globals.load(new StringLib());
globals.load(new CoroutineLib());
globals.load(new JseMathLib());
globals.load(new JseIoLib());
globals.load(new JseOsLib());
globals.load(new LuajavaLib());
LoadState.install(globals);
LuaC.install(globals);
return globals;
发现了在这里调用了LuajavaLib
类来初始化luajava这个东西,所以,我们大胆的猜想一下,要不我们也仿照写一个,在摸索的过程中,发现JavaClass.forClass
不允许外部访问,百度了一下,需要同一级的或者子类可以访问,所以我新建了一个java文件,内容如下
package org.luaj.vm2.lib.jse;//这个地方千万别漏掉~
public class JavaClassImpl extends JavaClass {
public JavaClassImpl(Class c) {
super(c);
}
}
下面是我注入lua的代码,globals是通过JsePlatform.standardGlobals()获得的对象
globals.load(new TwoArgFunction(){
public LuaValue call(LuaValue modname, 、LuaValue env){
LuaTable t = new LuaTable();
Class f = this.getClass();
t.set("bindClass",new mtn(1,"bindClass")); //此处的1表示下面的opcode
//下面这两个自己翻LuajavaLib.java文件照搬,主要是修改为了调用我们自己的classForName。
// t.set("newInstance",new mtn(2,"newInstance"));
// t.set("new",new mtn(3,"new"));
env.set("luajavax",t);
env.get("package").get("loaded").set("luajavax", t);
return t;
}
class mtn extends VarArgFunction{
public mtn(int opcode, String name) {
this.opcode = opcode;
this.name = name;
}
public Varargs invoke(Varargs args) {
try {
switch ( opcode ) {
case 1:{
final Class clazz = classForName(args.checkjstring(1));
return new JavaClassImpl(clazz);
}
}
}catch(Exception e){}
}
protected Class classForName(String name) throws ClassNotFoundException {
return Class.forName(name);//就是这个地方,绕了一大圈!
}
}