1

背景:我正在注入 Minecraft Launcher 以获取小程序(我已经完成了),但现在我希望通过我的类加载器加载 Minecraft 的文件。我找到了 GameUpdater.java(Minecraft 的游戏更新程序,也是客户端小程序的调度程序)的方法,并且在该方法下有一个名为“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 文档。

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

4

1 回答 1

1

解决了。诀窍是在添加新的(您的静态方法替换加载函数)之后删除 InvokerVirtual(从指令列表中删除 OPCODE)。

例子

instructionList.insert(instruction, classLoaderCall);
instructionList.delete(instruction);
于 2013-01-06T05:59:20.977 回答