java - 使用 Javassist 修改后检测加载的类

标签 java instrumentation javassist

我有以下 Javassist 代码来修改日志记录方法,使其仅记录某些情况(以尝试检测黑客在游戏中转移大笔资金,以供引用):

CtClass ctClass = ClassPool.getDefault().getCtClass(Trade.class.getName());
CtMethod commandMethod = ctClass.getDeclaredMethod("log");
commandMethod.setBody("if (/* conditions */) {"
                    + "    fw.write(sender + \" [\" + senderUser.getMoney() + \"/\" + senderOldBal + \"] sent \" + pay.getMoney() + \" to \" + receiver + \"[\" + receiverOldBal + \"/\" + receiverUser.getMoney() + \"]\");"
                    + "}");

据我了解,只需调用 ctClass.toClass()不会替换当前加载的类,为了实现这一点,我需要使用 Java 中的 Instrumentation API。然而,我还没有找到太多关于如何使用 Instrumentation API 的解释。

任何有关如何执行此操作的建议将不胜感激。

最佳答案

示例 javaagent 项目:java-agent-asm-javassist-sample (在谷歌中找到,不是我的代码)。

为了从 Instrumentation API 中受益,您需要构建自己的 javaagent:

public class Agent {

    public static void premain(String agentArgs, Instrumentation inst) {
        inst.addTransformer(new ClassFileTransformer() {
            @Override
            public byte[] transform(ClassLoader classLoader, String s, Class<?> aClass, ProtectionDomain protectionDomain, byte[] bytes) throws IllegalClassFormatException {
                if ("your/package/Trade".equals(s)) {
                    try {
                        ClassPool cp = ClassPool.getDefault();
                        CtClass ctClass = cp.get("your.package.Trade");
                        CtMethod commandMethod = ctClass.getDeclaredMethod("log");
                        commandMethod.setBody("if (/* conditions */) {"
                            + "    fw.write(sender + \" [\" + senderUser.getMoney() + \"/\" + senderOldBal + \"] sent \" + pay.getMoney() + \" to \" + receiver + \"[\" + receiverOldBal + \"/\" + receiverUser.getMoney() + \"]\");"
                            + "}");
                        byte[] byteCode = ctClass.toBytecode();
                        ctClass.detach();
                        return byteCode;
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
                return null;
            }
        });
    }

}

编译并打包到agent.jar中, list 中包含“Premain-Class”。

通过 JVM 参数传递 javagent:java -javaagent:some/path/agent.jar -jar your-main-app.jar

关于java - 使用 Javassist 修改后检测加载的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58026958/

相关文章:

java - GZIPOutputStream 不更新 Gzip 大小字节

java - play.data.Form - 如何最好地填写默认表单值

JavaScript 无法从 Java 解析使用 Gson 序列化的字符串

java - 如何使用 java.util.BitSet 表示整数数组?

wpf - 检测UI

java - 如何扩展最终类?(反射(reflection),Javassist)

c++ - 为 C/C++ 程序编写检测工具

java - Cobertura Maven 插件中的目标 "cobertura:instrument"

java - 将java类对象写入java源文件

java - Android 的自定义类加载器?