安全测试 byte-buddy 字节码修改工具有偿求助

一指 · 2024年08月06日 · 最后由 一指 回复于 2024年08月08日 · 4988 次阅读
  1. 我需要截获已加载类的方法执行过程,但是目前报错,我会把报错粘贴出来 Exception in thread "main" java.lang.IllegalStateException: Cannot call super (or default) method for public java.lang.String Foo.getMyHeart(java.lang.String) at net.bytebuddy.implementation.SuperMethodCall$Appender.apply(SuperMethodCall.java:133) at net.bytebuddy.asm.Advice$Appender$EmulatingMethodVisitor.resolve(Advice.java:12130)
  2. 我尝试给被截取类,加个父类,这样就不报错了,但是实际使用中不能做到都有父类诶。
  3. 源码不方便发出来,真有偿求助,有意向的大哥可以回帖或者站内信
共收到 9 条回复 时间 点赞

大佬在哪,求助,求助

你遇到的问题与使用 ByteBuddy 这样的字节码操作库有关。ByteBuddy 在尝试用 SuperMethodCall 动态地调用超类(或接口)中的方法时遇到了问题。错误信息表明你正在尝试覆盖一个方法,但该方法没有超类实现,因此无法调用 super 或默认方法。

在 Java 中,如果一个方法是最终的 (final)、静态的 (static)、私有的 (private) 或者是构造器 (constructor),那么它不能被子类重写,也就意味着你不能从子类中调用其 super 方法版本。

解决此问题的一种可能方案是:

避免直接覆盖最终或静态方法。如果方法是最终的或静态的,你不能在子类中调用其 super 版本。你需要考虑重新设计你的类层次结构,或者使用其他技术来达到你的目的,例如代理或装饰模式。
使用接口和默认方法。如果可以的话,将方法移动到接口中并提供默认实现,然后让目标类实现这个接口。这将允许你使用 SuperMethodCall 调用默认方法。
手动重写方法。在子类中手动实现方法,而不使用 SuperMethodCall,你可以直接调用超类的实现,例如通过反射或直接调用类的非私有方法(如果适用)。
使用 ByteBuddy 的其他特性。例如,你可以使用 MethodDelegation 或 MethodInterception 来拦截方法调用,而不需要直接调用超类方法。
如果你不能改变现有的类结构并且必须在没有父类的情况下工作,你可能需要考虑使用不同的字节码操作策略,比如使用拦截器(interceptor)来修改方法的行为。

如果你愿意分享更多的代码细节,我可以提供更具体的建议。不过,既然你提到源码不便分享,你可以尝试描述一下你的具体需求或目标,也许我能给出一些通用的解决方案或建议。

最近也在学习字节码修改,码住

fox 回复

赞助人为乐~

刚接触字节码,学习一下

fox 回复

大佬,是这样的,被修改的类,如果是子类,就不会报错。
如果被修改的类是个普通类,就会报这个错
简单的代码是这样的:
public class Foo {

public Foo(){

}
public static String getMyHeart(String s,String a){
System.out.println("Method begin");
return "It's my heart";
}
}
//上述这个类是被修改的类

我想要达到的目的是,动态的修改这个类。
在如下这个调用过程中,
Foo.getMyHeart("123","456");
//代码未修改,执行方法

//执行 Bytebuddy 动态修改的内容

Foo.getMyHeart("123","456");
//参数中包含 123,执行方法

Foo.getMyHeart("456","456");
//参数中不包含 123,直接跳出方法,不执行方法

fox 回复

我有尝试使用 MethodDelegation ,但是如果使用 MethodDelegation 的话,就只能完全拦截目标方法,没法执行原方法了,我是想有条件的执行原方法

想了解下修改字节码的目的是啥呢,最近在学习 arthas,想看看大佬们都怎么玩儿字节码的

AMEAME 回复

写个安全软件,动态的监控应用程序执行,并干预执行过程

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册