Linux可执行文件中使用的代码转换类型


13

我想问问,什么类型的编码用于制作linux可执行文件,例如十六进制,二进制或其他任何文件。如何转换?有什么办法可以从该可执行文件中获取原始代码?

这里有一些代码:

ELF���������>�����%|�����@�������������������@�8��@���������������������@�������@�����7<�����7<������� ������������������f�����f���������������������� ������[�UPX!L
h�h�8����������?�E�h=��ڊ̓�N�    4���9ISloB�q�w�]ȉ.��,ς��Q䝦����#e��-�N����/�b,���d<��'��-E��6E�s�/�U���ly�V�Y2]"a��S�.�hU�|�S�J�I�2���X}
�G0�;���5d�$���.)

它是什么意思?


尽管它并不能帮助您收回很多东西,但值得注意的是,strings筛选器程序在识别特定的二进制程序是什么或做什么方面非常有用,因为它会打印所有嵌入的文本字符串,而这些字符串的长度超过了指定长度。二进制文件和查看程序中的消息有时会告诉您很多有关其含义和作用的信息。

Answers:


29

它是二进制的。源代码已编译。您可以在编辑器中查看它(类似的十六进制编辑器bless可能会进行更精细的更改),但您确实需要知道自己在做什么。这可能只适合于更改字符串。

对于更顽固的事物,您可以开始将二进制文件反向工程为汇编代码。这通常被认为是人类可理解的最低级别的计算机语言。

objdump -d helloworld | less

但是它也将包含很多编译器废话。例如,如果使用G ++ 编译最简单的helloworld.cpp代码,则objdump最终会产生226行(剥去208行)的yuck。您可以只用15行汇编就可以编写一个“ hello world”,然后objdump对其进行编译,但是仍然会发展为166行(剥离)。

如果您对汇编有足够的了解,那么这可能使您有足够的机会了解正在发生的事情,甚至可以对其进行更改...但是要回答您的原始问题:

您不能将已编译的代码转换回原始源代码。

抱歉。这是一种单向转换,会丢失信息(注释,格式,可读的算法概念等),并与其他事物静态链接,并且通常以这种方式进行优化,从而使除最优秀,经验最丰富的程序员以外的任何人都无法理解。

为了让您大致了解问题的规模,整个逆向工程软件的想法都有其自己的Stack Exchange网站


您能告诉我如何进行反向工程并获取最大的代码量吗?我丢失了源代码
Redchief 2015年

7
查看我最近的编辑。没有回头的原始来源。通过大量的学习和大量的时间,您也许可以基于反汇编代码重写源代码,但是在大多数情况下,这样做会更便宜(除非您的时间没有用),并且更容易从头开始重写它。
奥利(Oli)

1
取回最大代码量的方法是还原最新备份。顺便说一句,这也是可靠地找回类似于原始源代码的唯一方法。
CVn 2015年

1
完全不反对最后一段,只是一个旁注:一些反编译器IME在恢复确切的代码结构方面做得很好(当然,除了您说的注释,格式,符号名称...之外)。如果您不是一开始就编写程序,那么恢复的源代码可能仍然难以理解,但是我认为这是一个(至少部分)恢复丢失的源代码/未知源代码(至少包含其中一部分)的绝佳选择。实际可理解,具体取决于特定的代码以及您是否也很幸运)
kos 2015年

1
这就是专有软件世界中所有EULA都禁止您执行的操作-逆向工程/反汇编。它们包含这样的子句是因为可以这样做-但肯定不容易!但是正如@MichaelKjörling所说的那样,唯一可以让您找回一切的好方法是从多级备份中获得您所关心的一切。

7

我的信誉点不足,因此无法回答。

不,不可能将其转换为“后退”。您提到过upx封隔器,您读过upx的手册吗?

如果您丢失了源代码,或者无法访问其他人的代码在这里无关紧要,那就根本不可能。

二进制可执行文件是由编译器生成的,不要相信此站点上的任何内容,只需阅读该编译器的手册即可。然后,您可以在此处添加原始代码以何种语言编写,使用了哪种编译器,然后您可能会注意到自己该步骤(预处理,编译,链接,打包)并没有完全相反,而只能分析原始作者的意图并撰写。



3

正如Oli在其答案中已经指出的那样,您无法获得可执行文件的原始源代码。

在源代码的编译过程中(编译的意图是接受更广泛的接受,因此将源代码“转换”为可执行文件的整个过程)会丢失很多信息。

例如,C预处理器将执行以下操作(除其他外):

  • 解释,执行和删除预处理器指令(#语句)
  • 删除评论
  • 删除不必要的空格

另一方面,在源代码的编译过程中没有丢失的东西在技术上可以恢复为功能上等效的源代码。

这是因为:

  • 二进制指令与汇编指令的对应关系为1:1。汇编源代码的汇编仅仅是基于对应表的汇编指令到二进制指令的转换。单个二进制指令总是可识别并可恢复为单个汇编指令 ;
  • 汇编指令与C指令之间没有 1:1的对应关系;C源代码的编译通常不仅仅是将C指令转换为基于对应表的汇编指令,事实上,情况往往恰恰相反。通常,一条C指令被转换为多个(根据编译器通常是不同的)汇编指令;但是,多个汇编指令的模式通常是可识别的,并且可以恢复为单个C指令

有一些称为反编译器的工具,其目的是试图将可执行文件还原为功能上等效的源代码。但是结果通常与原始源代码相去甚远(并且通常也无法编译);

考虑以下程序:

#include <stdio.h>

#define MESSAGE "Literal strings will be recovered" // This preprocessor directive won't be recovered

/*

This comment and the comment above won't be recovered

*/

int main(int argc, char* argv[]) {
    printf(MESSAGE);
    return 0;
}

通过将其编译为可执行文件并再次将其反编译为源代码,这或多或少是您通常会得到的(在这种情况下,我使用gcc/ Boomerang):

// address: 0x80483fb
int main(int argc, char **argv, char **envp) {
    printf("Literal strings will be recovered");
    return 0;
}

如预测的那样:

  • 缺少预处理器指令
  • 缺少注释(除了// address: 0x80483fb,反编译器已添加)
  • 缺少不必要的空格(除反汇编程序已添加的换行符和制表符之外)

这也是一个很好的结果。将内联汇编指令添加到代码中并不少见:

asm("assembly_instruction");
__asm__("assembly_instruction");

底线是(正如其他答案中已经指出的那样):您无法获得可执行文件 *的原始来源

*但是,取决于可执行文件和您的运气,您也许可以使用反编译器获得某些东西。


2

如果您在谈论编译程序,则可执行文件通常是二进制的。您可以使用找到更多信息file path/to/executable。您可以通过使用eg hexdump -C path/to/executable | less(无论有什么用)以十六进制显示二进制可执行文件。如果您想“将其转换回其原始格式”,则必须使用适当的反编译器,例如:,尽管这样会给您带来不易理解的代码,而不是原始的源代码。如果不是经过编译的二进制文件,它将是某种可执行脚本,在任何文本编辑器中都应易于阅读。您在此处向我们展示的可能是一个编译的可执行文件。ELF的意思是“可执行和链接格式”,这是Linux / Unix系统上的一种常见二进制格式。那里'strings path/to/executable,如果这是您需要的。


我尝试使用upx打包程序对其进行逆向工程,但是没有用,也没有按照您的建议进行。所以,请告诉我是否还有其他方法。
恶作剧

非常抱歉,但是我只能告诉您@Oli出色文章中的内容。
Hinz 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.