Tipo de conversão de código usada nos arquivos executáveis ​​do Linux

13

Quero perguntar que tipo de codificação é usada para criar arquivos executáveis ​​em linux, por exemplo, hexadecemal, binário ou qualquer outra coisa. como é convertido? Existe alguma maneira de recuperar o código original desse arquivo executável?

Aqui está um pouco do código que 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 isso significa?

lenço
fonte
Embora isso não o ajude a recuperar muito, vale a pena notar que o stringsprograma de filtro pode ser muito útil para identificar o que um programa binário específico é ou faz, porque imprimirá todas as seqüências de texto incorporadas por mais de um comprimento especificado em um arquivo binário e observar as mensagens em um programa às vezes diz muito sobre o que é e faz.
Joe
Possível / duplicado parcial? stackoverflow.com/questions/193896/whats-a-good-c-decompiler
arielf

Respostas:

29

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

Para algo mais grave, você pode começar a fazer engenharia reversa do binário em código de montagem . Isso geralmente é considerado como a linguagem de computador de nível mais baixo analisável por humanos.

objdump -d helloworld | less

Mas também incluirá muitas bobagens do compilador. Por exemplo, se você compilar o mais simpleshelloworld.cpp com o G ++ e, em seguida objdump, acabar com 226 linhas (208 removidas) de eca. Você pode escrever um "olá mundo" em apenas 15 linhas de montagem , compilá-lo e criarobjdump , mas isso ainda floresce em 166 linhas (despojadas).

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

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

Desculpe. É uma transformação unidirecional que perde informações (comentários, formatação, conceitos de algoritmos legíveis etc.), está estaticamente vinculada a outras coisas e geralmente é otimizada de maneira a torná-la ininteligível a qualquer coisa, exceto aos melhores e mais experientes programadores.

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

Oli
fonte
Você pode me dizer como posso fazer engenharia reversa e obter quantia de volta máximo de código coz eu perdi a fonte
redchief
7
Veja minha edição recente. Não há como voltar à fonte original. Com muito aprendizado e muito tempo, você pode reescrever a fonte com base no código de montagem desmontado, mas, na maioria dos casos, seria mais barato (a menos que seu tempo não valha a pena) e mais fácil apenas reescrevê-lo do zero.
Oli
1
A maneira de recuperar a quantidade máxima de código é restaurar o backup mais recente. Aliás, essa também é a única maneira de recuperar de forma confiável algo semelhante ao código-fonte original.
um CVn
1
Não discordo do último parágrafo, apenas uma observação: alguns IMP descompiladores fazem um ótimo trabalho em restaurar a estrutura exata do código (além de como você disse comentários, formatação, nomes de símbolos ...). Se você não escreveu o programa em primeiro lugar, o código-fonte recuperado ainda pode ser ininteligível, no entanto, acho que é uma ótima opção para recuperar (pelo menos parcialmente) um código-fonte perdido / um código-fonte desconhecido (com pelo menos partes dele) inteligíveis, dependendo do código específico e se você tiver sorte também)
kos
1
É isso que todos os EULAs no mundo do software proprietário dizem que você não tem permissão para fazer - engenharia reversa / desmontagem. Eles incluem cláusulas como essa porque é possível, mas certamente não é fácil! Mas, como @ MichaelKjörling diz, a única maneira de recuperar as coisas é com vários níveis de backup para qualquer coisa que você goste.
Joe
7

Como não tenho pontos de reputação suficientes para comentar, é 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, isso simplesmente não é possível.

O executável binário foi produzido com um compilador, não acredite em nada indicado neste site, basta ler o manual exatamente desse compilador. Em seguida, você pode adicionar aqui, em qual idioma o código original foi escrito, qual compilador foi usado e, em seguida, você pode observar que essas etapas (pré-processamento, compilação, vinculação, talvez empacotamento) não são revertidas como um todo, mas somente seja analisado o que o autor original possa ter pretendido e escrito.

justabot
fonte
3

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

Durante a compilação de um código fonte (compilação pretendida como em sua aceitação mais ampla típica, 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
  • Remova espaços em branco desnecessários

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.

Isto é porque:

  • As instruções binárias têm uma correlação 1: 1 com as instruções de montagem; a montagem de um código-fonte de montagem é apenas uma mera conversão das instruções de montagem em instruções binárias com base em uma tabela de correspondências; uma única instrução binária é sempre identificável e reversível a uma única instrução de montagem ;
  • As instruções de montagem não têm uma correlação 1: 1 com as instruções C; a compilação de um código-fonte C geralmente não é apenas uma mera 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 várias instruções de montagem (geralmente diferentes com base no compilador); no entanto, padrões de várias instruções de montagem são geralmente identificáveis ​​e reversíveis para uma única instrução C ;

Existem ferramentas chamadas descompiladores cujo objetivo é tentar reverter um executável para um código-fonte funcionalmente equivalente; no entanto, o resultado geralmente é algo muito distante do código fonte muito original (e geralmente também não compilá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, é mais ou menos o que você costuma receber de volta (nesse caso específico, 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
  • Faltam comentários (além do // address: 0x80483fbque foi adicionado pelo decompilador)
  • Falta espaço em branco desnecessário (além de novas linhas e tabulações, que foram adicionadas pelo decompilador)

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

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

A linha inferior é (como já indicado 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ê poderá obter algo usando um descompilador.

kos
fonte
2

Os executáveis ​​geralmente são 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, por exemplo, hexdump -C path/to/executable | less(qualquer que seja o benefício). Se você quiser "convertê-lo de volta à sua forma original", você precisará usar um descompilador apropriado, consulte este post, por exemplo , embora isso lhe dê um código bastante ilegível, e não o original do qual foi compilado. Se não for um binário compilado, seria algum tipo de script executável, que deve 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. Lá'strings path/to/executable, se é isso que você precisa.

Hinz
fonte
Tentei fazer engenharia reversa com o empacotador upx, mas não funcionou e também com o post que você sugeriu. Então, por favor me diga se existe outra maneira.
redchief
Sinto muito, mas não posso contar nada além do que está escrito no excelente post de @ Oli.
Hinz