栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

在Javassist中修改行号

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在Javassist中修改行号

容易的部分

CtMethod对象中存在的方法insertAt(int lineNumber,String
src)
允许在给定行中的代码
之前* 注入以 src 编写的代码。 *

例如,使用以下(简单)示例程序:

public class TestSubject {   public static void main(String[] args) {     TestSubject testSubject = new TestSubject();     testSubject.print();   }   private void print() {    System.out.println("One"); // line 9    System.out.println("Two"); // line 10    System.out.println("Three"); // line 11   }}

通过简单的编码(请记住,方法变量必须是 打印 方法的CtMethod表示形式):

   // notice that I said line 10, which is where the sysout of "two" is   method.insertAt(10, true, "System.out.println("one and an half");");

将在类中插入新的sysout指令。新类的输出将是:

 one one and an half two  three

困难的部分

Javassist没有提供简单的方法来删除一行代码,因此,如果您真的想替换它,那么除了破解之外,别无选择。

怎么做?好吧,让我向您介绍您的新朋友(如果您还不知道)CodeAttribute对象。

CodeAttribute对象负责保存表示方法流的字节码,该代码属性还具有另一个名为LineNumberAttribute的属性,该属性可帮助您将行号映射到字节码数组中。因此,总结该对象即可满足您的所有需求!

以下示例中的想法非常简单。将字节码数组中的字节与应删除的行相关联,并用无操作码替换字节。

再一次,method是方法 print 的CtMethod表示形式 __

    // let's erase the sysout "Two"    int lineNumberToReplace = 10;    // Access the pre attribute    CodeAttribute preAttribute = method.getMethodInfo().getCodeAttribute();    // Access the LineNumberAttribute    LineNumberAttribute lineNumberAttribute = (LineNumberAttribute)      preAttribute.getAttribute(LineNumberAttribute.tag);    // Index in bytepre array where the instruction starts    int startPc = lineNumberAttribute.toStartPc(lineNumberToReplace);    // Index in the bytepre array where the following instruction starts    int endPc = lineNumberAttribute.toStartPc(lineNumberToReplace+1);    System.out.println("Modifying from " + startPc + " to " + endPc);    // Let's now get the bytepre array    byte[] pre = preAttribute.getCode();    for (int i = startPc; i < endPc; i++) {      // change byte to a no operation pre       pre[i] = CodeAttribute.NOP;    }

原始 TestSubject类中运行此修改,将导致注入的类具有以下输出:

 one three

加起来

当你有需要添加一条线,仍保持现有的一个,你只需要使用给出的例子 比较容易的部分 ,如果你想更换线路,您必须先删除使用中给出的例子既有线 的硬部分
,然后使用第一个示例注入新行。

还请记住,在示例中,我假设您已经对javassist的基础知识感到满意,只显示了多汁的部分,而不是全部内容。这就是为什么,例如,在示例中没有ctClass.writeFile
…您仍然需要这样做,我只是省略了它,因为我希望您应该知道您必须这样做。

如果您在代码示例中需要任何其他帮助,请询问。我很乐意提供帮助。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/509483.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号