Как получить исходный код c из скомпилированного кода

У меня есть скомпилированный код C в текстовом формате. Мне нужно извлечь исходный код, декомпилировав машинный код. Как это сделать?

из двоичного файла вы можете создать соответствующий исходный код на ассемблере с некоторой связанной информацией на случай, если присутствуют отладочные данные (двоичный файл не разделен), но не ожидайте большего. Кроме того, у вас может быть один и тот же двоичный файл из нескольких начальных источников C, поэтому даже вы можете отменить компиляцию для создания кода C, он не будет первоначальным, и его будет нелегко читать.

bruno 17.02.2019 14:03

Пожалуйста, опишите подробнее, что вы ожидаете. Дело не в том, что вы получите читаемый исходный код из исполняемого файла, не так ли? Что вы подразумеваете под «скомпилированным кодом C в текстовом формате»? «текстовый формат» звучит как что-то удобочитаемое, а «скомпилированный» — наоборот. Обратите внимание, что даже люди не очень хорошо умеют писать читаемый или даже похожий код для одной и той же цели. Также всегда есть несколько способов написания разных кодов, которые приводят к одному и тому же двоичному коду. И тот, который состоит только из информации, которая находится в двоичном файле, конечно, не тот, который обычно считается читаемым.

Yunnosch 17.02.2019 14:08

Разговорный термин для этого — «превращение гамбургера обратно в коров». Практически невозможно восстановить исходный код из скомпилированного машинного кода. Декомпиляторы дадут вам что-то функционально эквивалентное, но это не будет исходный код оригинальный.

John Bode 17.02.2019 17:26
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
3
3 472
3

Ответы 3

«Настоящая» декомпиляция, в принципе, невозможна. Прежде всего, вы не можете «декомпилировать» локальные имена (в функциях и файлах/модулях исходного кода). Для них вы получите что-то вроде int локальных переменных: i1, i2... Конечно, если у вас также нет отладочной информации, что бывает нечасто.

Декомпиляция в «что-то» (которое может быть не очень читабельным) возможна, но обычно она опирается на некоторую эвристику, распознавая шаблоны кода, которые генерируют компиляторы, и может обманывают, создавая странный (возможно, даже неправильный) код C. На практике это означает, что декомпилятор обычно работает нормально для определенного компилятора с определенными (по умолчанию) параметрами компиляции, но не так хорошо с другими.

Сказав это, декомпиляторы существуют, и вы можете попытать счастья, скажем, Снеговик

Пожалуйста, опубликуйте пример «скомпилированного кода C в текстовом формате».

Возможно, тогда будет легче увидеть, чего вы пытаетесь достичь.

Обычно нецелесообразно перепроектировать язык ассемблера в C, потому что большая часть удобочитаемой информации в виде меток и имен переменных безвозвратно теряется в процессе компиляции.

Как сказал Срджан, в общем случае декомпиляция программы C (или C++) невозможна. Слишком много информации теряется в процессе компиляции. Например, рассмотрите объявление, такое как int x, это «потеряно», поскольку оно не создает напрямую никаких инструкций машинного уровня. Эта информация нужна компилятору только для проверки типов.

Однако теперь можно выполнить дизассемблирование, которое переводит скомпилированный исполняемый файл на уровень языка ассемблера. Однако интерпретация сборки может быть (будет ли?) сложной и, безусловно, требует много времени. Есть несколько доступных дизассемблеров, если у вас есть деньги, IDA-Pro, вероятно, является отраслевым стандартом среди дизассемблеров, и если вы выполняете такую ​​работу, то стоит несколько тысяч долларов за лицензию. Есть несколько доступных дизассемблеров с открытым исходным кодом, Google может их найти.

Теперь, когда было сказано, что были попытки создать декомпиляторы, у IDA-Pro есть один, и вы можете посмотреть на http://boomerang.sourceforge.net/ в дополнение к Snowman, указанному выше.

Наконец, другие языки более дружественны к декомпиляции, чем C или C++. Например, программы C# можно декомпилировать с помощью таких инструментов, как dotPeek или ilSpy. Аналогично с Java существует ряд инструментов, которые могут конвертировать байт-код Java обратно в исходный код Java.

Другие вопросы по теме