我正在尝试使用此枚举并添加新材料。 任何尚未删除的东西在其他地方都有硬依赖,即使如此,根据mods作者的说法,这几乎是在java字节限制,所以无论如何都没有太多的工作空间。
GregoriousT提到“有一种方法。主宰使用Reflection来加入他自己的东西攻击Enum。不知道他是怎么做到的,也不知道如果你问他他会花多长时间来回复你。”我们谈论的是: http://pastebin.com/g0aJ2Qjd
所以我只是问,我该怎么做呢?
这是我目前的尝试抛出[FML]: Variable m:1|newInstance|public java.lang.Object sun.reflect.DelegatingConstructorAccessorImpl.newInstance(java.lang.Object[]) throws java.lang.InstantiationException,java.lang.IllegalArgumentException,java.lang.reflect.InvocationTargetException|false
在客户端崩溃之前。 (删除日志代码以便于阅读)
目前的尝试:
public class MaterialsNew {
public static void getGregMaterials() throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, SecurityException{
Utils.LOG_WARNING("Stepping through the process of Greg's materials.");
Constructor<?> con = Materials.class.getDeclaredConstructors()[0];
java.lang.reflect.Method[] methods = con.getClass().getDeclaredMethods();
for (java.lang.reflect.Method m1 : methods) {
if (m1.getName().equals("acquireConstructorAccessor")) {
m1.setAccessible(true);
m1.invoke(con, new Object[0]);}
}
Field[] fields = con.getClass().getDeclaredFields();
Object ca = null;
for (Field f : fields) {
if (f.getName().equals("constructorAccessor")) {
f.setAccessible(true);
ca = f.get(con);
}
}
Method m = ca.getClass().getMethod( "newInstance", new Class[] { Object[].class });
m.setAccessible(true);
Materials v = (Materials) m.invoke(ca, new Object[] { new Object[] { "NEWMATERIAL", Integer.MAX_VALUE } });
System.out.println(v.getClass() + ":" + v.name() + ":" + v.ordinal());}}
任何帮助或建议都表示赞赏,他们在Forge IRC的工作人员也不确定。
答案 0 :(得分:1)
JVM应该防止这种偷偷摸摸的enum
实例创建。所以你必须使用一个很快就会被解决的漏洞,或者在JRE中进行深入攻击,以至于最轻微的改变可能会破坏它。
这是一个适用于Oracle当前JRE 8的技巧,也许是JRE 7,并且非常简单:
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Constructor;
import java.util.EnumSet;
public class EnumHack {
public static void main(String[] args) throws Throwable {
Constructor<Thread.State> c
= Thread.State.class.getDeclaredConstructor(String.class, int.class);
c.setAccessible(true);
MethodHandle h=MethodHandles.lookup().unreflectConstructor(c);
Thread.State state=(Thread.State)h.invokeExact("FLYING", 42);
System.out.println("created Thread.State "+state+"("+state.ordinal()+')');
System.out.println(EnumSet.allOf(Thread.State.class).contains(state));
}
}
但是不要指望这个解决方案能够坚持......