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

使用ASM注入字节码时触发StringIndexOutOfBoundsException异常原因排查

解决ASM注入代码时的StringIndexOutOfBoundsException问题

这个异常的根源非常明确——你调用visitMethodInsn时传入的方法名字段是空字符串"",ASM在处理这个空字符串时,尝试访问它的第0个字符(用于内部语法校验或逻辑处理),直接触发了StringIndexOutOfBoundsException。

具体问题出在哪?

在JVM字节码规范里,所有类的构造方法在字节码层面的固定名称是<init>,而不是类名或者空字符串。你从ASMifier复制的代码里,所有构造方法调用的名字都被错误地写成了空字符串:

  1. SimpleDateFormat构造方法调用:
    // 错误写法
    mv.visitMethodInsn(INVOKESPECIAL, "java/text/SimpleDateFormat", "", "(Ljava/lang/String;)V", false);
    
  2. Date构造方法调用:
    // 错误写法
    mv.visitMethodInsn(INVOKESPECIAL, "java/util/Date", "", "()V", false);
    
  3. StringBuilder构造方法调用:
    // 错误写法
    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "", "()V", false);
    

这些空字符串是导致异常的直接原因——ASM内部会尝试解析方法名的结构,空字符串没有任何字符,自然会触发索引越界。

修正后的代码

把所有构造方法调用的名字改成<init>即可,修正后的关键代码片段如下:

// 初始化SimpleDateFormat
mv.visitTypeInsn(NEW, "java/text/SimpleDateFormat");
mv.visitInsn(DUP);
mv.visitLdcInsn("yyyy.MM.dd.HH.mm.ss");
// 修正:方法名改为<init>
mv.visitMethodInsn(INVOKESPECIAL, "java/text/SimpleDateFormat", "<init>", "(Ljava/lang/String;)V", false);

// 初始化Date
mv.visitTypeInsn(NEW, "java/util/Date");
mv.visitInsn(DUP);
// 修正:方法名改为<init>
mv.visitMethodInsn(INVOKESPECIAL, "java/util/Date", "<init>", "()V", false);

// 初始化StringBuilder
mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
mv.visitInsn(DUP);
// 修正:方法名改为<init>
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V", false);

为什么必须用<init>?

JVM要求所有构造方法的字节码名称必须是<init>,这是字节码层面的硬性规范。ASM作为字节码操作库,严格遵循这个规范,当你传入不符合要求的方法名(比如空字符串)时,内部的校验逻辑就会抛出异常。

修正这几处之后,你的注入代码应该就能正常执行,不会再触发这个索引越界异常了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:23:41