BCel 即时修补方法不起作用



我正在尝试使用BCEL将回调插入Java方法,但从未调用回调。程序的运行就好像根本没有被检测过一样。

我所做的精简版本:

package com.github.worldsender;
import java.lang.reflect.InvocationTargetException;
import org.apache.bcel.*;
import org.apache.bcel.classfile.*;
import org.apache.bcel.generic.*;
public class CustomHook {
    public static void callback() {
        System.out.println("Success");
    }
    private static JavaClass getOriginal() {
        try {
            return Repository.lookupClass("com.github.worldsender.Foo");
        } catch (ClassNotFoundException e) {
            throw new RuntimeException("Foo not found.", e);
        }
    }
    private static ClassGen modClass(ClassGen classGen) {
        for (Method method : classGen.getMethods()) {
            if (!method.getName().equals("main"))
                continue;
            classGen.removeMethod(method);
            MethodGen methodGen = modConstructor(classGen, method);
            classGen.addMethod(methodGen.getMethod());
            methodGen.getInstructionList().dispose();
            return classGen;
        }
        throw new RuntimeException("Method not found, abort");
    }
    private static MethodGen modConstructor(ClassGen classGen, Method constructor) {
        InstructionFactory factory = new InstructionFactory(classGen);
        ConstantPoolGen constants = classGen.getConstantPool();
        MethodGen methodGen = new MethodGen(constructor, classGen.getClassName(), constants);
        InstructionList ilist = methodGen.getInstructionList();
        String invokedClass = "com.github.worldsender.CustomHook";
        String invokedMethod = "callback";
        Type returnType = Type.VOID;
        Type[] arguments = Type.NO_ARGS;
        short invokeType = Constants.INVOKESTATIC;
        InvokeInstruction invoke = factory.createInvoke(invokedClass, invokedMethod, returnType, arguments, invokeType);
        ilist.insert(invoke);
        methodGen.stripAttributes(true);
        methodGen.setMaxStack();
        methodGen.setMaxLocals();
        return methodGen;
    }
    public static void main(String[] args) throws Exception {
        JavaClass original = getOriginal();
        ClassGen modClass = new ClassGen(original);
        modClass = modClass(modClass);
        Repository.removeClass(original);
        Repository.addClass(modClass.getJavaClass());
        Class<?> minecraftMain = Class.forName("com.github.worldsender.Foo");
        java.lang.reflect.Method meth = minecraftMain.getMethod("main", String[].class);
        meth.invoke(null, (Object) args);
    }
}
//// Other class
package com.github.worldsender;
public class Foo {
    public static void main(String[] args) {
        System.out.println("Here");
    }
}

打印的所有内容是:

Here

我期待的是:

Success
Here

我做错了什么?

调用时

Repository.addClass(modClass.getJavaClass())

将类添加到 BCEL 存储库,但不添加到当前 VM 的类路径。呼叫时

Class.forName("com.github.worldsender.Foo")

但是,您正在指示 VM 从类路径加载未修改的类文件。因此,您无法观察到任何效果。查看 BCEL 用于加载生成的类的内置类加载器。

相关内容

  • 没有找到相关文章

最新更新