java反编译器剖析(上)-java开发java经验技巧

java反编译器剖析(上)-java开发java经验技巧

ID:30780053

大小:97.09 KB

页数:7页

时间:2019-01-03

java反编译器剖析(上)-java开发java经验技巧_第1页
java反编译器剖析(上)-java开发java经验技巧_第2页
java反编译器剖析(上)-java开发java经验技巧_第3页
java反编译器剖析(上)-java开发java经验技巧_第4页
java反编译器剖析(上)-java开发java经验技巧_第5页
资源描述:

《java反编译器剖析(上)-java开发java经验技巧》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库

1、Java反编译器剖析(上)-编程开发技术Java反编译器剖析(上)木文由ImportNew・乌

2、1柏翻译自javacodegeekso欢迎加入翻译小纽.。转载请见文末要求。反编译器(或者解码器),简而言之,就是将目标程序码反转成源代码。但是其中的过程却比较复杂,也很有意思一一J3V3源码是结构化的,字节码却不是。而月.,转换不是一一对应的:两段完全不同的Java程序也可能生成完全相同的字节码,有时需要一些试探才能更加接近源码。(一段简短的)字节码教程为了更好的理解反编译器如何工作,现在有必要理解一下

3、字节码基础。如杲你对此非常熟悉,可以略过此处直接跳到下一部分。(不同于基于寄存器register-based的方式)JVM运行基■于钱。这就意味着指令会在evaluationstack(计算堆栈)上执行。操作对象可能先出栈,进行一些操作,然后再把结果入栈來进行接下來的操作。考虑如下场景:publicstaticintplus(inta,intb){intc二a+b;returnc;}注:本文所有的相关的字节码都是由javap严么例如执行命令javap-c-pMyClasSopublicstatici

4、ntplus(int,int);Code:stack二2,locals=3,argumcnts=20:iload_01:iloadl2:iadd3:istore_24:iload_25:ireturn//load'x,fromslot0,pushontostack//load"y,fromslot1,pushontostack//pop2integers,addthemtogether,andpushtheresult//poptheresult,storeas'sum'inslot2//load'

5、sum,fromslot2,pushontostack//returntheintegeratthetopofthestack方法中的木地变量(包扌舌方法声明)被寄存在所谓的木地变量数组%。为了简单起见,在这里我们将一个存放在本地变量数组位置#x处的变量称为slotttx(参见JVM规范3.6.1)o对于示例方法,slot#0的值一般是this指针。然后从左到右依次是方法中的各个变量,接下来是方法中声明的本地变量。在上面的示例中,由于方法是静态的,所以没有this指针。相应的slot#0存放的是参数

6、x,slottty存放的是参数y,本地变量sum存放在slot#2中。有意思的是,每个方法的栈大小和本地变量存储空间都有最大值的限制。二者都是在编译时决定。目前为止,所有内容都是非常直口的,仅有一点没有达到你的预期:编译器一直没有尝试去优化这些代码。事实上,javac几乎从未支持字节码优化。这样有很多好处,比如几乎口J以在任何地方设置断点:一旦移除load/store操作,就会失去这种特:性。所以,大部分压力都转移到了运行时JIT编译器(just-in-timecompiler)。反编译那么,怎样才

7、能将一个非结构化、基于栈的字节码转换为结构化的Java代码呢?通常,第一步要先按弃操作对象栈。可以通过映射栈的值成变量,并插入合适的load/store操作来实现这个步骤。如果一个“栈变量”仅仅分配并使用一次,你会发现这将产生非常多的重复变量——而口接下来会牛成的重复变量会更多!反编译器会将这些字节码缩减成更简单的指令集。这里对此不作深究。我们使用sO代表栈变量,⑴代表原始的字节码在本地的真实引用(存在slot±)O字节码栈变量复制传播0iload_0sO=vO1iload_lsl=vlv2=vO+

8、vl2iadds2=sO+si3istore2v2=s2returnv24iload_2s3=v25ireturnreturns3通过为push或pop的每个值分配一个标识符,可以将字节码转换为本地变量。比如iadd是将两个操作数出栈并、相加,并将结果入栈。然后,使用一种复制传播(copypropagation)的技术,可以消除一些重复变量。复制传播是内联的一种形式,可以将变量简单替换为指定值,前捉是这种转换是有效的。如何定义”有效性“?这里包含了一些重耍准则。考虑下面这种情况:0:sO=vl1:v

9、l二s42:v2=sO<一一sOcannotbereplacedwithvl在这里,如果将sO替换为vl结果将大不相同。因为vl的值在sO被指定Z后改变了,虽然此时vl的值却还没有被使用〈译注:原文这里是V0,根据注释可以确认为笔误)o为了避开这种复杂的情形,这里复制传播只考虑仅被赋值一茨的内联变量(inlinevariable)。译注:一个简单的(C语言)内联变量手动解析示例,来自Wikipedia:inlineexpansionintpred(intx){if(x

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。