首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java BCEL注入/替换出错

Java BCEL注入/替换出错
EN

Stack Overflow用户
提问于 2013-01-06 11:25:39
回答 1查看 614关注 0票数 1

背景:我正在注入“我的世界”启动器来获取applet (我已经做到了),但现在我希望通过我的类加载器加载“我的世界”的文件。我找到了GameUpdater.java (我的游戏更新程序,也是客户端applet的分派器)的方法,在这个方法下有一个叫做"createApplet“的方法。

GameUpdater.java:

代码语言:javascript
复制
public Applet createApplet() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Class localClass = classLoader.loadClass("net.minecraft.client.MinecraftApplet");
return (Applet)localClass.newInstance();
}   

好吧,非常简单,用您自己的静态加载方法替换classLoader.loadClass。所以,我尝试了,在我的类加载器中,这是我的转换代码:

代码语言:javascript
复制
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 (正如您在上面看到的,我转储它)

代码语言:javascript
复制
public Applet createApplet() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Class localClass = MinecraftLauncher.loadClass(classLoader).loadClass("net.minecraft.client.MinecraftApplet");
return (Applet)localClass.newInstance();
}

下面是GameUpdater中createApplet方法的字节码的图片

现在,我没有其他的想法来做这件事。如果有人能给我指出正确的方向,那就太棒了!同时,我将继续尝试,并阅读bcel文档。

如果你有任何关于更多代码等的问题,请告诉我。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-01-06 13:59:21

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

示例

代码语言:javascript
复制
instructionList.insert(instruction, classLoaderCall);
instructionList.delete(instruction);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14178980

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档