chu*_*acw 5 java delphi java-native-interface
由于在上述方法中调用了Reflection.getCallerClass,因此在调用getDeclaredMethods/getDeclaredFields/getConstructors时会收到AV.
我通过JNI从Delphi应用程序创建了一个Java VM.不幸的是,我发现在调用java.lang.Class类中的某些方法时,这些方法会调用
checkMemberAccess(1, Reflection.getCallerClass(), true);
Run Code Online (Sandbox Code Playgroud)
这导致了AV,因为堆栈上没有真正的Java类,因为我直接调用了getDeclaredXXX方法,并且来自Delphi的JNI调用.
为了克服getCallerClass,我创建了一个Java类包装器,如下所示:
public class DelphiClassHelper {
private Field[] f;
private Method[] m;
private Constructor<?>[] c;
private static DelphiClassHelper helper;
public Field[] pGetDeclaredFields(ClassLoader cl, String ClassName) {
Class<?> AClass = null;
try {
System.out.println("Loading class: "+ClassName);
System.out.println("ClassLoader: "+cl.toString());
AClass = cl.loadClass(ClassName);
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
if (AClass!=null) {
f = AClass.getDeclaredFields();
return f;
} else
return new Field[]{};
}
public static Field[] GetDeclaredFields(ClassLoader cl, String ClassName) {
helper = new DelphiClassHelper();
return helper.pGetDeclaredFields(cl, ClassName);
}
public Method[] pGetDeclaredMethods(ClassLoader cl, String ClassName) {
Class<?> AClass = null;
try {
System.out.println("Loading class: "+ClassName);
System.out.println("ClassLoader: "+cl.toString());
AClass = cl.loadClass(ClassName);
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
if (AClass!=null) {
m = AClass.getDeclaredMethods();
return m;
} else
return new Method[]{};
}
public static Method[] GetDeclaredMethods(ClassLoader cl, String ClassName) {
helper = new DelphiClassHelper();
return helper.pGetDeclaredMethods(cl, ClassName);
}
public Constructor<?>[] pGetConstructors(ClassLoader cl, String ClassName) {
Class<?> AClass = null;
try {
System.out.println("Loading class: "+ClassName);
System.out.println("ClassLoader: "+cl.toString());
AClass = cl.loadClass(ClassName);
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
if (AClass!=null) {
c = AClass.getConstructors();
return c;
} else
return new Constructor[]{};
}
public static Constructor<?>[] GetConstructors(ClassLoader cl, String ClassName) {
helper = new DelphiClassHelper();
return helper.pGetConstructors(cl, ClassName);
}
}
Run Code Online (Sandbox Code Playgroud)
我创建上述内容的想法是公共静态方法创建一个Java类,然后调用实例方法pXXXX,然后调用其中一个方法Class.getDeclaredMethods,getDeclaredFields,getConstructors,这肯定会满足getCallerClass调用,因此,防止AV.
但不,我仍然得到AV.是否有任何其他框架可以提供getDeclaredXXXX方法提供的信息,或者是否有办法解决getCallerClass要求,例如在堆栈上创建一个可以满足Reflection.getCallerClass调用的假类?
我的Delphi到JNI应用程序的其他部分工作,只要它不调用任何最终调用Reflection.getCallerClass的Java方法.
请注意,当我从JNI调用创建Java VM时,没有安装任何SecurityManager.
更新:2014年1月24日AV的原因是由于某些优化,这导致对象的实例被放置在其中一个CPU寄存器中,在调用checkMemberAccess时会被擦除.随后当Delphi运行时尝试从CPU寄存器中检索对象并再次使用它时,它会导致AV,因为预期值已被删除.
小智 0
你的方法看起来是正确的。问题是您在方法中传递有关 ClassLoader c1 参数的内容是什么?这需要使用来自与您尝试内省的类相同的虚拟机的类来生成。任何班级都可以。如果您有这样的类,您可以在其构造函数中使用该类来获取正确的 ClassLoader 。