You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否在原始类内部运行时检测字节码篡改并告警?

运行时字节码篡改的检测与告警方案

目前存在JavaAssist、ASM等多款工具可在运行时重新生成字节码,应用性能管理(APM)便是典型场景之一——其提供的Agent会在应用启动阶段重写现有字节码。

例如,原始类A包含方法:void sayHello(String name){},这类Agent可生成如下新方法:

void NewA:sayHello(String name){
    Long start = System.currentTimeMillis();
    A::sayHello(name);
    Long elapsed = System.currentTimeMillis() - start;
}

JVM加载类后会执行NewA而非原始类A。

现咨询:能否在原始类A内部通过运行时检测识别此类修改,进而告警当前执行的字节码并非交付的原始字节码?


可以实现,以下是几种可行的思路:

  • 字节码哈希校验
    在原始类A的代码中,预先计算自身目标方法(比如sayHello)的原始字节码哈希值(如MD5、SHA-256)并硬编码在类中。运行时,通过Class.getDeclaredMethod()获取当前方法的字节码,计算哈希后与预存值对比。若不一致,说明字节码被篡改,触发告警。
    注意:要避免校验逻辑本身被篡改,可将哈希值和核心校验逻辑放在单独的强签名模块中,或使用Java的SecurityManager限制对校验代码的修改权限。

  • 栈帧检测
    在原始方法sayHello内部,通过Thread.currentThread().getStackTrace()获取当前调用栈。若发现调用栈中存在异常类(如APM Agent注入的代理类NewA),或方法调用者不符合预期,就触发告警。
    局限性:仅能检测直接代理调用,对更隐蔽的字节码修改(如直接在原始方法内插入代码而非生成代理类)可能无效。

  • 方法体结构校验
    借助ASM或JavaAssist的API,在运行时解析当前类的方法体结构,对比原始方法的指令序列。比如原始sayHello是空实现,运行时解析后发现方法体内多了计时、调用原始方法的指令,即可判定为被篡改。
    注意:需预先保存原始方法的指令特征(如指令数量、关键指令类型),避免因JVM版本差异导致的指令细微变化引发误判。

  • 类加载器校验
    检查当前类A的类加载器是否为预期加载器(如应用类加载器AppClassLoader)。若为Agent使用的自定义类加载器加载的修改后类,触发告警。但这种方式对同一类加载器内的字节码修改无效。

需要说明的是,这些方案无法做到100%防篡改——若攻击者拥有足够权限,仍可修改校验逻辑本身。但针对APM Agent这类合法工具的篡改检测,这些方案已足够实用。


内容的提问来源于stack exchange,提问作者shijie xu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 23:23:17