Тип перетворення коду, який використовується у виконуваних файлах 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програма фільтра може бути дуже корисною для визначення того, що конкретна бінарна програма чи робить, оскільки вона буде друкувати всі вбудовані текстові рядки довше вказаної довжини в двійковий файл і перегляд повідомлень у програмі іноді багато що розповідає про те, що це і що робиться.
Джо

Можливий / частковий дублікат? stackoverflow.com/questions/193896/whats-a-good-c-decompiler
arielf

Відповіді:


29

Це бінарне. Вихідний код був складений. Ви можете переглянути його в редакторі (шістнадцятковий редактор, як, blessможливо, вносити більш вдосконалені зміни), але вам дійсно потрібно знати, що ви робите. Це, мабуть, добре лише для внесення змін до рядків.

Для чогось більш жорсткого, ви можете почати інвертувати бінарний код на збірний код. Це часто розглядається як найменший рівень комп’ютерної мови, що відповідає людству.

objdump -d helloworld | less

Але це також буде містити багато дурниць компілятора. Наприклад, якщо ви компілюєте найпростішийhelloworld.cpp з G ++, а потім objdumpвін, ви отримуєте 226 рядків (208 позбавлених) yuck. Ви можете написати "привіт світ" всього за 15 рядків складання , скласти objdumpйого, але він все ще розквітає на 166 рядків (позбавлений).

Якщо ви досить добре зібралися, це може дати вам достатній доступ, щоб зрозуміти, що відбувається, і навіть дозволить вам змінити це… Але відповісти на своє первісне запитання:

Ви не можете повернути складений код назад у вихідний вихідний код.

Вибачте. Це одностороння трансформація, яка втрачає інформацію (коментарі, форматування, читабельні концепції алгоритмів тощо), статично пов'язана з іншими речами і, як правило, оптимізована таким чином, що зробить її не зрозумілою ні до чого, окрім найкращих і досвідчених програмістів.

Щоб дати вам уявлення про масштаб проблеми, у всієї ідеї програмного забезпечення зворотного проектування є власний сайт Stack Exchange .


Чи можете ви сказати мені, як мені повернути його інженером і отримати максимальну кількість коду, тому що я втратив джерело
redchief

7
Дивіться мою останню редакцію. Немає повернення до першоджерела. Маючи багато знань і багато часу, ви, можливо, зможете переписати джерело на основі розібраного коду збірки, але в більшості випадків це буде дешевше (якщо ваш час не вартий) і простіше просто переписати його з нуля.
Олі

1
Спосіб повернення максимальної кількості коду - відновлення останньої резервної копії. Це, до речі, єдиний спосіб надійно повернути щось, що нагадує оригінальний вихідний код.
CVn

1
Зовсім не погоджуючись з останнім абзацом, лише бічна зауваження: деякі декомпілятори IME роблять чудову роботу щодо відновлення точної структури коду (окрім, як ви сказали коментарів, форматування, назви символів ...). Якщо ви не написали програму в першу чергу, відновлений вихідний код може бути все ще не зрозумілим, проте я думаю, що це чудовий варіант відновити (принаймні частково) втрачений вихідний код / ​​невідомий вихідний код (принаймні його частини насправді зрозуміло, залежно від конкретного коду та від того, чи пощастить вам
kos

1
Ось що кажуть всі ті EULAs у світі власного програмного забезпечення, що вам заборонено робити це - зворотна інженерія / демонтаж. Вони включають подібні статті, тому що це можна зробити - але, звичайно, непросто! Але як говорить @ MichaelKjörling, єдиний хороший спосіб повернути речі - це з декількох рівнів резервного копіювання для всього, що вам важливо.
Джо

7

У мене недостатньо балів репутації для коментаря, тому це відповідь:

Ні, конвертувати це "назад" неможливо. Ви згадуєте пакувач upx, ви коли-небудь читали посібник з upx?

Якщо ви втратили джерело або не маєте доступу до коду когось іншого тут не має значення, це просто неможливо.

Бінарний виконуваний файл був створений за допомогою компілятора, не вірте нічого, що зазначено на цьому сайті, просто прочитайте інструкцію саме цього компілятора. Потім ви можете додати сюди, якою мовою був написаний оригінальний код, який компілятор був використаний, а потім ви могли б відзначити себе, що ці кроки (попередня обробка, компіляція, зв'язування, можливо упаковка) не змінюються в цілому, а можуть лише проаналізувати те, що, можливо, задумав автор, і написав.



3

Як вказував Олі вже у своїй відповіді, ви не можете отримати дуже оригінальний вихідний код виконуваного файлу.

Під час компіляції вихідного коду (компіляція призначена як типово більш широке прийняття, отже, як весь процес, який "перетворює" вихідний код у виконуваний файл), багато інформації втрачається.

Препроцесор C, наприклад, зробить наступне (серед іншого):

  • Інтерпретація, виконання та видалення директив ( #операторів) препроцесора
  • Видалити коментарі
  • Видаліть зайвий пробіл

З іншого боку, те, що не втрачається під час компіляції вихідного коду, технічно перетворюється на функціонально еквівалентний вихідний код.

Це відбувається тому:

  • Бінарні інструкції мають відповідність 1: 1 із інструкціями щодо складання; складання вихідного коду збірки - це лише просте перетворення інструкцій складання у бінарні інструкції на основі таблиці корисних можливостей; одна двійкова інструкція завжди може бути ідентифікована і перетворювана на одну інструкцію зі складання ;
  • Інструкції по збірці не мають 1: 1 відповідальності з інструкціями 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/ Бумеранг ):

// 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. Ви можете відображати бінарні виконувані файли у шістнадцятковій формі, використовуючи, наприклад, hexdump -C path/to/executable | less(що б там не було добре, що б вам зробило). Якщо ви хочете "перетворити його в початковий вигляд", вам доведеться скористатися відповідним декомпілятором, перегляньте цю публікацію, наприклад , хоча це дасть вам нечитабельний код, а не оригінал, з якого він був складений. Якщо це не скомпільований двійковий файл, це був би якийсь виконуваний сценарій, який повинен легко читатися в будь-якому текстовому редакторі. Те, що ви нам тут показали, - це, мабуть, aa, складений виконуваний файл. ELF означає "виконуваний і зв'язуючий формат", який є поширеним бінарним форматом для систем Linux / Unix. Там 'strings path/to/executable, якщо це те, що вам потрібно.


Я спробував повернути його інженеру за допомогою пакета upx, але не вийшло, а також із запропонованою вами публікацією. Тож скажіть, будь ласка, чи є інший спосіб.
redchief

Дуже шкода, але я не можу сказати тобі більше, ніж те, що написано у відмінній публікації @ Олі.
Гінз
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.