- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用 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";
}
private static String generateSimpleAgent() {
return "import java.lang.instrument.ClassFileTransformer;" + "\n" +
"import java.lang.instrument.Instrumentation;" + "\n" +
"import java.security.ProtectionDomain;" + "\n" +
"\n\n" +
"public class Agent {" +"\n" +
" public static void agentmain(String argument, Instrumentation inst) {" +"\n" +
" inst.addTransformer(new ClassFileTransformer() {" +"\n" +
" @Override" +"\n" +
" public byte[] transform(" +"\n" +
" ClassLoader loader," +"\n" +
" String className," +"\n" +
" Class<?> classBeingRedefined," +"\n" +
" ProtectionDomain protectionDomain," +"\n" +
" byte[] classFileBuffer) {" +"\n" +
" System.out.println(\"transform on : \" +className);" +"\n" +
" return classFileBuffer;" +"\n" +
" }" +"\n" +
" });" +"\n" +
" }" +"\n" +
"}" +"\n";
}
private static String generateAgentManifest() {
return String.join("\n", "Agent-Class: Agent",
"Can-Retransform-Classes: true",
"Can-Redefine-Classes: true",
"Premain-Class: Agent"
);
}
private static String generateAgentManifest2() {
return String.join("\n",
"Manifest-Version: 1.0",
"Agent-Class: Agent",
"Permissions: all-permissions"
);
}
private static String generateTransformer() {
return String.join("\n",
"import java.lang.instrument.ClassFileTransformer;",
"import java.security.ProtectionDomain;",
"import java.util.Arrays;",
"public class Transformer implements ClassFileTransformer {",
" public byte[] transform(ClassLoader loader, String className, Class<?> cls, ProtectionDomain dom, byte[] buf) {",
" return null;",
" }",
"}"
);
}
private static void writeFile(String path, String data) throws IOException {
final PrintWriter out = new PrintWriter(path);
out.print(data);
out.close();
}
private static void runCommand(String cmd) throws Exception {
System.out.println("[commmand] " + cmd);
String s;
Process p = Runtime.getRuntime().exec(cmd);
BufferedReader out = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((s = out.readLine()) != null) {
System.out.println("[out] " + s);
}
out = new BufferedReader(new InputStreamReader(p.getErrorStream()));
while ((s = out.readLine()) != null) {
System.out.println("[err] " + s);
}
p.waitFor();
System.out.println("[exit status] " + p.exitValue());
p.destroy();
}
private static File createAgent() throws Throwable {
writeFile("Agent.java", generateSimpleAgent());
writeFile("Transformer.java", generateTransformer());
writeFile("manifest.mf", generateAgentManifest2());
runCommand("javac Agent.java Transformer.java");
runCommand("jar -cfm agent.jar manifest.mf Agent.class Transformer.class");
return new File("agent.jar");
}
}
最佳答案
仅添加变压器不会导致重新加载已加载的类。默认情况下,您的变压器只会看到新加载的类,因此您在退出时看到一些类的原因是这些类之前没有使用过,而是专门为关闭过程加载的。
要重新转换类,您首先必须使用 addTransformer(yourTransformer, true)
进行注册,然后调用 retransformClasses
与您想要转换的类。注意 getAllLoadedClasses 的存在和 getInitiatedClasses(ClassLoader)
作为补充说明,我强烈反对采用将 Java 代理作为源代码字符串嵌入的方法,需要将它们写入临时文件、调用编译器并最终创建 jar 文件。您可以轻松地将代理类集成到普通源代码中。然后,要生成仅包含 Agent 类的 jar 文件,您只需将现有的 .class
文件从应用程序的代码库复制到 Agent jar 即可。对于简单的情况,您可以同时使应用程序 jar 文件成为有效的代理 jar 文件,然后直接使用它,无需任何额外的复制步骤。
此外,请记住,对于所有未更改的类,ClassFileTransformer
应始终返回 null
。返回原始类文件字节在语义上是相同的,但调用方需要付出额外的努力才能发现您没有更改它。对于将为每个加载的类调用但通常只对少数几个类感兴趣(或者只想打印信息而不更改任何内容)的代码,此类性能问题很重要。
关于java - ByteBuddy 附加到本地正在运行的进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55029961/
我有一个无法修改的大型第 3 方代码库,但我需要在许多不同的地方进行微小但重要的更改。我希望使用基于 ByteBuddy 的代理,但我不知道如何使用。我需要替换的调用的形式为: SomeSystemC
我正在尝试在 bytebuddy 中创建一个抽象类的子类,并想用我自己的函数覆盖构造函数。我不能让它与 defineConstructor 一起工作。 父类(super class): public
如何将 byte-buddy 生成的类与“org.reflections”一起使用? 例子: Class dynamicType = new ByteBuddy() .
我正在尝试更改已加载类的方法的返回值。 从 ByteBuddy 的文档 (http://bytebuddy.net/#/tutorial) 看来,只要我不添加任何字段/方法,这似乎可以使用 Java
我正在尝试使用 ByteBuddy 附加到我的计算机上运行的正在运行的进程。我希望在附加到正在运行的程序时,我的代理将导致重新加载已加载的类并显示我的 Transformer 的打印语句。 相反,当我
我正在尝试使用 ByteBuddy 重新定义 2 个方法,如下所示: ClassLoader classLoader = ClassLoader.getSystemClassLoader(); Cla
如何使用 AgentBuilder 将子类与名称匹配? 我可以轻松匹配类型本身 new AgentBuilder.Default() .type(named("SomeClass"))
我正在尝试与字节伙伴一起模仿模拟创建。是否可以一次性拦截所有方法? 我尝试了以下方法: new ByteBuddy() .subclass(Object.class) .method(na
我正在尝试编写一个如下所示的通用方法: private static Class immutableVersionOfClass(Class clazz) { return new Byte
我有一个带有方法 m() 的类 A 和带有方法 n() 的类 B。在 A 中,我有一个 B 类型的字段 b。在 m() 中的某个时刻会调用 b.n()。我需要使用 ByteBuddy 更改 A 的代码
我有一堆在普通 JDK 上运行的 Web 服务,我需要拦截所有公共(public)方法才能执行某些操作。一些方法使用@WebParam 注释。使用 ByteBuddy 对 WebService 进行子
如果我有以下内容: public abstract class Parameterized { protected abstract String foo(); } 是否可以这样做: Dynami
语境 我正在使用 ByteBuddy 实现字节码转换,操作过程是一个多步骤过程。 因此,操作必须能够: 扩充原有方法 完全创建新方法 扩充通过 2 引入的方法。 对于 1. 我使用了 @OnMetho
我目前正在尝试制作一个记录器代理,我目前正在拦截 PrepareStatement 类。在 PrepareStatement 中,有多种我希望跟踪的方法,但我感觉我做错了。 通常我现在所做的是拦截我希
我已经使用 ByteBuddy 库有一段时间了,但我发现自己陷入了困境。当测试的类位于同一个文件中(作为静态内部类)时,我可以使用此方法,但现在我已将逻辑分离到一个单独的文件中,它不再起作用。 如果有
如何定义一个方法,然后用 ByteBuddy 装饰它(多次)?这是我的例子 Builder builder = new ByteBuddy().subclass(Object.class).name(
有没有办法使用 ByteBuddy 为没有空构造函数的类创建代理? 这个想法是为给定的具体类型创建一个代理,然后将所有方法重定向到处理程序。 此测试展示了为没有空构造函数的类创建代理的场景,它会抛出
我正在尝试使用 bytebuddy 为进程附加代理。我发现我们可以使用 ByteBuddyAgent.attach(file,"18467");为了这。但是当我尝试执行此操作时,发生了以下错误。 这是
我正在尝试开发一个需要使用注释的工具。一个重要的功能是定位带有注释的元素并更改其值,即 // from this @Annotation(value = "foo") class SomeClass
我正在使用 Byte Buddy 1.9.0 作为基于 Xtext 的编程语言的代码生成器,并且我正在努力为实例化“匿名”类的方法生成字节码。出于所有意图和目的,我试图让 Byte Buddy 创建一
我是一名优秀的程序员,十分优秀!