2013-01-06 3 views
1

배경 : 애플릿을 얻기 위해 Minecraft Launcher를 주입하고 있습니다 만, 이제는 내 클래스 로더를 통해 minecraft 파일을로드하려고합니다. 나는 GameUpdater.java (Minecraft의 gameupdater, 또한 클라이언트의 애플릿을위한 디스패처) 메소드를 발견했으며, 그 아래에는 "createApplet"이라는 메소드가 있습니다.Java BCEL 주입/교체가 잘못되었습니다.

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(); 
} 

지금, 나는 다른 생각이 bytecode info

GameUpdater의 방법 createApplet에 대한 바이트 코드의 사진입니다 어떻게 해야할지. 누군가가 올바른 방향으로 나를 가리킬 수 있다면, 그것은 굉장 할 것입니다! 그 동안, 나는 계속 노력할 것이고, bcel doc을 읽을 것입니다.

기타 코드 등에 관해 문의 사항이 있으면 알려주십시오.

답변

1

해결. 트릭은 새 것을 추가 한 후 InvokerVirtual (명령어 목록에서 OPCODE 삭제)을 삭제하는 것입니다 (로드 함수를 대체하는 정적 메소드).

instructionList.insert(instruction, classLoaderCall); 
instructionList.delete(instruction); 
관련 문제