Tipo de conversão de código usado em arquivos executáveis do Linux

13

Eu quero perguntar que tipo de codificação é usada para criar arquivos executáveis do Linux, por exemplo. hexadecimal, binário ou qualquer outra coisa. como é convertido? Existe alguma maneira de recuperar o código original deste arquivo executável?

Aqui está um código que eu tenho:

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�$���.)

o que é que isso quer dizer?

    
por redchief 08.09.2015 / 09:34

5 respostas

29

É binário. O código fonte foi compilado. Você pode visualizá-lo em um editor (um editor hexadecimal como bless pode fazer alterações mais refinadas), mas você realmente precisa saber o que está fazendo. É provável que seja bom apenas para fazer alterações de string.

Para qualquer coisa mais hardcore, você pode começar a fazer engenharia reversa do binário no código assembly . Isso geralmente é considerado como a linguagem de computador mais humana que pode ser analisada.

objdump -d helloworld | less

Mas também incluirá muito bobagem no compilador. Por exemplo, se você compilar o mais simples helloworld.cpp com G ++ e, em seguida, objdump , você terminará até com 226 linhas (208 despojado) de yuck. Você poderia escrever um "hello world" em apenas 15 linhas de montagem , compilá-lo e objdump , mas isso ainda floresce em 166 linhas (despojado).

Se você é bom o suficiente com a montagem, isso pode lhe dar acesso suficiente para entender o que está acontecendo e até mesmo permitir que você o altere ... Mas, para responder à sua pergunta original:

Você não pode transformar o código compilado de volta no código-fonte original .

Desculpe. É uma transformação unidirecional que perde informação (comentários, formatação, conceitos de algoritmos legíveis, etc), está estaticamente ligada a outras coisas e é geralmente otimizada de tal forma que tornaria ininteligível para qualquer coisa, exceto os melhores e mais experientes programadores.

Para dar uma idéia da escala do problema, toda a ideia do software de engenharia reversa tem seu próprio site Stack Exchange .

    
por Oli 08.09.2015 / 10:00
7

Não tenho pontos de reputação suficientes para um comentário, por isso, é uma resposta:

Não, não é possível convertê-lo "de volta". Você mencionou upx packer, você já leu o manual do upx?

Se você perdeu a fonte, ou não tem acesso ao código de outra pessoa, não importa aqui, simplesmente não é possível.

O executável binário foi produzido com um compilador, não acredite em nada declarado neste site, apenas leia o manual exatamente desse compilador. Então, você poderia adicionar aqui, em qual linguagem o código original foi escrito, qual compilador foi usado, e então você pode notar que estas etapas (pré-processamento, compilação, ligação, talvez empacotamento) não são revertidas como um todo, mas somente ser analisado o que o autor original poderia ter pretendido e escrito.

    
por justabot 08.09.2015 / 16:30
3

Este é provavelmente um arquivo binário (um arquivo ELF), conforme descrito bem aqui:

link

Se você alterou com um editor de texto normal e salvou suas alterações, isso não era uma boa ideia e você pode tê-lo destruído.

    
por Bruni 08.09.2015 / 09:48
3

Como Oli já apontou em sua resposta, você não pode obter o código-fonte original de um executável.

Durante a compilação de um código-fonte (compilação destinada como em sua típica aceitação mais ampla, portanto, como todo o processo que "transforma" um código-fonte em um executável), muitas informações são perdidas.

O pré-processador C, por exemplo, fará o seguinte (entre outras coisas):

  • Interpretar, executar e remover diretivas de pré-processador ( # instruções)
  • Remover comentários
  • Remover espaço em branco desnecessário

Por outro lado, o que não é perdido durante a compilação do código-fonte é tecnicamente reversível para um código-fonte funcionalmente equivalente.

Isso porque:

  • As instruções binárias têm uma correspondência de 1: 1 com instruções de montagem; a montagem de um código fonte de montagem é apenas uma mera conversão das instruções de montagem para as instruções binárias com base em uma tabela de correspondências; uma única instrução binária é sempre identificável e reversível para uma única instrução de montagem ;
  • As instruções de montagem não têm uma correspondência de 1: 1 com instruções C; a compilação de um código-fonte C não é, em geral, apenas uma simples conversão das instruções C para as instruções de montagem com base em uma tabela de correspondências; na verdade, muitas vezes é o contrário; geralmente uma instrução C é convertida em múltiplas (frequentemente diferentes baseadas no compilador) instruções de montagem; no entanto, padrões de múltiplas instruções de montagem são geralmente identificáveis e reversíveis para uma única instrução C ;

Existem ferramentas chamadas descompiladores cuja finalidade é tentar reverter um executável para um código fonte funcionalmente equivalente; no entanto, o resultado geralmente é algo longe do código-fonte original (e geralmente também não-compensável);

Considere este programa:

#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;
}

Compilando-o em um executável e descompilando-o em um código-fonte novamente, isso é mais ou menos o que você normalmente recebe de volta (neste caso específico eu usei gcc / Boomerang ):

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

Como previsto:

  • Diretivas de pré-processador estão ausentes
  • Os comentários estão faltando (além de // address: 0x80483fb , que foi adicionado pelo decompilador)
  • Espaços em branco desnecessários estão faltando (além das novas linhas e tabulações, que foram adicionadas pelo decompilador)

Este também é um bom resultado; não é raro obter instruções de montagem inline no código:

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

A linha de fundo é (como já foi apontado nas outras respostas): você não pode obter a fonte original de um executável *.

* No entanto, dependendo do executável e da sua sorte, você pode conseguir algo usando um decompilador.

    
por kos 09.09.2015 / 18:29
2

Executáveis são geralmente binários se você estiver falando sobre programas compilados. Você pode encontrar mais informações usando file path/to/executable . Você pode exibir executáveis binários em hexadecimal usando, e. hexdump -C path/to/executable | less (seja qual for o bem que você faria). Se você quiser "convertê-lo de volta à sua forma original", será necessário usar um decompilador apropriado veja este post, por exemplo , embora isso daria a você um código bastante ilegível, não o original do qual ele foi compilado. Se não é um binário compilado, seria algum tipo de script executável, que deveria ser facilmente legível em qualquer editor de texto. O que você nos mostrou aqui provavelmente é um executável compilado. ELF significa "Formato executável e de vinculação", que é um formato binário comum em sistemas Linux / Unix. Existe a possibilidade de extrair as partes de string legíveis de arquivos binários usando strings path/to/executable , se é isso que você precisa.

    
por Hinz 08.09.2015 / 10:00