背景:我正在注入Minecraft Launcher来获取applet(我已经完成了),但现在我希望通过我的类加载器加载minecraft的文件。我找到了GameUpdater.java(Minecraft的gameupdater,也是客户端applet的调度程序)的方法,下面有一个名为“createApplet”的方法。
GameUpdater.java:
public Applet createApplet() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Class localClass = classLoader.loadClass("net.minecraft.client.MinecraftApplet");
return (Applet)localClass.newInstance();
}
好的,非常简单,用自己的静态加载方法替换classLoader.loadClass。所以,我试过,在我的类加载器中,这是我的转换代码:
for(Method method : generator.getMethods()) {
if(method.getName().equals("createApplet")) {
ConstantPoolGen cpg = generator.getConstantPool();
MethodGen methodGen = new MethodGen(method, generator.getClassName(), cpg);
Instruction instruction = null;
InstructionList instructionList = methodGen.getInstructionList();
InstructionHandle[] instructionHandles = instructionList.getInstructionHandles();
for(int i = 0; i < instructionHandles.length; i++) {
//System.out.println(instructionHandles[i].getInstruction()); //debug
if(instructionHandles[i].getInstruction() instanceof LDC) {
instruction = instructionHandles[i].getInstruction();
InstructionFactory instructionFactory = new InstructionFactory(generator, cpg);
InvokeInstruction classLoaderCall =
instructionFactory.createInvoke(
"MinecraftLauncher", "loadClass", Type.CLASS, new Type[]{Type.STRING},Constants.INVOKESTATIC);
instructionList.insert(instruction, classLoaderCall);
methodGen.setInstructionList(instructionList);
instructionList.setPositions();
methodGen.setMaxStack();
methodGen.setMaxLocals();
methodGen.removeLineNumbers();
generator.replaceMethod(method, methodGen.getMethod());
generator.getJavaClass().dump("gameupdater.class");
}
}
}
然而,我摔倒在脸上。这是更新的gameupdater.class(如上所示,我将其转储)
public Applet createApplet() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Class localClass = MinecraftLauncher.loadClass(classLoader).loadClass("net.minecraft.client.MinecraftApplet");
return (Applet)localClass.newInstance();
}
下面是GameUpdater中createApplet方法的字节码图片
现在,我不知道如何做到这一点。如果有人能指出我正确的方向,那就太棒了!与此同时,我将继续尝试,并阅读bcel doc。
如果您对更多代码有任何疑问,请告诉我。
答案 0 :(得分:1)
解决。诀窍是在添加新的(删除加载功能的静态方法)后删除InvokerVirtual(从指令列表中删除OPCODE)。
示例
instructionList.insert(instruction, classLoaderCall);
instructionList.delete(instruction);