Java BCEL注入/更换出错了

时间:2013-01-06 03:25:39

标签: java minecraft bcel

背景:我正在注入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方法的字节码图片 bytecode info

现在,我不知道如何做到这一点。如果有人能指出我正确的方向,那就太棒了!与此同时,我将继续尝试,并阅读bcel doc。

如果您对更多代码有任何疑问,请告诉我。

1 个答案:

答案 0 :(得分:1)

解决。诀窍是在添加新的(删除加载功能的静态方法)后删除InvokerVirtual(从指令列表中删除OPCODE)。

示例

instructionList.insert(instruction, classLoaderCall);
instructionList.delete(instruction);