反编译 订阅
计算机软件反向工程(Reverse engineering)也称为计算机软件还原工程,是指通过对他人软件的目标程序(比如可执行程序)进行“逆向分析、研究”工作,以推导出他人的软件产品所使用的思路、原理、结构、算法、处理过程、运行方法等设计要素,某些特定情况下可能推导出源代码。反编译作为自己开发软件时的参考,或者直接用于自己的软件产品中。 展开全文
计算机软件反向工程(Reverse engineering)也称为计算机软件还原工程,是指通过对他人软件的目标程序(比如可执行程序)进行“逆向分析、研究”工作,以推导出他人的软件产品所使用的思路、原理、结构、算法、处理过程、运行方法等设计要素,某些特定情况下可能推导出源代码。反编译作为自己开发软件时的参考,或者直接用于自己的软件产品中。
信息
定    义
高级语言源程序经过编译变成
类    型
反编译:机器码(汇编语言)
概述 
计算机软件反向工程
中文名
反向编译
关联软件
VBExplorer,JD(Java Decompiler)等
别    称
计算机软件还原工程
反向编译定义
高级语言源程序经过编译变成可执行文件,反编译就是逆过程。
收起全文
精华内容
参与话题
问答
  • Android APK反编译就这么简单 详解(附图)

    万次阅读 多人点赞 2014-03-11 22:06:09
    你往往会去借鉴别人的应用是怎么开发的,那些漂亮的动画和精致的布局可能会让你爱不释手,作为一个开发者,你可能会很想知道这些效果界面是怎么去实现的,这时,你便可以对改应用的APK进行反编译查看。下面是我参考...

    在学习Android开发的过程你,你往往会去借鉴别人的应用是怎么开发的,那些漂亮的动画和精致的布局可能会让你爱不释手,作为一个开发者,你可能会很想知道这些效果界面是怎么去实现的,这时,你便可以对改应用的APK进行反编译查看。下面是我参考了一些文章后简单的教程详解。

    (注:反编译不是让各位开发者去对一个应用破解搞重装什么的,主要目的是为了促进开发者学习,借鉴好的代码,提升自我开发水平。)


    测试环境:

            win 7 


    使用工具:

         CSDN上下载地址:

           apktool (资源文件获取  下载  

           dex2jar(源码文件获取) 下载

           jd-gui  (源码查看) 下载

     

           Android反编译整合工具包(最新) 下载

     

         官方最新版本下载地址:

           apktool(google code)

      dex2jar(google code)  

       jd-gui(google code)最新版请见官方


    工具介绍:

    apktool  

         作用:资源文件获取,可以提取出图片文件和布局文件进行使用查看

    dex2jar

         作用:将apk反编译成java源码(classes.dex转化成jar文件)

    jd-gui

         作用:查看APK中classes.dex转化成出的jar文件,即源码文件


    反编译流程:

    一、apk反编译得到程序的源代码、图片、XML配置、语言资源等文件

    下载上述工具中的apktool,解压得到3个文件:aapt.exeapktool.batapktool.jar ,将需要反编译的APK文件放到该目录下,

    打开命令行界面(运行-CMD) ,定位到apktool文件夹,输入以下命令:apktool.bat d -f  test.apk  test    


    (命令中test.apk指的是要反编译的APK文件全名,test为反编译后资源文件存放的目录名称,即为:apktool.bat   d  -f    [apk文件 ]   [输出文件夹]

    说明获取成功,之后发现在文件夹下多了个test文件,点击便可以查看该应用的所有资源文件了。

    如果你想将反编译完的文件重新打包成apk,那你可以:输入apktool.bat   b    test(你编译出来文件夹)便可,效果如下:


    之后在之前的test文件下便可以发现多了2个文件夹:

    build

    dist(里面存放着打包出来的APK文件)


    二、Apk反编译得到Java源代码

    下载上述工具中的dex2jarjd-gui ,解压

    将要反编译的APK后缀名改为.rar或则 .zip,并解压,得到其中的额classes.dex文件(它就是java文件编译再通过dx工具打包而成的),将获取到的classes.dex放到之前解压出来的工具dex2jar-0.0.9.15 文件夹内,

    在命令行下定位到dex2jar.bat所在目录,输入dex2jar.bat   classes.dex效果如下:

    在改目录下会生成一个classes_dex2jar.jar的文件,然后打开工具jd-gui文件夹里的jd-gui.exe,之后用该工具打开之前生成的classes_dex2jar.jar文件,便可以看到源码了,效果如下:

    被混淆过的效果图(类文件名称以及里面的方法名称都会以a,b,c....之类的样式命名):



    三、 图形化反编译apk(本人未使用过)

    上述步骤一、二讲述了命令行反编译apk,现在提供一种图形化反编译工具:Androidfby

    首先,下载上述反编译工具包,打开Androidfby目录,双击Android反编译工具.exe,就可以浏览打开要反编译的apk


    通过反编译,你可以获知该应用用到了什么第3方的库文件,它的代码是如何编写的等等。

    然而,如果该APK进行了混淆处理,那么你看到的类文件名称以及里面的方法名称都会以a,b,c....之类的样式命名,所以你可以想找到你所想得知的界面代码可能会十分费劲,找到了代码可能看起来也会很费劲,可是一个大体的思路会获得,有了这个思路,你就可以自己去尝试了。

    本人曾经想写一个类似唱吧的名人界面布局,可是当初第一次接触不知道如何去写,进进行了反编译,即使他的那个代码是混淆过的,我也看出来他是通过LISTVIEW的TYPE设定不同的ITEM布局实现了。可能好多引用都是采用重写VIEW来实现效果,你可以得到他的大体思路对你的开发有益无害。


    还有处于一个开发者辛辛苦苦将自己的应用开发出来被别人一反编译便成为了他自己的东西,所以要进行混淆处理:

    以下是我转载的混淆的教程:http://blog.csdn.net/vipzjyno1/article/details/21042823


    展开全文
  • 反编译系列教程(上)

    2018-03-08 11:06:21
    MalwareBenchmark · 2016/03/14 15:25Author: MalwareBenchmark0x00 简介《编译原理》课程在大学本科阶段就难道了很多计算机专业的同学。...顾名思义,反编译可以认为是编译的逆过程,这一点从编译和反编译(C...

    MalwareBenchmark · 2016/03/14 15:25

    Author: MalwareBenchmark

    0x00 简介

    《编译原理》课程在大学本科阶段就难道了很多计算机专业的同学。而反编译技术更需要从事者具有深厚的编译技术基础,因此一直是很多业内人士希望能够深入了解和掌握的一门技术。

    从现在开始,我们讨论反向编译的一些内容。顾名思义,反编译可以认为是编译的逆过程,这一点从编译和反编译(Compile and De-compile,英文中也有用De-compilation来表示反编译的)的中英文描述都可看出。但这看似只有一字之差的名称,在实际应用中并不是简单的“逆流而上”。因为在多数时候“创造”远比“恢复”来得简单,就好像您不小心打碎了家里的花瓶,想要通过修复和粘接把碎片恢复成原样,几乎是不可能办到的。即便能够基本复原,但粘接的花瓶与它原来的样子也不会完全一样。与碎片到花瓶的变化类似,反编译过程远比编译过程复杂和繁琐,而且反编译的结果也远远不如您原来编写的代码那么“美妙”。但是反向编译却能在程序功能分析、恶意代码发现、二进制翻译等特殊工作中发挥重要作用,这也是笔者仍然致力于研究这一并不十分完善的技术的重要原因。

    0x01 反编译的概念和基本过程


    1.什么是反编译

    在这一节里我们将对反编译做出一个基本的说明,给出反编译的概念,使读者们可以对反编译有一个初步的理解。我们给出的概念不是学术研究中严谨的定义,只是作者基于相关文献和多年来的研究心得所给出的一段说明。此外,我们还会揭示一个事实,尽管编译与反编译看起来是正反两项技术,但有趣的是:反编译器的编写方法却恰恰依赖于编译器的编写技术。

    反编译概念

    反编译技术是通过对低级语言代码(二进制代码或者汇编代码等)进行分析转化,得到等价的高级语言(不限制语言类型,本书的描述主要以C语言为例)代码的过程。它涉及指令系统,可执行文件格式,反汇编技术,数据类型分析技术,控制流分析技术和高级代码生成技术等。

    编译与反编译

    反编译的本质是编译的逆过程。从二十世纪五十年代第一个编译器出现开始,将机器码转换成为高级语言的期望就引发了人们广泛的兴趣。图1揭示了编译器同反编译器之间的关系。

    可以看到编译器同反编译器都将程序从一种形式转换到另外一种形式,而且在转换的步骤中,都使用了类似的中间表示。差别只是在于编译器的总体方向是从源程序到机器码,而反编译器的总体方向则是从机器码到源程序。尽管在整体方向上两者是相反的,但编译器和反编译器往往在分析阶段使用类似的技术,例如数据流分析。

    编译器通过对源代码进行解析得到中间表示(IR,intermediaterepresentation),反编译器通过对指令进行解码得到中间表示。类似的,编译器的低级代码生成同反编译器的高级代码生成恰好对应。

    图1 编译器同反编译器在结构上的对应性

    编译的过程为源程序打上了机器属性,比如CPU及寄存器的使用、机器指令的使用、以及内存地址的分配等;而反编译过程则需要剥离机器相关的细节,尽可能地区分指令和数据,通过逆向分析,重建高级数据结构和程序结构。

    反编译器

    反编译器是利用反编译技术实现的具体软件系统。它读入一个机器语言的程序(被编译器编译生成的二进制编码,即源语言),并把它翻译为一个等价的高级语言程序(即目标语言)。反编译器或反向编译器,尝试逆向一个编译器的过程,把一个二进制程序或可执行程序翻译成一个高级语言程序。它应用基本的反编译器技术,把多种多样的机器语言二进制程序反编译成某种高级语言。反编译器的结构是基于编译器的结构,而且应用类似的原理和技术进行程序分析。

    2.反编译的基本过程

    在这一小节,我们按照三种不同的分类,从多个角度阐述反编译的基本过程。

    1. 如果按照反编译技术实施的顺序划分,则可以分为7个阶段,它们是:句法分析、语义分析、中间代码生成、控制流图生成、控制流分析、代码生成。如图所示。

      图2 按照反编译技术实施的顺序划分

    2. 如果按照实践中的具体操作划分,一般也可以分为7个不同的步骤,分别是:文件装载,指令解码,语义映射,相关图构造,过程分析,类型分析和结果输出等。如图 3。

      图3 反编译操作

      以逆向分析为目的,反编译的各个阶段并不是一个严格的一遍顺序,而是存在着一些并行的模块,并且也需要通过循环执行分析过程来针对某些特殊问题(例如非N分支代码产生的间接跳转指令)进行分析和恢复。

    3. 反编译的处理过程,如果按功能区分,可以分为:前端、中端和后端三个部分。其实这种划分方式是将上述两种过程的阶段进行合并,也就是将几个反编译器阶段组合在一起。这样划分的好处是:通过设计不同的前端、中端和后端以实现针对多种源和目标的反编译器。

    0x02 反编译的前世今生


    1.建立——20世纪60年代

    随着第一台计算机的诞生,硬件与软件就成了构成计算机系统的两个重要组成部分,它们相伴而生、相互促进,它们分工迥异、各司其职。为了使用和驱动不断演化的硬件系统,通过计算机语言来编写系统和应用程序的方式逐渐确立了主流的地位。伴随着高级编程语言的出现,第一代编译器也在20世纪50年代产生了,它实现了高级语言到机器代码的等价转换,完成了人类认知到机器“认知”的转换。而几乎与此同时,将机器码还原成为高级语言的逆向思考也引发了研究人员的求知欲望。

    在第一代编译器出现十年之后的20世纪60年代,以小规模集成电路为特征的第三代计算机开始出现。由于其与第二代晶体管计算机的差异较大,使得运行在第二代计算机上的软件几乎面临着即将被全部淘汰的危险。然而基于当时的软件开发技术和开发成本,淘汰软件意味着巨大的损失。为了挽救这些价值不菲的软件,同时也为了加速开发第三代机器的软件,与软件移植技术相关的研究逐渐兴起,例如:程序转换器、交叉汇编器、翻译器、反编译器等。其中反编译器成了最初的研究热点。

    1) D-Neliac——反编译器的开山祖师

    一些美国公司和研究机构开始着手进行软件移植工具的研究,并且由美国海军电子实验室的J.K.Donally和H.Englander在1960年实现了第一代反编译器D-Neliacdecompiler。由此我们的反编译器鼻祖正式“粉墨登场”了,比它的兄弟“编译器”整整小了10岁。Donnelly-Neliac(D-Neliac)可以将机器代码反编译成Neliac(类似于Algol的一种编程语言,是NEL在1955年开发的一个Algol-Algorithmiclanguage类型语言)程序代码。

    2) Sassaman的Fortran反编译器——不是一个人的江湖

    无独有偶,1966年Sassaman在TRW公司开发了一个反编译器,该反编译器以IBM 7000序列的符号化汇编程序做为输入并产生Fortran程序,是第一个使用汇编程序而非纯二进制代码作为输入的反编译器。它是有据可查的第二个正式的反编译器,但是由于它以包含大量有用信息的符号化汇编程序作为输入,而省却了反汇编的过程,也因此降低了反编译的难度。这是第一个使用汇编程序而非纯二进制代码作为输入的反编译器。汇编程序包含名字、宏、数据和指令形式的有用信息,在二进制程序或者可运行程序中是没有这些信息的,因此避免了在反编译器的语法分析阶段区分数据和指令的问题。

    又因为该反编译器的输出是1960年代的标准编程语言Fortran程序(第二代、第三代计算机上都在使用Fortran),所以使得它看起来更具有实用意义。该反编译器面向的是涉及代数运算的工程应用程序,使用者需要掌握一定的相关知识,并能够为子程序的识别自定义规则。在熟练的程序员干预下,该反编译器的正确率可以达到90%,因此它是属于少数人的“阳春白雪”。

    3)Lockheed Neliac——开山祖师的传人

    1967年,洛克希德导弹与空间公司在海军电子实验室开发的Neliac编译器上做了一些增强,我们称它为Lockheed Neliac。

    反编译器LockheedNeliac与D-Neliac类似,它们都可将机器代码程序转换成Neliac程序代码,特别是它们可以将非Neliac语言生成的机器代码转换为Neliac程序代码。这一时期的反编译器采用模式匹配的方法进行反编译,把许多复杂的问题留给程序员手工解决。

    4)小结——De-compiler的拓荒者们

    整个60年代,反编译方面的研究主要集中在研制专门用途的反编译器上,并希望其可以作为软件移植的工具来使用。但是受限于当时计算机发展水平,以及体系结构的影响,这一时期的反编译器主要采用模式匹配的方法进行反编译,需要较多的人工干预;并且反编译的结果通常不经过优化处理,所以输出的结果代码效率较低、可读性较差。

    从前边的叙述中可以看出,尽管从编译器被发明以来,人们就对编译的逆过程倍感兴趣,但真正迈出这关键的一步却是由于进行“软件移植”的诉求。那个年代的计算机程序停留在大型商业公司和高等院校的实验室里,只有很少的人能接触和掌握高级语言的编程,程序的复杂程度也较为有限,也没有大量出现病毒,因此利用反编译进行程序分析并没有那么重要。

    2.发展——20世纪70年代

    反编译技术建立初期,并没有很快成为通用的商业软件流行起来。大学校园的理论研究,成为推动这项技术发展的主要动力。下面我们按照时间的脉络,走进历史进程中的“象牙塔”,回顾一下反编译技术的发展过程。反编译理论方面的研究成为这个时期的热门,随着美国多位博士以反编译作为博士研究课题,一些对逆向编译和程序移植有一定影响的理论和技术被相继提出。在这个研究领域,豁然呈现出百花齐放的景象。

    1)花开一朵——博士们的研究

    1973年,DoctorHollander首次针对反编译方式生成的代码,使用控制流与数据流分析相结合的技术手段来进行优化。此外,他还基于元语言描述定义了一个反编译过程的五级模型,并且实现了从IBM System360汇编子集到类ALGOL语言的反编译。该反编译器虽然引入了一些新的技术,即综合利用数据流和控制流分析技术来改善反编译器的输出代码,并使用形式化方法来分析代码,但其核心依然是构筑在模式匹配技术基础之上。

    几乎在同时,DoctorHousel的博士论文对反编译进行了较系统的论述,文中描述了一种可行的反编译方法,并通过实验验证了部分理论。Housel的反编译方法借用编译器、图、和优化理论的概念,并据此设计了一种包括部分汇编、分析器、代码生成等三个主要步骤的反编译器。然而受限于当时实验平台和目标程序,Housel仅仅测试了6个程序。实验中,有88%的指令可以通过反编译器自动生成,剩余的指令则需要程序员进行手工干预。这个反编译器证明,通过使用已知的编译器和图的方法,可以实现生成良好高级代码的反编译器。中间表示法的使用使得分析完全不依赖机器。这个方法学的主要缺陷在于源语言的选择,MIX汇编语言,在这些程序中不仅带有大量可用信息,而且它是一个简单化的、非现实的汇编语言。

    1974年,DoctorFriedman在他的博士学位论文中描述了一个反编译器,用于在相同体系结构等级内的小型计算机操作系统的迁移。该编译器包含四个主要部分:前期处理器、反编译器、代码生成器、和编译器,它是Housel反编译器的一个改写版。Friedman在反编译操作系统代码的方向上迈出了第一步,而且它例证了在反编译机器依赖的代码时反编译器面对的困难。不足的是,该迁移系统对输入程序有所要求,即需要对输入程序做大量格式化工作;同时,该系统最后产生的程序代码具有较大的空间膨胀率,而代码膨胀率高又带来了执行时间和效率的低下。

    1978年,DoctorHopwood所做的工作实现了从汇编语言程序到MOL620语言程序的翻译功能。他引入了控制流图的概念,即指定一条指令作为控制流图的一个节点。与现在广为采用的以基本块为节点的方式相比,Hopwood的方案对内存的要求会更高一些。Hopwood的博士学位论文描述了有关其设计的一个包含七个步骤的反编译器的内容,他的研究的主要缺点是控制流向图的粒度和在最后的目标程序中寄存器的使用。其中控制流向图的粒度的使用,导致该反编译器处理大规模程序的时候开销太大;而在其所生成的目标高级语言代码中使用了寄存器,导致反编译结果并非纯正的高级代码。

    2)花开二朵——反编译技术在工程上的应用

    20世纪70年代的十年是反编译技术发展的一个黄金时期,当时的反编译器并未局限在对高级编程语言的恢复上,而是引入了“翻译”的特征。在这个时期,除了一些以理论研究为主的反编译器模型被提出以外,还有一些具有代表性的实用系统被开发出来。

    1974年,由Barbe开发的Piler系统是第一个实现的X型通用反编译器架构,它的设计目标是实现从多种机器级代码到与其各自对应的高级语言程序的反编译。但是这种多源到多目标的反编译实现起来具有极高的难度,直接导致Piler系统最终实现时,仅能支持从通用公司的Honeywell 600机器代码到Fortran和COBOL两种高级语言程序的反编译。可见,当时的反编译器如果能够实现对“翻译”输出的高级语言再次编译,并且编译后程序的运行结果与反编译前一致的话,就几乎相当于一个二进制翻译器了。

    3)花开三朵——反编译技术在军事上的应用

    反编译技术同样被军方慧眼识珠,在上世纪70年代多项军事应用中可以看到它的身影。

    1974年,Ultrasystems公司的一个反编译工程中也用到了反编译器。这个反编译器作为三叉戟 (Trident)潜艇射击控制软件系统的一个文档编写工具。它以Trident汇编程序作为输入,产生这个公司开发的Trident高级语言程序。该编译器分成四个主要阶段:规格化、分析、表达式凝聚和代码生成。该系统的输入为经过“规格化预处理”的汇编程序,其目的是为了解决部分指令和数据的区分问题;与此同时,预处理过程还会生成一种中间表示,并对数据进行分析;然后,在表达式凝聚的过程期间,算术表达式和逻辑表达式将被还原并建立;最后,再通过和THLL(Ultra systems公司的名为Trident的高级语言)匹配控制结构,而生成输出的高级语言程序。

    1978年,D.A.Workman主导了一项有军方背景的反编译应用研究,目的是为美国军方实时训练装置系统设计适用的高级语言。该应用在F4型教练机的相关设计中发挥了作用。F4教练机的操作系统是用汇编语言编写的,因此这个反编译器的输入语言是汇编语言。由于这项应用的目标是用于设计,因此没有确定输出语言,没有实现代码生成,仅仅实现了反编译器的两个阶段:阶段一,把汇编程序映射为一个中间语言并收集关于源程序的统计信息;阶段二,产生基本块的控制流向图,依据它们的可能类型来划分指令,并且分析控制流以确定高级控制结构。这项成果的贡献在于,提出了一种在当时看起来十分独特的反编译技术应用。即这个反编译器,并未以输出高级语言代码为最终目的,而是通过把指令分类来进行数据分析。从这一案例,可以看出反编译技术的先进性在当时得到了美国军方的认可,并且在实际应用中催生出了代码分析的功能,值得后续研究的借鉴。

    4)小结

    有了1960年代的技术积累,反编译技术在高等院校得到了理论和实践的双重推进。在理论研究的支撑下,越来越多的实用系统中都使用了反编译技术。以至于被大家公认的高科技技术集散地的美国军方,也将反编译技术投入到军事训练和实战中。因此,在1970年代反编译技术拥有自己完美的发展期,并获得了长足的进步。

    3.瓶颈期——20世纪80年代

    之所以将1980年代称为反编译发展的瓶颈期,主要是这项技术所能实现的功能的合法性问题。毕竟随着计算机的普及和发展,软件知识产权逐步被人们所重视。反编译技术可以逆向获得程序源代码的特性,与软件知识产权的保护存在着一定的矛盾。如何界定科学研究和非法获利,一时没有定论,但是这个十年中,相关研究也没有完全停滞,仍然有一些具有代表性的工作。

    1) Zebra

    1981年,美国军方的另一个反编译实例:美国海军水下系统中心开发的Zebra样机试图实现汇编程序的可移植性。Zebra的主要功能是把ULTRA/32汇编语言的一个名叫AN/UYK-7的子集作为输入语言,进而产生PDP-11/70的汇编程序输出。尽管Zebra并不是传统意义的反编译器,更像是单纯的程序移植和变换,但是该系统的实现方式与反编译并没有什么不同,即Zebra的实现主要由三大步骤构成。第一阶段,词汇和流分析:对原程序进行解析,并在基本块内做控制流分析;第二阶段,程序被翻译为中间形式;第三阶段,做中间表示的化简。

    Zebra利用已知的技术来开发一个汇编程序的反编译器,整个研发过程并没有引入新的概念。但是Zebra提出一个观点值得我们回味,也就是说:从Zebra的研发过程中看出,反编译应该作为一个工具帮助解决某个问题,而不是完全解决该问题的工具。这个结论,源于科研人员对反编译的了解而提出的假设,即假如反编译器不可能达到100%正确。虽然这是一个上世纪80年代初就提出的论断,但我们仍然可以从中一窥反编译发展至今的主要作用——程序分析(相关的讨论,我们放到相应的章节来具体讨论)。

    2)Forth Decompiler

    1982到1984年,Forth Decompiler系统具有一定的代表性。它是一种可以通过递归扫描Forth语言编译字典条目,而把单词反编译成原语和地址的一个工具。但是Forth Decompiler并不是一个纯正的反编译器,它更像是一个逆语法分析工具,该工具递归地扫描一个字典表并且返回与给定单词有关的原语或地址。

    3)STS(SoftwareTransport System)

    1985年,C.W. Yoo介绍了软件传输系统STS (SoftwareTransport System),实现汇编代码从一机器到另一机器的自动转换。STS的转换思路是:将机器m1的汇编代码反编译成高级语言程序,然后将获得的程序在机器m2上编译成新的汇编代码。一个实验型的STS系统是针对Z-80处理器而研发的C语言交叉编译器,但是由于STS系统缺少数据类型信息导致此项目搁浅。

    4)Decomp

    1988年,Reuter编写了一套反编译器,并命名为Decomp,它是一种专用于Vax BSD 4.2机器的反编译器。Decomp需要带有符号信息的目标文件作为反编译的输入,而通过反编译生成类C源码程序,部分输出的C源码经过手工编辑后可以被再次编译。Decomp做了一件今天看起来十分有趣的事情,也就是它为了一款游戏而生,它在没有可用源代码的情况下把帝国游戏(Empire)移植到VMS环境。这件事情与笔者目前从事的二进制翻译相关研究非常类似,即实现了应用程序级别的移植,并以游戏这种生动的形式加以展示。

    Decomp反编译器在当时的条件下,花费了大概5人月的工作量,并且可以从因特网上免费获取它。昆士兰大学的Cristina Cifuentes在她的博士论文中,成功地重现了Decomp的反编译过程。从实验中可以看出,Decomp反编译生成的程序有正确的控制结构、正确的变量数据类型、库例程和子过程的名字,甚至用户程序入口点也得到了还原。当然上述功能的取得,都需要满足一定的先决条件,但仅从功能上来看,Decomp是一个又实用价值的反编译器。

    5)小结

    经过20年的技术积累,1980年代本来应该成为反编译技术的爆发期,但是由于它天生的逆向属性,导致其与软件知识产权的保护产生了矛盾。在法律监管的空白时间里,并没有产生一些让我们记忆犹新的优秀系统和应用。整个1980年代的研究延续了不温不火的态势,但是对反编译完备性的讨论和实用化的驱使,仍然使得这个方向的研究延续下来。这个10年的研究比1970年代更注重实用性,并从专用这个角度加以体现。

    4.反编译的春天——20世纪90年代

    1990年代,反编译技术作为一个主体终于有了可以依据的法律——许多国家针对软件逆向工程进行立法,以规范该领域的研究工作。从一篇美国研究者Pamela Samuelson的文章“Reverse-engineering SomeoneElse's Software: Is It Legal?”中,可以重现当时美国对“反编译”这一类技术的法律定义:根据美国联邦法律,对拥有版权的软件进行逆向工程操作,例如反汇编、反编译,若其目的不是通过剖析原软件,来研制新产品与之竟争,所进行的逆向操作是合法的。仔细品味这句话可知,只要是非盈利性的软件分析和源代码获取是被允许的。在上述背景下,反编译技术迎来了发展的春天,一批国家层面的综合性研究项目代表了反编译在当时的地位,比如:由11个欧洲工业和学术组织合作研究的REDO计划,主要是以调查研究软件的维护、有效性和软件系统文档化为目标。他们在软件逆向工程研究主题下对反编译进行了大量研究,从逻辑语义上给出反编译的一些实现方法和本质描述,并将其结果应用于英国核工业部。既然春天来了,除了上述枝叶返青的参天大树,哪能没有百花齐放呢?我们再把1990年代的反编译发展脉络梳理一下。

    此外,在这个十年中,反编译这项技术与另外一项称作“二进制翻译”的技术结合的越来越紧密。反编译技术作为二进制翻译的一种重要实现方式,我们将在后文详细介绍二者的联系和区别,同时也会花一定篇幅,着重揭开一下能够体现反编译技术实用性的“二进制翻译”的神秘面纱。

    1) Exe2c

    1990年,由AustinCode Works公司推出的实验项目Exe2c可以将Intel80286/DOS可执行程序反汇编,并转换为内部格式代码,最终转换成C程序。从Exe2c的输出代码看出,它并没有实现数据流分析,而仅仅实现了部分控制流分析。C语言使用的一些控制结构被恢复,如:if-then和循环。它生成的C语言程序的大小是汇编程序的3倍。这个反编译器的积极意义在于,它是在过去的若干年中第一个尝试反编译可运行文件的反编译器。其成果表明,为了产生更好的C代码需要引入一个较为完善的数据流分析和启发式功能。而且,建立一个忽略所有由编译器引进的外来代码和发现库子程序的机制会很有帮助。这一点可以大大降低反编译的工作量,同时提升反编译输出的可用性。

    2) PLM-80 Decompiler

    1991年研发的PLM-80Decompiler反编译器也是一款具有国家支持和军事应用背景的软件,它是澳大利亚国防部的信息技术司研究的一个反编译的国防应用,也是在“反编译的春天”里值得一提的一项研究。PLM-80Decompiler研发的主要目的是针对废弃代码的维护、具有科技情报产品的分析、以及针对信息系统的安全和保密风险的评估,其中除了第一点以外,其它的目的都与反编译在当今时代的需求所契合,可见该项目在当时是具有前瞻意义的一项研究。

    虽然研发目标具有重要意义,但最终由于技术实现的难度,PLM-80Decompiler只实现了一个样机。该样机是用Prolog语言编写的,针对特定机器PLM-80编译器编译的Intel 8085汇编程序,可以产生一种称作“Small-C语言”的目标程序(Small-C代表所生成的代码是标准C语言的子集)。从公开可以查阅的文献中,可以了解到PLM-80Decompiler可以从输入的汇编程序中识别出部分if..then和while()等简单结构,可以还原一些int和char等简单的数据类型,以及一些全局和局部变量。除此之外,PLM-80Decompiler还设计了一个图形化用户界面用于显示汇编程序和伪C程序,并且用户还可以通过图形界面编辑变量的名字、增加注解,以及支持手工确定主程序的入口点等功能。

    总的来说,PLM-80Decompiler所做的分析局限于控制结构和简单数据类型的识别,并没有引入针对寄存器使用的分析。同时,该反编译器也不支持分析编译器生成的优化代码。但值得称道的是,PLM-80Decompiler对图形界面的引入,是对用户体验的一次提升,也是对反编译这种需要人工反馈参与工作的一种新的支持手段。

    3) 8086 C Decompiling System

    1991年推出的8086C Decompiling System是一个将Intel 8086/DOS可执行程序翻译成C程序的反编译器。它实现了库函数的识别以减少生成代码的量,同时它基于规则识别出了数组和结构体的指针等数据类型。不出意外的是,这个反编译器同样对输入文件有特殊的要求——输入文件必须是由Microsoft C V5.0版本小存储器模型编译所生成的。这一点再一次印证了:一个反编译器的可用性受限于它对源编译器的依赖。多数反编译器只能针对特定的编译器类型(或者编译器版本)完成正确的反编译动作。

    8086 C Decompiling System描述了五个阶段:库函数的识别、符号执行、数据类型识别、程序转换和C语言代码生成。

    该系统在库函数识别阶段所做的工作具有一定代表性,很多反编译器和后来的二进制翻译器都采用类似的方法。有必要单独说明一下:8086 C DecompilingSystem主要实现了对Microsoft C库函数的识别,用来区分哪些是系统调用的库函数,哪些是用户自己编写的函数。这么做的目的是为了在反编译时只处理用户函数,生成相应的C代码,而所有库函数则不必被反编译。识别库函数是通过模板匹配的形式完成,即预先构造一个所有C语言的库函数表,包含一些特殊信息,这部分工作是反编译器作者手工实施的。

    除了库函数识别阶段以外,该反编译器其余阶段的实施中规中矩。它的符号执行是将机器指令完全用特有符号来表示,形成一套中间指令;而对数据类型的识别则是通过两套规则配合来实现的,即首先通过一组规则对于不同数据类型进行信息收集,然后再根据所收集的信息和另外一组分析规则共同确定数据类型;程序转换则把存储计算转变成各种地址表达式,例如数组寻址;最后,C语言代码生成器通过识别控制结构,继而转换成相应的程序结构,并且生成C语言代码。

    8086 C Decompiling System是由我国合肥工业微机所科研人员开发的一套较早的反编译系统,代表了当时我国的反编译研究的方向和水平。

    4) Alpha AXP Migration Tools

    数字装备公司(Digital Equipment Corporation)在设计Alpha AXP体系结构的时候,需要能够在“新”的Alpha AXP计算机上运行“现有”的VAX和MIPS代码。正是由于这个动议,使得Alpha AXP MigrationTools作为一套可以完成上述功能的二进制翻译工具被开发出来。Alpha AXPMigration Tools可以实现旧体系结构的指令序列转换成新体系结构的指令序列,即实现不同体系结构间二进制级代码的无缝移植。这个移植过程中被开发者定义成两个部分,分别是:二进制翻译过程和运行时环境。为了保证二进制翻译过程的全自动执行,同时能够实现执行期间创建或修改代码的功能,该移植工具在二进制翻译部分使用了反编译技术。

    Alpha AXP Migration Tools中反编译技术的应用,主要体现在机器指令的潜在含义理解和分析上。例如:原体系结构上的条件码分析,以便后续翻译过程中可以转化为Alpha体系结构上的相应操作;通过代码分析,确定函数的返回值或者发现代码中的错误;MIPS中标准库例程的发现和定位,以减少代码翻译的工作量,因为库例程绝大多数情况下是可以在新体系架构中找到类似库函数实现其功能的;发现代码中的“成语”(可以理解为在特定体系结构上,完成特定功能的一组指令序列),并使用目标体系结构中功能等价的指令组合来实现该“成语”的功能。通过上述一系列的分析工作,以及其他翻译工作,最终以AXP操作码的形式组成翻译后的二进制编码,并由运行时环境执行翻译的代码。

    这个工程举例说明在一个现代翻译系统中反编译技术的使用。证明对于众多类别的二进制程序来说它是成功的。一些无法翻译的程序是在技术上不可翻译的程序,比如使用特权操作码的程序或者以超级用户特权运行的程序。

    5) 其它反编译器产品和研究

    在这一阶段还有众多公司纷纷推出自己的反编译器产品,具体情况如表所示。

    表1 20世纪90年代部分反编译器产品

    产品名称年份用途厂商
    Valkyrie1993用于 Clipper Summer '87 的可视化反编译器CodeWorks
    OutFox1993用于加密的FoxBASE+程序的反编译器不详
    ReFox1993用于反编译加密的FoxPro文件Xitech
    DOC1993用于 AS/400 和 System/38 的COBOL反编译器Harman Resources
    Uniclip1993用于 Clipper Summer '87 EXE 文件的反编译器Stro Ware
    Clipback1993用于Summer '87 可执行文件的反编译器Intelligent Information Systems
    Brillig1993用于 Clipper 5.X .exe文件和.obj文件的反编译器APTware

    同时也有一批大学的实验室,发表自己的试验系统,其中在这一领域Cifuentes博士的研究成果,成为以后反编译研究的主要参考方向。Cifuentes在自己的博士论文中指出,可以通过数据流分析识别参数和返回值,通过控制流分析将代码恢复成具有结构的C程序。研究型反编译器dcc展现了她的工作,但它只能处理很小的Intel 80286/DOS可执行程序。

    在dcc的基础上,反编译器REC(Reverse Engineering Compiler)基于Cifuentes的工作在几个方面进行了扩展,但是它生成的类C程序比较难读,因为包含了寄存器符号。它可以处理多个处理器(如:Intel 386、Motorola 68K)上运行的多种格式的可执行文件(如:ELF和Windows PE等)。像数组等复杂的数据类型保留为访问内存的表达式。

    5.持续的研究——进入21世纪

    时间荏苒,当历史的脚步进入新世纪,反编译的相关研究也随之更进一步,本节我们将用简单的笔触介绍2000年后的相关研究和商用产品。

    2001年,Guilfanov介绍了IDA Pro反汇编器使用的类型传播系统,并着重讲解了库函数的识别工作。IDA Pro利用库函数的签名信息来恢复库函数调用语句使用的参数的数据类型,然后使用类型传播技术处理赋值语句来进行数据类型恢复。上述事实说明,没有一种数据类型恢复不是根据库函数类型信息进行的。

    2002年,Morisada发布了处理32位Windows可执行程序的反编译器Anatomizer。对某些Windows可执行程序它表现的很出色,可以恢复参数和返回值,条件语句和switch语句也得到了很好的处理。当使用Anatomizer处理Cygwin程序时,库函数printf无法被恢复。另外,Anatomizer无法处理浮点指令和间接调用,数组仍然被保留为访问内存的表达式。当寄存器在某些过程体中未被定值而先使用时,它无法将其识别成参数。反编译器Anatomizer经常会异常终止。

    2002年,Tröger和Cifuentes给出一个分析间接调用指令的方法。如果由虚函数产生的间接调用被成功识别,那么关于此间接调用的诸多信息都会获得。然而,此方法受限于一个基本块的范围,导致无法处理所有的情况。

    2004年,RaimarFalke基于Mycroft的理论并进行扩展开发了反编译器Yadec,用于恢复数组数据类型。但需要一个相当于用户抉择的文件来处理冲突。

    2004年,由AndreyShulga编写的反编译器Andromeda一直没有公开发行,但从网站可以获得一个GUI程序对应反编译生成程序。生成程序给人的印象非常深刻,但不能仅凭一个反编译生成程序来断定反编译器的优劣,可能它恢复出的数据类型是经过手工编辑的。

    2007年,IlfakGuilfanov发布一个集成反汇编器IDA Pro的反编译器Hex-Rays,用来处理32位Windows可执行程序。反编译器Hex-Rays可以在窗口中展示反编译生成的类C代码,通过点击函数名跳到函数体视窗。所有函数的参数和返回值都得到了恢复,但作者声明反编译生成的程序仅用于阅读,不能对其进行编译。

    遗憾的是,2008年后国外与反编译紧密的相关的重要研究很难再被检索到。笔者分析,其主要原因是反编译本身的复杂性,不完备性,以及在逆向分析实践中不如反汇编实用的现实所造成的。此外,虚拟化技术的日渐成熟,也分化了相当一部分使用反编译形式进行二进制翻译的研究资源。

    6.身边的反编译——我国对反编译的研究

    国内从事反编译方面研究的团队较少,能够在公开报道中查证的有:从1984年开始,合肥工业大学微机所开展了一系列与反编译相关的研究工作:在国家自然科学基金的资助下,以Dual-68000为硬件平台,研制T 68000 C反编译系统;用手工的方法反编译了UNIX操作系统部分组件;七•五期间,他们还进行了8086 C语言反编译系统的研究;随后,他们还发布了商业化的反编译系统DECLER V1.0和V1.1。1991年发表的文献中提及,武汉大学从1986年起就开始研制VAX机上的C语言反编译系统。同年发表的另外一篇文献中提及,北京控制工程研究所在PC机上开发TC语言反编译系统。1992年,上海交通大学的科研人员也发表了关于VAX机器上C语言反编译系统研究与实现的论文。1994年哈尔滨工业大学的研发团队开发了一款基于Turbo C的小模式反编译系统。2001年,解放军信息大学开始研发ITA二进制翻译系统(历时五年),该系统可以实现将IA64/Lunix架构下由C语言编制的可执行程序反编译到SW/Lunix下执行。2006年,北京大学计算机科学研究所研发了汇编级别的分析工具BESTAR。该工具实现了Linux平台上的轻量级汇编代码结构化表示功能,它能够实现利用控制流和数据流分析技术识别通用控制结构。该工具还可以分析程序执行流,重构表达式和函数,发现数据依赖关系,将汇编代码转换成一个结构化、易理解的中间语言程序。

    当然前文还提到了8086 CDecompiling System也是国内非常重要的研究和工作,尤其8086 C Decompiling System还在Cifuentes的论文中被提及。

    最后 ,致谢 小楠楠,借鉴了他大段文字。经过博士论文撰写,发现你文笔水平大增啊!

    展开全文
  • app反编译

    千次阅读 2019-10-31 14:41:40
    在进行安卓开发或者爬虫开发过程中,偶尔会遇到需要将app进行反编译分析参考源码的需求,接下来,笔者将自己实践过程记录下来,給需要的朋友一个参考。仅供学习之用,勿做坏事儿,哈哈哈! 准备工作:确保电脑已经...

    在进行安卓开发或者爬虫开发过程中,偶尔会遇到需要将app进行反编译分析参考源码的需求,接下来,笔者将自己实践过程记录下来,給需要的朋友一个参考。仅供学习之用,勿做坏事儿,哈哈哈!

    准备工作:确保电脑已经配置好了java环境,最好是jdk1.8以上

    使用工具:

    apktool (作用:资源文件获取,可以提取出图片文件和布局文件进行使用查看)  下载地址:https://bitbucket.org/iBotPeaches/apktool/downloads/

    dex2jar(作用:将apk反编译成java源码(classes.dex转化成jar文件)) 下载地址:https://sourceforge.net/projects/dex2jar/files/

    jd-gui  (作用:查看APK中classes.dex转化成出的jar文件,即源码文件) 下载地址: http://java-decompiler.github.io/

    百度云盘下载地址:https://pan.baidu.com/s/1u7h1VT8WCW4vhQXpzq6png

    将下载好的工具放在指定目录,解压,如下图所示:

    1.用apktool反编译apk得到图片、XML配置、语言资源等文件

    1.1 使用cmd命令cd到工具所在的目录,例如

    cd C:\Users\lyl\Desktop\app反编译相关

    1.2 使用 apktool 反编译得到 图片、XML等静态资源

    java -jar [apktool_2.4.0.jar] d -f [apk地址] -o [输出的目录名称]

    例如下图所示,我这里需要反编译的app为非常准的app,名字为:feichangzhun_142.apk:

    执行成功之后,将会在指定的 fcz 目下生成如下图类似的文件,资源都在这里面:

    如果你想将反编译完的文件重新打包成apk,那你可以:

    java -jar [apktool_2.4.0.jar] b fcz (你编译出来文件夹)

    例如:

    java -jar apktool_2.4.0.jar b fcz

    之后在之前的fcz文件下便可以发现多了2个文件夹:

    build

    dist(里面存放着打包出来的APK文件)

    2.Apk反编译得到Java源代码

    将要反编译的APK后缀名改为.rar或则 .zip,并解压,得到其中的额classes.dex文件(它就是java文件编译再通过dx工具打包而成的),将获取到的 classes.dex放到之前解压出来的工具 dex2jar-0.0.9.13文件夹内,例如下图

    2.1 在命令行下定位到 dex2jar.bat所在目录,输入

    dex2jar.bat  classes.dex

    如图:

    在该目录下会生成一个 classes_dex2jar.jar 的文件,然后打开工具 jd-gui 文件夹里的 jd-gui.exe,之后用该工具打开之前生成的classes_dex2jar.jar文件,便可以看到源码了,效果如下:

    备注:如果要反编译的app是加了壳的话,需要脱壳,这里推荐有个大佬的文章地址可以参考一下:http://www.52bug.cn/cracktool/4794.html

    作者我这里这个app也是使用的360加壳过的,所以也需要进行脱壳处理,具体脱壳步骤将在下一篇文章进行记录

    3.签名

    在从新打包之后,需要进行重新签名,这样才能在手机上成功安装,这里需要下载 Auto-sign.zip 工具,我这里有整理一份以上传百度云盘,下载地址:https://pan.baidu.com/s/1JeA4MkS7BWdeQkSHLvUs1w

    将 Auto-sign.zip 解压,然后通过命令行 cd 到路径下,并且把要签名的app拷贝进去,例如我这里要签名的app为 飞常准.apk ,拷贝进去之后,目录结构如下图:

    在命令行使用此命令进行签名

    java -jar signapk.jar testkey.x509.pem testkey.pk8 飞常准.apk fcz.apk

    注意:这里的 fcz.apk 是指的签名成功之后,要生成的新的app名称

    执行成功之后,将会在当前目录生成已经签名好的新文件,如下图

    我这里遇到一个问题,就是我已经从新签名之后,并且把安装包发到手机上也成功安装了,但是打开运行app之后,会闪退,不不知道是否是我修改源码之后,修改出了问题,如有遇到同样问题的朋友,可以留言互相交流下喔!

    展开全文
  • Java| 编译和反编译

    万次阅读 2018-04-20 15:49:18
    什么是编程语言?... 在介绍编译和反编译之前,我们先来简单介绍下编程语言(Programming Language)。编程语言(Programming Language)分为低级语言(Low-level Language)和高级语言(High-level La...

    什么是编程语言?

    在介绍编译和反编译之前,我们先来简单介绍下编程语言(Programming Language)。编程语言(Programming Language)分为低级语言(Low-level Language)和高级语言(High-level Language)
    机器语言(Machine Language)和汇编语言(Assembly Language)属于低级语言,直接用计算机指令编写程序。
    而C、C++、Java、Python等属于高级语言,用语句(Statement)编写程序,语句是计算机指令的抽象表示。

    什么是编译?

    上面提到语言有两种,一种低级语言,一种高级语言。简单的理解:低级语言是计算机认识的语言、高级语言是程序员认识的语言。
    那么如何从高级语言转换成低级语言呢?这个过程其实就是编译


    将便于人编写、阅读、维护的高级计算机语言所写作的源代码程序,翻译为计算机能解读、运行的低阶机器语言的程序的过程就是编译。负责这一过程的处理的工具叫做编译器


    现在我们知道了什么是编译,也知道了什么是编译器。不同的语言都有自己的编译器,Java语言中负责编译的编译器是一个命令:javac


    当我们写完一个HelloWorld.java文件后,我们可以使用javac HelloWorld.java命令来生成HelloWorld.class文件,这个class类型的文件是JVM可以识别的文件。通常我们认为这个过程叫做Java语言的编译。其实,class文件仍然不是机器能够识别的语言,因为机器只能识别机器语言,还需要JVM再将这种class文件类型字节码转换成机器可以识别的机器语言。


    javac是收录于JDK中的Java语言编译器。该工具可以将后缀名为.java的源文件编译为后缀名为.class的可以运行于Java虚拟机的字节码。

    什么是反编译?

    反编译的过程与编译刚好相反,就是将已编译好的编程语言还原到未编译的状态,也就是找出程序语言的源代码。就是将机器看得懂的语言转换成程序员可以看得懂的语言。Java语言中的反编译一般指将class文件转换成java文件。


    有了反编译工具,我们可以做很多事情,最主要的功能就是有了反编译工具,我们就能读得懂Java编译器生成的字节码。比如我们就可以洞悉Java语法糖背后的原理。

    Java常用反编译工具

    本文主要介绍4个Java的反编译工具:javapjadcfr以及可视化反编译工具JD-GUI

    JAVAP

    javap是jdk自带的一个工具,可以对代码反编译,也可以查看java编译器生成的字节码。javap和其他两个反编译工具最大的区别是他生成的文件并不是java文件,也不像其他两个工具生成代码那样更容易理解。拿一段简单的代码举例,如我们想分析Java 7中的switch是如何支持String的,我们先有以下可以编译通过的源代码:

    public class switchDemoString {
        public static void main(String[] args) {
            String str = "world";
            switch (str) {
                case "hello":
                    System.out.println("hello");
                    break;
                case "world":
                    System.out.println("world");
                    break;
                default:
                    break;
            }
        }
    }
    

    执行以下两个命令:

    javac Decompilation.java
    javap -c Decompilation.class

    生成代码如下:

    Compiled from "Decompilation.java"
    public class Decompilation {
      public Decompilation();
        Code:
           0: aload_0
           1: invokespecial #8                  // Method java/lang/Object."<init>":()V
           4: return
    
      public static void main(java.lang.String[]);
        Code:
           0: ldc           #16                 // String world
           2: astore_1
           3: aload_1
           4: dup
           5: astore_2
           6: invokevirtual #18                 // Method java/lang/String.hashCode:()I
           9: lookupswitch  { // 2
                  99162322: 36
                 113318802: 48
                   default: 82
              }
          36: aload_2
          37: ldc           #24                 // String hello
          39: invokevirtual #26                 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
          42: ifne          60
          45: goto          82
          48: aload_2
          49: ldc           #16                 // String world
          51: invokevirtual #26                 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
          54: ifne          71
          57: goto          82
          60: getstatic     #30                 // Field java/lang/System.out:Ljava/io/PrintStream;
          63: ldc           #24                 // String hello
          65: invokevirtual #36                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
          68: goto          82
          71: getstatic     #30                 // Field java/lang/System.out:Ljava/io/PrintStream;
          74: ldc           #16                 // String world
          76: invokevirtual #36                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
          79: goto          82
          82: return
    }
    
    

    javap并没有将字节码反编译成java文件,而是生成了一种我们可以看得懂字节码。其实javap生成的文件仍然是字节码,只是程序员可以稍微看得懂一些。如果你对字节码有所掌握,还是可以看得懂以上的代码的。其实就是把String转成hashcode,然后进行比较。


    个人认为,一般情况下我们会用到javap命令的时候不多,一般只有在真的需要看字节码的时候才会用到。但是字节码中间暴露的东西是最全的,你肯定有机会用到,比如我在分析synchronized的原理的时候就有是用到javap。通过javap生成的字节码,我发现synchronized底层依赖了ACC_SYNCHRONIZED标记monitorentermonitorexit两个指令来实现同步。

    JAD

    JAD是一个比较不错的反编译工具,只要下载一个执行工具,就可以实现对class文件的反编译了。还是上面的源代码,使用jad反编译后内容如下:


    命令:jad.exe Decompilation.class 会生成一个Decompilation.jad的文件

    JAD反编译的结果如下:

    // Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
    // Jad home page: http://www.kpdus.com/jad.html
    // Decompiler options: packimports(3) 
    // Source File Name:   Decompilation.java
    
    package com.yveshe;
    
    import java.io.PrintStream;
    
    public class Decompilation
    {
    
        public Decompilation()
        {
        }
    
        public static void main(String args[])
        {
            String str = "world";
            String s;
            switch((s = str).hashCode())
            {
            default:
                break;
    
            case 99162322: 
                if(s.equals("hello"))
                    System.out.println("hello");
                break;
    
            case 113318802: 
                if(s.equals("world"))
                    System.out.println("world");
                break;
            }
        }
    }
    

    看上面的代码这不就是标准的java的源代码么。这个就很清楚的可以看到原来字符串的switch是通过equals()hashCode()方法来实现的。


    PS: 但是,由于JAD已经很久不更新了,在对Java7生成的字节码进行反编译时,偶尔会出现不支持的问题,在对Java 8的lambda表达式反编译时就彻底失败。

    CFR

    JAD很好用,但是无奈的是很久没更新了,所以只能用一款新的工具替代他,CFR是一个不错的选择,相比JAD来说,他的语法可能会稍微复杂一些,但是好在他可以用.


    CFR将反编译现代Java特性–Java 8 lambdas(Java和更早版本中的Java beta 103),已经反编译Java 7 String,但CFR是完全用Java 6编写的.

    我们使用CFR对刚刚的代码进行反编译。执行一下命令:
    java -jar cfr_0_125.jar Decompilation.class --decodestringswitch false
    得到以下错误的结果(死活是反编译失败~)

    /*
     * Decompiled with CFR 0_125.
     */
    package com.yveshe;
    
    public class Decompilation {
        /*
         * Exception decompiling
         */
        public static void main(String[] args) {
            // This method has failed to decompile.  When submitting a bug report, please provide this stack trace, and (if you hold appropriate legal rights) the relevant class file.
            // org.benf.cfr.reader.util.CannotPerformDecode: reachable test BLOCK was exited and re-entered.
            // org.benf.cfr.reader.bytecode.analysis.opgraph.op3rewriters.Misc.getFarthestReachableInRange(Misc.java:143)
            // org.benf.cfr.reader.bytecode.analysis.opgraph.op3rewriters.SwitchReplacer.examineSwitchContiguity(SwitchReplacer.java:385)
            // org.benf.cfr.reader.bytecode.analysis.opgraph.op3rewriters.SwitchReplacer.replaceRawSwitches(SwitchReplacer.java:65)
            // org.benf.cfr.reader.bytecode.CodeAnalyser.getAnalysisInner(CodeAnalyser.java:394)
            // org.benf.cfr.reader.bytecode.CodeAnalyser.getAnalysisOrWrapFail(CodeAnalyser.java:191)
            // org.benf.cfr.reader.bytecode.CodeAnalyser.getAnalysis(CodeAnalyser.java:136)
            // org.benf.cfr.reader.entities.attributes.AttributeCode.analyse(AttributeCode.java:95)
            // org.benf.cfr.reader.entities.Method.analyse(Method.java:369)
            // org.benf.cfr.reader.entities.ClassFile.analyseMid(ClassFile.java:770)
            // org.benf.cfr.reader.entities.ClassFile.analyseTop(ClassFile.java:702)
            // org.benf.cfr.reader.Main.doClass(Main.java:46)
            // org.benf.cfr.reader.Main.main(Main.java:191)
            throw new IllegalStateException("Decompilation failed");
        }
    }
    

    中间出了一个小插曲,就是始终反编译失败,由于博主偷懒每次都是用的Eclipse的自动编译生成的class文件,没有通过javac命令你来生成class文件,导致之前存在问题的java文件编译成了class文件而一直么有更新…害死人啊,建议大家手动通过javac Decompilation.java命令来编译生成Decompilation.class文件,再做测试.

    成功的反编译结果如下:

    /*
     * Decompiled with CFR 0_125.
     */
    package com.yveshe;
    
    import java.io.PrintStream;
    
    public class Decompilation {
        public static void main(String[] args) {
            String str;
            String s = str = "world";
            switch (s.hashCode()) {
                default: {
                    break;
                }
                case 99162322: {
                    if (!s.equals("hello")) break;
                    System.out.println("hello");
                    break;
                }
                case 113318802: {
                    if (!s.equals("world")) break;
                    System.out.println("world");
                }
            }
        }
    }
    

    相比Jad来说,CFR有很多参数,还是刚刚的代码,如果我们使用以下命令,输出结果就会不同:
    E:\CRF>java -jar cfr_0_125.jar Decompilation.class

    /*
     * Decompiled with CFR 0_125.
     */
    package com.yveshe;
    
    import java.io.PrintStream;
    
    public class Decompilation {
        public static void main(String[] args) {
            String str;
            String s = str = "world";
            switch (s.hashCode()) {
                default: {
                    break;
                }
                case 99162322: {
                    if (!s.equals("hello")) break;
                    System.out.println("hello");
                    break;
                }
                case 113318802: {
                    if (!s.equals("world")) break;
                    System.out.println("world");
                }
            }
        }
    }
    

    --decodestringswitch表示对于switch支持string的细节进行解码。

    类似的还有--decodeenumswitch--decodefinally--decodelambdas等。

    --decodelambdas可以对lambda表达式进行反编译。


    CFR还有很多其他参数,均用于不同场景,读者可以使用java -jar cfr_0_125.jar --help进行了解。这里不逐一介绍了。

    JD-GUI

    JD-GUI 是一个用 C++ 开发的 Java反编译工具,由 Pavel Kouznetsov开发,支持Windows、Linux和苹果Mac Os三个平台。而且提供了Eclipse平台下的插件JD-Eclipse。JD-GUI 基于GPLv3开源协议,对个人使用是完全免费的。JD-GUI主要的是提供了可视化操作,直接拖拽文件到窗口既可,效果图如下
    这里写图片描述

    JadClipse

    在Eclipse中安装Jad插件,注意这里是安装的是Jad插件不是Jd插件~
    所需要资源: net.sf.jadclipse_3.3.0.jar插件jar和JAD.exe反编译软件(在文末有下载地址)


    JadClipse下载地址在官网下载插件的jar包,然后将jar包放到eclipse的plugins目录下;在打开Eclipse,Eclipse->Window->Preferences->Java,此时你会发现会比原来多了一个JadClipse的选项如下图配置JadClipse:
    这里写图片描述
    这里写图片描述
    基本配置完毕后,我们可以设置一下class文件的默认打开方式:

    Eclipse->Window->Preferences->General->Editors->File Associations 我们可以看到class文件的打开方式有两个,这里设置JadClipse和Eclipse自带的Class File Viewer,而JadClipse是默认的。 全部配置完成,下面我们可以查看源码了,选择需要查看的类,按F3即可查看源码.如果JadClipse不是默认设置,设置成默认设置既可.

    PS: 该方式好像不能正常工作了(2019/4/2)更新,可以使用安装jd插件jd-eclipse-site-1.0.0-RC2.zip下载地址 http://jd.benow.ca/ ,参考Eclipse中安装SVN插件(离线安装)方式安装.

    如何防止反编译?

    由于我们有工具可以对Class文件进行反编译,所以,对开发人员来说,如何保护Java程序就变成了一个非常重要的挑战。但是,魔高一尺、道高一丈。当然有对应的技术可以应对反编译咯。但是,这里还是要说明一点,和网络安全的防护一样,无论做出多少努力,其实都只是提高攻击者的成本而已。无法彻底防治。
    典型的应对策略有以下几种:
    ● 隔离Java程序
    ○ 让用户接触不到你的Class文件
    ● 对Class文件进行加密
    ○ 提到破解难度
    ● 代码混淆
    ○ 将代码转换成功能上等价,但是难于阅读和理解的形式


    比如: 用很复杂的算法加密 class文件,然后在虚拟机载入前调用解密程序。考虑使用jvmti,这样可以防止class loader被反编译导致加解密算法泄漏.

    相关资源

    在线反编译:
    http://www.javadecompilers.com/ (支持选择多种反编译器)
    http://javare.cn/


    资源下载:
    https://varaneckas.com/jad/ (JAD支持各种平台)
    http://jd.benow.ca/ (JD相关)
    https://baike.xsoftlab.net/view/264.html (JD-GUI)
    http://www.benf.org/other/cfr/ (CFR)
    http://jadclipse.sourceforge.net/wiki/index.php/Main_Page (JadClipse:Eclipse插件,也可以通过配置外部的Jad来在Eclipse中实现反编译)


    反编译软件(JAD,JadClipse,JD-GUI,CRF)打包下载


    参考链接:
    http://www.admin10000.com/document/5064.html (7款开源Java反编译工具:)
    https://blog.csdn.net/chenchunlin526/article/details/78259682 (反编译工具对比)
    http://53873039oycg.iteye.com/blog/2015192(工具CFR,Procyon简介:)

    展开全文
  • 在线反编译网站

    万次阅读 2018-10-16 17:05:21
    http://javare.cn/ 还有一种方法:idea编辑器自己就能查看.class文件
  • 编译与反编译

    千次阅读 2019-08-11 22:44:02
    代码从预处理,编译,汇编,链接,最终形成文件,C语言作为编译语言,可以准确定义在不同情况下所采取的行动。 程序的执行过程 预处理: 头文件展开,宏替换,去掉注释 test.i 编译: 生成汇编码 词法和语法的检查 ...
  • 反编译

    2020-07-30 16:58:15
    什么是编译 将高级语言(JAVA、C、C++等)转换成低级语言(汇编语言、机器语言)的过程...1、使用命令行的方式:java -jar CFR的安装路径 想要反编译文件的路径 [–反编译后文件的保存路径] 2、另外可以使用 java -jar
  • 首先呢,1024,大家程序员节快乐~ ...那么只有去学习别人的做法,这就不得不用到反编译,包括后面进了第二家手游公司,也需要做一些逆向工作。积累了一些东西,总觉得整理一下才比较安心。 感觉基本上把能用到的...
  • 反编译系列教程

    千次阅读 2018-12-11 23:29:57
    反编译技术更需要从事者具有深厚的编译技术基础,因此一直是很多业内人士希望能够深入了解和掌握的一门技术。 从现在开始,我们讨论反向编译的一些内容。顾名思义,反编译可以认为是编译的逆过程,这...
  • 转:https://blog.csdn.net/kongwei521/article/details/54927689在项目开发过程中,估计也有人和我遇到过同样的经历:运行环境出现了重大Bug亟需解决、或者由于电脑挂了、旧代码覆盖新代码,而在这种情况下,我们不...
  • 我们都知道,Android程序打完包之后得到的是一个APK文件,这个文件是可以直接安装到任何Android手机上的,我们反编译其实也就是对这个APK文件进行反编译。Android的反编译主要又分为两个部分,一个是对代码的反编译...
  • 如何实现反编译一个APP

    万次阅读 2018-03-31 10:02:53
    前言: 开始反编译之前,我们要知道有三个工具,分别是apktool,dex2jar,jd-gui,其中apktool是用来反编译资源文件和注册清单这些资源的,dex2jar和jd-gui用来做java代码的反编译反编译之前提醒大家以上工具尽量去...
  • Android反编译工具包(升级)官方绿色版

    万次下载 热门讨论 2012-10-10 19:18:30
    Android反编译工具包,内含图形和命令两种反编译方式,命令支持windows和linux平台,亲测验证成功!详见博客:Android APK反编译详解(附图) http://blog.csdn.net/sunboy_2050/article/details/6727581
  • android反编译工具(dex2jar,apk2java)

    千次下载 热门讨论 2011-08-28 22:30:54
    Android APK反编译得到Java源代码和资源文件的工具 反编译apk生成程序的源代码和图片、XML配置、语言资源等文件的工具
  • Android 反编译整理

    千次阅读 2019-06-14 11:14:12
    Android 反编译需要用到以下几个工具: Apktool: 这个工具的作用是: It is a tool for reverse engineering 3rd party, closed, binary Android apps. It can decode resources to nearly original form and ...
  • 本文的核心内容是,反编译其他apk,新增页面且不使用动态布局,完全使用开发习惯的xml包括shape 新增图片,一不替换已经存在的R.xxx,二不需要在反编译的apk public.xml中手动注册id,所以核心就是无视public.xml(R...
  • Android APK反编译详解(附图)

    万次阅读 多人点赞 2011-08-28 22:42:11
    这段时间在学Android应用开发,在想既然是用Java开发的应该很好反编译从而得到源代码吧,google了一下,确实很简单,...本文Android反编译教程,测试环境:Win7 Ultimate x64Ubuntu 12.04 x86_x64反编译工具包 下载
  • Android 反编译

    千次阅读 2016-11-08 10:39:28
    前言:作为开发者,我们反编译的目的是查看别人优秀的代码,而不是破解别人的代码,恶意修改,植入广告,获取利益。目前已经有很多APP被反编译破解了,什么保卫萝卜,等等。对原开发者,和用户都造成利益上的损失。 ...
  • android反编译

    2017-07-18 16:43:05
    感觉这篇对反编译还是讲解得相当清楚的,关于最后一提到的爱加密以后还是可以研究一下的。 1.11 反编译APK获取代码&资源 分类 Android 基础入门教程 本节引言 "反编译Apk",看上去好像好像很高端的样子,...
  • 绝对完整的Android反编译工具 使用Android反编译工具以前得选安装java环境。
  • apktool 反编译工具 绿色版

    万次下载 热门讨论 2014-03-11 20:18:37
    apktool功能:反编译出apk资源文件。 使用方式: 把apktool 解压到任意位置 执行 在dos 改目录下 执行 apktool d xxx.apk test ,便会把编译后的资源存入test文件夹下。
  • Android 反编译工具汇总

    千次下载 热门讨论 2017-09-06 16:38:34
    Android反编译工具(主要有 apktool,dex2jar, jd-gui ) 详细地址:http://blog.csdn.net/xcc1234/article/details/77868174
  • Android 反编译APK + 工具+教程;Android 反编译APK + 工具+教程;Android 反编译APK + 工具+教程;
  • Android反编译工具

    千次阅读 2018-10-24 17:03:43
    可以反编译apk,也可以重新打包apk 下载地址:https://github.com/iBotPeaches/Apktool/releases brew安装:brew install apktool 文档:https://ibotpeaches.github.io/Apktool/documentati...
  • dex2jar-0.0.9.15,jd-gui-0.3.6.windows 两个工具的打包。
  • 所谓工欲善其事必先利其器 很好用的Android反编译 必备工具 所谓工欲善其事必先利其器 很好用的Android反编译 必备工具 所谓工欲善其事必先利其器 很好用的Android反编译 必备工具
  • Android反编译初探:MAC下的反编译

    千次阅读 2018-04-14 20:50:24
    前言:突然看见有关反编译的文章,便学习一下 一、工具: https://ibotpeaches.github.io/Apktool/ http://jd.benow.ca/ https://sourceforge.net/projects/dex2jar/ 分别是 apktool主要用户反编译和打包; ...
  • Android反编译for mac

    热门讨论 2013-11-21 15:22:55
    在mac 上实现android 反编译,拿到图片等资源、源代码等,学习神器。
  • 首先反编译别人的APK,主要是学习别人的实现逻辑,给自己一个思路。比较商业的APK也不会给你留下这个漏洞,一些核心的业务处理会在后台进行操作;本地的 APK 也会进行混淆加密等。 好了废话不多说,步入正题: 方法...
  • Android 反编译初探 应用是如何被注入广告的

    万次阅读 多人点赞 2016-12-05 08:54:30
    本文由我的微信公众号:鸿洋(hongyangAndroid)原创首发。...一、概述最近和朋友聊天,发现一些灰色产业链通过批量反编译市场上的apk,然后进行注入广告,再重新打包上渠道。我想大家都不希望自己家的产品或者自

空空如也

1 2 3 4 5 ... 20
收藏数 312,389
精华内容 124,955
关键字:

反编译