`
aswang
  • 浏览: 848130 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

ASM指南翻译-5

 
阅读更多

2.2.4转换类

到目前为止,ClassReaderClassWriter都是独立使用。手工产生事件,然后被ClassWriter直接消费,或者对称地,事件由ClassReader产生,然后手工地消费,如通过一个自定义的ClassVisitor来实现。当把这些组件组合在一起使用时,将变得很有趣。第一步,将ClassReader产生的事件导入到ClassWriter,结果就是类将被ClassReader解析,然后再由ClassWriter重组为Class

byte[] b1 = ...;

ClassWriter cw = new ClassWriter();

ClassReader cr = new ClassReader(b1);

cr.accept(cw, 0);

byte[] b2 = cw.toByteArray(); // b2 represents the same class as b1

 

当然,有趣的并不是这个过程本身(因为有更简单的方式来复制一个字节数组)。但是,接下来介绍的ClassAdapter,它处于ClassReaderClassWriter之间,将会带来变化:

byte[] b1 = ...;

ClasssWriter cw = new ClassWriter();

ClassAdapter ca = new ClassAdapter(cw); // ca forwards all events to cw

ClassReader cr = new ClassReader(b1);

cr.accept(ca, 0);

byte[] b2 = cw.toByteArray(); // b2 represents the same class as b1

 

与上面代码对应的结构图如如2.6.在下面的图中,组件以方形表示,事件以箭头表示(在序列图中是一个垂直的时间线)。



2.6 转换链

执行结果没有任何变化,因为这里使用的ClassAdapter 事件过滤器没有过滤任何东西。但是,现在可以重写这个类来过滤一些事件,以实现转换类。例如,考虑下面这个ClassAdapter的子类:

public class ChangeVersionAdapter extends ClassAdapter {

         public ChangeVersionAdapter(ClassVisitor cv) {

                   super(cv);

         }

         @Override

         public void visit(int version, int access, String name,

                   String signature, String superName, String[] interfaces) {

                   cv.visit(V1_5, access, name, signature, superName, interfaces);

         }

}

这个类仅重写了ClassAdapter的一个方法。因此,所有的调用都未经过改变直接传递给了ClassVisitor实例cvcv通过构造方法传递给自定义的ClassAdapter,除了visit方法,visit方法修改了类的版本号。对应的序列图如下:


2.7

 

可以通过修改visit方法的其它参数来实现其它转换,而不仅仅是修改类的版本号。例如,你可以给类增加一个借口。当然也可以修改类的名称,但是这需要修改很多东西,而不只是修改visit方法中类的名称。实际上,类名可能在很多地方存在,所有这些出现的地方都需要修改。

 

优化

前面的转换只改变了原始类中的四个字节。尽管如此,通过上面的代码,b1被完整的解析,产生的事件被用来从头构造b2,尽管这样做不高效。另一种高效的方式是直接复制不需要转换的部分到b2,这样就不需要解析这部分同时也不产生对应的事件。ASM会自动地对下面的方法进行优化:

 

  • 如果ClassReader检测到一个MethodVisitor直接被ClassVisitor返回,而这个ClassVisitor(如ClassWriter)是通过accept的参数直接传递给ClassReader,这就意味着这个方法的内容将不会被转换,并且对应用程序也是不可见的。
  • 在上面的情形中,ClassReader组件不会解析这个方法的内容,也不会产生对应的事件,而只是在ClassWriter中复制该方法的字节数组。

 

这个优化由ClassReaderClassWriter来执行,如果它们拥有彼此的引用,就像下面的代码:

byte[] b1 = ...

ClassReader cr = new ClassReader(b1);

ClassWriter cw = new ClassWriter(cr, 0);

ChangeVersionAdapter ca = new ChangeVersionAdapter(cw);

cr.accept(ca, 0);

byte[] b2 = cw.toByteArray();

 

经过优化,上面的代码将比前面例子中的代码快两倍。因为ChangeVersionAdapter没有转换任何方法。对于转换部分或者所有方法而言,这种对速度的提高虽然很小,但确实显著的,可以达到10%20%。不幸地是,这种优化需要复制在原始类中定义的所有常量到转换后的类中。这对于在转换中增加字段,方法或者指令什么的不是一个问题,但是相对于未优化的情形,这会导致在大的类转换过程中删除或者重命名很多类的元素。因此,这种优化适合于需要添加代码的转换。

 

使用转换后的类

 

转换后的类b2可以保存到磁盘或者被ClassLoader加载,如前面章节描述的。但是在一个ClassLoader中只能转换被该ClassLoader加载的类。如果你想转换所有的类,你需要把转换的代码放置到一个ClassFileTransformer中,该类定义在java.lang.instrment包中(可以参看该报的文档获得详细信息):

public static void premain(String agentArgs, Instrumentation inst) {

         inst.addTransformer(new ClassFileTransformer() {

                   public byte[] transform(ClassLoader l, String name, Class c,

                            ProtectionDomain d, byte[] b)throws IllegalClassFormatException {

                            ClassReader cr = new ClassReader(b);

                            ClassWriter cw = new ClassWriter(cr, 0);

                            ClassVisitor cv = new ChangeVersionAdapter(cw);

                            cr.accept(cv, 0);

                            return cw.toByteArray();

                            }

         });

}

  • 大小: 19.2 KB
  • 大小: 5.4 KB
1
1
分享到:
评论

相关推荐

    ASM3.0指南翻译

    ### ASM3.0指南翻译——深入理解Java字节码引擎库 #### 1. 引言与背景 在软件开发领域,程序分析、生成及转换技术的应用极为广泛,覆盖从语法解析到语义分析,再到代码优化、混淆、调试、性能监控及面向切面编程等...

    ASM4使用指南.pdf

    根据提供的文件信息,以下是关于“ASM4使用指南.pdf”文档中所提及知识点的详细介绍: 1. ASM库介绍: ASM(Java字节码操作和分析框架)是一个Java字节码操作与分析框架。它被设计用于直接以类文件的形式读写和修改...

    ASM30-LINK30和实用程序用户指南

    根据给定的文件信息,我们可以提炼出以下几个关键的知识点,主要围绕着ASM30-LINK30和实用程序用户指南,以及Microchip Technology Inc.的相关信息进行深入解析: ### 1. 微芯科技(Microchip Technology Inc.)...

    C32Asm 反汇编工具

    在压缩包中的"读我.txt"文件,很可能是C32Asm的使用指南或注意事项,它可能包含了安装步骤、配置选项、命令行参数以及一些使用技巧。而"c32asm"可能是个可执行文件,即C32Asm工具本身,或者是一个示例文件,用于演示...

    反汇编工具 win32asm

    描述中提到的“汉化了的,好用”,意味着这个win32asm工具已经被翻译成了中文,这对于中文用户来说是一个极大的便利,因为它消除了语言障碍,使得不懂英文的开发者也能轻松使用。通常,反汇编器的界面和文档都是英文...

    《Win32asm与Radasm开发教程》第二阶段视频的代码和资料下载

    《汇编程序员之代码风格指南》,此书是我自己翻译的中文版,网上已有很多 地方可下载,学习汇编语言而不注意编码风格是很吃亏的事,此书能教你什么时候 该做什么,什么时候不应该做什么。良好的编码风格对于win32...

    ADS开发工具详细教程

    src DCD 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4 dst DCD 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 END ``` 该程序定义了两个缓冲区`src`和`dst`,并通过循环将`src`中的...

    汇编程序员之代码风格指南

    本指南由著名的汇编语言专家Randall Hyde撰写,并由jhkdiy翻译成中文版。该指南旨在帮助程序员理解如何提高他们所编写的汇编代码的可读性。书中通过一系列实例来展示常见的问题及其解决方案,这些实例均来自互联网上...

    GCC中文手册.PDF

    本中文手册是由一位热心人士翻译整理的,其内容主要摘自GNU C编译器的官方文档。手册旨在为用户提供一个简明扼要的GCC使用指南,特别是针对编译器选项的解释。 #### 二、手册重要声明 1. **免责声明**:手册的内容...

    c++实现的mips汇编器

    - `ReadMe.txt`:通常包含项目说明、使用指南或者注意事项。 - `ConsoleApplication1`:可能是C++编译生成的可执行程序,包含了汇编和反汇编的功能。 - `汇编与反汇编exe`:这可能是最终生成的汇编和反汇编器的可...

    AsmToE汇编机器码转换工具

    - 中文伪指令.txt 可能包含了易语言中的特殊指令,这些指令在易语言中用中文表示,但被翻译为对应的汇编指令。 - 测试代码.txt 包含了一些示例代码,用于测试软件的功能和性能。 - 高级指令.txt 可能介绍了更复杂或...

    Linux 汇编语言开发指南

    ### Linux 汇编语言开发指南 #### 一、简介 汇编语言作为一种低级语言,在现代编程领域中虽然不如高级语言那样普及广泛,但它在特定场景下的优势不容忽视。尤其是在Linux环境中,汇编语言被用于优化性能敏感的模块...

    Windows 汇编语言编程指南

    全部翻译完了,给我的感觉就是这篇文章是为已有汇编基础但从未接触过Windows汇编编程的读者写的,虽然对我来说这些内容很简单,但也觉得说的很详细了,好过国内许多三言两语的所谓菜鸟教程;但如果读者想全面学习Win...

    Pro-E三维转二维的一些设置.pdf

    - `PRO/Emenu_translatyesnopro/enno-yes-both` 可能指的是菜单的翻译设置,用户可以根据需要选择中文、英文或者是双语界面。 - `menu_fontARIAL`:指定菜单使用的字体为Arial,确保了软件界面的一致性和可读性。 ...

    Oracle Database Reference 10.2.pdf

    2. **限制性使用**:根据许可证协议中的规定,用户不得擅自复制、翻译、广播、修改、授权、传输、分发、展示或表演软件的任何部分,除非许可证协议中有明确规定或许可,或者法律允许的情况。 3. **反向工程禁止**:...

    乐曲程序的设计与实现

    在提供的文件列表中,"huibian.doc"可能是关于ASM乐曲程序设计的一个指南或教程,可能详细介绍了如何编写和调试ASM代码以创建音乐程序。而"www.pudn.com.txt"可能是从一个编程讨论论坛或资源网站下载的资料,可能...

    dREAMtHEATER翻的国外汇编教程

    2. **Win32汇编编程指南**: - **Win32环境下的开发工具**:介绍用于编写、编译和调试Win32汇编程序所需的工具链。 - **创建Win32汇编应用程序**:讲解如何从零开始构建一个简单的Win32汇编程序。 - **Win32 API...

Global site tag (gtag.js) - Google Analytics