我正在尝试使用 ByteBuddy 附加到我的计算机上运行的正在运行的进程。我希望在我附加到正在运行的程序时,我的代理将导致重新加载加载的类并显示我的 Transformer 的打印语句。相反,当我停止正在附加的正在运行的进程时,会发生一些来自我的 Transformer 的打印语句,用于某些 JDK 类。代码贴在下面:import net.bytebuddy.ByteBuddy;import net.bytebuddy.agent.ByteBuddyAgent;import net.bytebuddy.dynamic.loading.ClassReloadingStrategy;import net.bytebuddy.implementation.FixedValue;import java.io.*;import static net.bytebuddy.matcher.ElementMatchers.named;public class Thief { public static void main(String[] args) throws Throwable { String pid = "86476"; // <-- modify this to attach to any java process running on your computer System.out.println(new Thief().guessSecurityCode(pid)); } public String guessSecurityCode(final String pid) throws Throwable { File jarFile = createAgent(); ByteBuddyAgent.attach(jarFile, pid); return "0000"; }
1 回答
蝴蝶不菲
TA贡献1810条经验 获得超4个赞
仅仅添加一个转换器不会导致重新加载已经加载的类。默认情况下,您的转换器只会看到新加载的类,因此您在退出时看到一些类的原因是这些类以前没有使用过,而是专门为关闭过程加载的。
要重新转换您首先必须addTransformer(yourTransformer, true)
用于注册的类,然后使用您要转换retransformClasses
的类调用。注意getAllLoadedClasses的存在和getInitiatedClasses(ClassLoader)
作为附加说明,我强烈反对将 Java 代理嵌入为源代码字符串的方法,需要将它们写入临时文件,调用编译器并最终创建 jar 文件。您可以轻松地将代理类集成到您的普通源代码中。然后,要生成仅包含代理类的 jar 文件,您只需将现有.class
文件从应用程序的代码库复制到代理 jar。对于简单的情况,您可以同时使您的应用程序 jar 文件成为有效的代理 jar 文件,然后直接使用它,而无需任何额外的复制步骤。
此外,请记住, aClassFileTransformer
应该始终返回null
它不会更改的所有类。返回原始类文件字节在语义上是相同的,但是调用方需要付出额外的努力才能发现您没有更改它。对于将为每个加载的类调用的代码,但通常只对少数感兴趣(或者只想打印信息而不更改任何内容),这样的性能问题很重要。
添加回答
举报
0/150
提交
取消