什么样的语言可以进行反编译

本文从知乎扒的,没扒图,感觉文字足以表述.中间加了一些注释,如需详情请移步原文.

概念介绍

要理解这个问题,先要看「正」编译的过程是怎样的。

  • 你有一个想法,这是一种人类自然语言可以表达出来的东西。你利用编程技能,把它「翻译」成你熟悉的一种编程语言这个过程叫做编程。
  • 你使用编译器(compiler)将它翻译成机器所能理解的语言:这个过程叫做编译。

编程和编译都是「信息丢失」的过程。比如你说,我有一组整数,我要把这些数排个序,然后轻车熟路地写了个冒泡排序。然而一定程度上,你的原始动机其实已经从代码里丢失了。
有经验的人可以一眼看出这段代码是在排序,而新手小明看到的只有一些 for 和 if 之类的东西。
如果是更复杂的功能,可能过一段时间你自己都看不懂自己当时是想干什么。从程序语言到机器语言的过程其实也是一样的。

这两个过程其实都是把「做什么」转换成「怎么做」的过程,转换完成之后,究竟一开始是要做什么,这个信息已经丢失了。
所谓「反编译」,其实就是找回这些丢失的信息的过程。从这个角度上来说,你阅读一段代码的过程,其实就是在将它「反编译」成自然语言。
如果要完美地反编译,那只存在一种可能,就是信息完全没有丢失——比如说你阅读的这段代码有充分的注释,或者它使用了一种你所知晓的模式(这也是为什么大家一再强调注释和设计模式的重要性)。

对于从机器语言到程序语言的反编译过程,也是一样。比如说有比反编译更低级(非贬义)的过程,叫做反汇编。
严格来说汇编语言也是一种编程语言,不过我们在这里把它和我们常说的高级编程语言(包括C语言)区分开。

这个步骤里,我在汇编和机器语言里使用的是双向实线箭头,因为它们是可以互相转换的。从汇编语言到机器语言的过程中没有丢失任何信息——因为两者的指令是一一对应的,因此反汇编可以轻松达成。这就是很多程序语言只能反汇编、不能(难以,下同)反编译的原因。

一般我们管这种语言叫「编译语言」,又称「原生语言」。代表有C、C++等。那为什么有的语言可以反编译呢?
这又要从机器语言说起。就像不同地域的人所用的语言不同一样,不同的机器说的语言也不尽相同。用行话说,叫「指令集不同」

比方说,你的电脑和你的手机,指令集通常是不一样的。一段程序要让不同的机器都能执行,只能分别翻译(编译)成相应的机器语言。
这个过程太麻烦了,于是人们想了个办法,搞出了一种叫解释语言的东西(此处未考证解释语言是否就是因此发明的,只是帮助理解)。

问题分析

解释语言有两种执行方式,这取决于执行端的「解释器」是如何工作的。

  • 一种是直接解释执行,中间就没有机器语言什么事情了,但这种方式效率很低。(不能发挥批处理以及指令流水线的优势,所以效率较低).
  • 先通过JIT编译的方式将源码翻译成机器语言,然后再执行,保证执行效率。JIT编译大致可以理解为「用到什么就编译什么」,这个过程常常是在执行过程中同步进行的。(php8中有这个东西,要注意理解).

现代的解释语言基本上都会采用第二种方式,,先通过JIT编译的方式翻译成机器语言,然后再执行,保证执行效率。「解释器」的英文interpreter,其实就是名词「翻译」的意思。
这好比你国外交部发了封文件(源码)到各国大使馆,再由大使馆的工作人员分别翻译成相应的语言,传达给目标国相关部门。
代表性的解释语言如Javascript,它要在不同机器的浏览器上都能正确执行,所以采用这种方式。
但是这样一来,程序代码就必须提供给每一台执行端机器了。
这可是泄密啊。对于防止泄密,最直接的方式自然是加密。(在浏览器中js文件是可以被爬取的,所以一些敏感功能的实现需要加密防止技术外泄.比如直播场景中的h5播放器代码.)

有锁就有钥匙,同时也有开锁术;有加密解密,也有相应的破解方式。这时候所谓的「反编译」,其实就是破解加密算法。这一点就不展开聊了。
后来,人们觉得解释语言执行得实在有点慢,于是又想了一个办法:把一些可以前期做掉的工作先做掉,只留着那些跟目标机器有关的工作,到时候再说。于是程序被处理成了一种叫做「中间语言」,或者叫「字节码」的东西这个过程一般也叫做编译

中间语言词汇少,比较精炼,执行起来也更快。这些语言一般也会用上JIT技术,进一步把中间语言编译成机器语言(而非解释执行),执行效率也就跟那些原生的编译语言不相上下了。这种语言代表性的有Java等。
程序语言可以编译成中间语言,反过来,中间语言也可以在一定程度上反编译成程序语言。这是因为采用这种编译方式的编程语言为了保证它们的高级特性(比如说反射),在编译的过程中保留了源程序的绝大部分信息,
只有很少的信息丢失;也正是因为丢失了这一部分信息,中间语言通常不能完美地反编译——最常见的就是反编译出来的程序中局部变量的名字都丢了,被替换成了由反编译器自动生成的名字。
但这样反编译出来的程序,结构和功能都是完备的,可读性也有一定的保障。一般来说,我们所说的可以反编译的程序都是指这样一类语言写就的程序。

中间语言可以被反编译;加密又会被破解,而且执行前还要解密,会带来额外的性能开销。有没有办法能让代码既能有效执行,又不被截获代码的人所利用呢?这时候人们从一些职业素养很差的程序员那里得到了启发,并且开发一个工具,唤作「混淆器」。
这样代码即使被反编译和解密了,别人看也看不懂,不小心还会被带到坑里去。代码毕竟是写给人看的,只是偶尔让机器跑一跑,所以没有可读性的代码是没有价值的

这种方法一出,广受好评,于是变成了一种非常普遍的做法。在中间代码和JIT的步骤,混淆通常会跟这些技术一起使用。

结论

  • 汇编语言编译得到binary可以直接进行反汇编. 没有信息丢失.
  • C语言等编译型语言的binary反编译难度较大. 逆向过程存在信息丢失
  • Java等解释型语言的反编译难度较上者低.逆向过程存在信息丢失

所以:很多程序语言只能反汇编、难以反编译.

原文地址

作者:hillin
链接:https://www.zhihu.com/question/21853681/answer/74134768
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

什么样的语言可以进行反编译相关推荐

  1. ultraedit反编译c语言,UltraEdit怎么反编译

    满意答案 nqshlv 2012.12.30 采纳率:44%    等级:11 已帮助:10349人 [1]解决方法:去网吧下载windows\system32下的全部dll文件打包 下载地址:thu ...

  2. 反编译与反汇编、C++编译过程,包括预编译--汇编--编译--链接

    参考:C/C++程序编译流程(预处理->编译->汇编->链接) - ProLyn - 博客园 反汇编和反编译的区别_代码小卒_新浪博客 反汇编与反编译: 汇编:是把汇编源程序转变为目 ...

  3. Java——编译与反编译

    ** 一.基础知识 ** 1.1 编程语言 在介绍编译和反编译之前,我们先来简单介绍下编程语言(Programming Language).编程语言(Programming Language)分为低级 ...

  4. Java开发必会的反编译知识

    转载自 Java开发必会的反编译知识 编程语言 在介绍编译和反编译之前,我们先来简单介绍下编程语言(Programming Language).编程语言(Programming Language)分为 ...

  5. java反编译工具_Java开发必会的反编译知识(附支持对Lambda进行反编译的工具)...

    我之前推送过Java代码的编译与反编译,其中简单的介绍了Java编译与反编译相关的知识,最近给GitChat写<深入分析Java语法糖>的时候,又用到了很多反编译相关的知识,遂发现哪篇文章 ...

  6. Java代码的编译与反编译那些事儿

    GitHub 2.5k Star 的Java工程师成神之路 ,不来了解一下吗? GitHub 2.5k Star 的Java工程师成神之路 ,真的不来了解一下吗? GitHub 2.5k Star 的 ...

  7. java编译和反编译

    Java开发必会的反编译知识(附支持对Lambda进行反编译的工具) (qq.com)https://mp.weixin.qq.com/s?__biz=MzI3NzE0NjcwMg==&mid ...

  8. Java 编译与反编译

    编程语言 在介绍编译和反编译之前,我们先来简单介绍下编程语言(Programming Language).编程语言(Programming Language)分为低级语言(Low-level Lang ...

  9. Java 编译和反编译

    什么是编译 编译: 将高级语言翻译成汇编语言或机器语言的过程 Java语言中的编译一般指将Java文件转换成class文件 顾名思义反编译就是编译的逆向过程 反编译: 将汇编语言或机器语言反编译成高级 ...

最新文章

  1. “臭名昭著”的他们终于被裁了!字节宣布将精简HR团队,网友:业界毒瘤!...
  2. [SOJ] 简单哈希
  3. 云服务双十一大促,最后选手阿里云上场!没有让等到最后的用户失望!
  4. Expected more than 1 value per channel when training, got input size torch.Size
  5. Winform控件-DevExpress18下载安装注册以及在VS中使用
  6. Sci-Hub和 Alexandra 的基本信息
  7. 暴走英雄坛html5游戏在线玩,暴走英雄坛h5
  8. [转] Silverlight Navigation(多页面切换、传值)
  9. 小林求职记(三)一上来就围绕电商系统层层提问,我太难了....
  10. java中的文件操作:读取写入byte[]字节流、string字符串、list列表
  11. Windows Phone开发(14):数据模板 转:http://blog.csdn.net/tcjiaan/article/details/7350849...
  12. java一卡通实例代码_java写的简单校园卡管理系统 校园一卡通 - 下载 - 搜珍网
  13. P4与5G UPF实践
  14. 不用花钱,让你百度网盘满速下载的神器!简单实用教程
  15. WIN10外接显示器有妙招
  16. 2017年下半年梦想板
  17. 淘宝logo设计遇到的坑
  18. python getch_macOS 下的 getch()
  19. cannal 启动异常(show master status‘ has an error pls check. you need (at least one of) the SUPER,REPLI)
  20. Write Week 3 Blog beforehand

热门文章

  1. 企鹅号快速赚钱方法?企鹅号收益情况?
  2. 2022年大数据技能大赛国赛(模块A,B)
  3. 服务器能共享性能吗,共享云服务器性能
  4. win10密码忘了怎么办_笔记本密码忘了怎么办
  5. Android 9 红米4x,红米4X lineage16 安卓9.0 极致省电 纯净 完美root Xposed 经典版
  6. win10计算机找不到家庭组,Win10 家庭版 没有家庭组 这个选项,如何设置局域网 - Microsoft Community...
  7. BIOS三种硬盘模式
  8. Java并发相关知识(多线程、锁、容器、工具)
  9. 硬盘备份到新电脑,你需要知道这个技巧
  10. 前沿重器[13] | 知乎query改写思路启示