Как в делфи скомпилировать exe файл

Обновлено: 04.07.2024

Читая форумы по программированию, иногда натыкаешься на вопрос типа: "У меня есть откомпилированная программа на Delphi. Как мне получить её исходный код?". Обычно такой вопрос возникает, когда программист потерял файлы проекта и у него остался только .exe. Как правило полностью восстановить исходный код на языке высокого уровня невозможно. Значит ли это, что другие тоже не смогут восстановить исходный код Вашей программы ? Хм . и да и нет .

Для начала сразу скажу, что восстановить исходный код в точности каким он был однозначно невозможно, так как не существует в мире такого декомпилятора, который бы смог сотворить такое.

После компиляции и линковки проекта и получения исполняемого файла все имена, используемые в программе конвертируются в адреса. Потеря имён означет, что декомпилятор создаст уникальное имя для каждой константы, переменной, функции и процедуры. Даже если мы и достигнем какого-то успеха в декомпиляции исполняемого файла, то получим уже другой синтаксис программы. Данная проблема связана с тем, что при компиляции практически идентичные куски кода могут быть скомпилированы в разные последовательности машинных команд (ASM), которые присутствуют в .exe файле.
Естевственно декомпилятор не обладает такой степенью интеллектуальности, чтобы решить - какова же была последовательность инструкций языка высокого уровня в исходном проекте.

2 Reply by PunBB 2015.07.09 10:20

Когда же применяется декомпиляция ? Для этого существует довольно много причин. Вот некторые из них:
- Восстановление исходного кода;
- Перенос приложения на другую платформу;
- Определение наличия вирусов в коде программы или вредоносного кода;
- Исправление ошибок в программе, в случае, если создатель приложения не собирается этого делать

Легально ли всё это ? Хотя декомпиляция и не является взломом, но утвердительно ответить на этот вопрос довольно сложно. Обычно программы защищены законом об авторских правах, однако в большинстве стран на декомпиляцию делается исключение. В часности, когда необходимо изменить интерфейс программы для конкретной страны, а сервис приложения не позволяет этого сделать.

На данный момент Borland не предоставляет никаких программных продуктов, способных декомпилировать исполняемые файлы (.exe) либо откомпилированные Delphi-модули (.dcu) в исходный код (.pas).

Если же Вы всё-таки решились попробовать декомпилировать исполняемый файл, то необходимо знать следующие вещи. Исходные коды на Delphi обычно хранятся в файлах двух типов: сам исходник в ASCII кодировке (.pas, .dpr) и файлы ресурсов (.res, .rc, .dfm, .dcr). Dfm файлы хранят в себе свойства объектов, содержащихся в форме. При создании конечного .exe, Delphi копирует в него информацию из .dfm файлов. Каждый раз, когда мы изменяем координаты формы, описания кнопок или связанные с ними события, то Delphi записывает эти изменения в .dfm (за исключением кода процедур. Он сохраняется в файлах pas/dcu ). И наконец, чтобы получить при декомпиляции файл .dfm, нужно знать - какие типы ресурсов хранятся внутри Win32 исполняемого модуля.

3 Reply by PunBB 2015.07.09 11:35

Все программы, скомпилированные в Delphi имеют следующие секции: CODE, DATA, BSS, .idata, tls, .rdata, .rsrc. Самые важные для декомпиляции секции CODE и .rsrc. В статье "Adding functionality to a Delphi program" приведены некоторые интересные факты о исполняемых форматах Delphi, а так же информация о классах и DFM ресурсах. В этой статье есть один интересный момент под заголовком: "Как добавить свой обработчик события в уже откомпилированный файл, например, чтобы изменять тект на кнопке".

Среди многих типов ресурсов, которые сохранены в .exe файле, интерес представляет RT_RCDATA, который хранит информацию, которая были в DFM файле перед трансляцией. Чтобы извлеч DFM данные из .exe файла, мы можем вызываться API функцией EnumResourceNames.

Исскуство декомпилирования традиционно было уделом мастеров, знакомых с ассемблером и отладчиками. Некоторые Delphi декомпиляторы создают впечатление, что любой, даже с ограниченными техническими знаниями, может изменить по своему желанию большинство исполняемых файлов Delphi.

4 Reply by PunBB 2015.07.09 11:46

Если Вы заинтересовались декомпилованием, то предлагаю Вам несколько Delphi декомпиляторов:

DeDe
DeDe довольно шустрая программка, позволяющая анализировать экзешники, скомпилированные в Delphi. После декомпиляции DeDe даёт Вам следующее:
- Все dfm файлы. Вы сможете открывать их и редактировать в Delphi
- Все объявленные методы с хорошо комментированным кодом на ассемблере с ссылками на строки, импортированных функций, методов и компонент в юните, блоки Try-Except и Try-Finally.
- Большое количество дополнительной информации.
- Вы можете создать папку Delphi проекта со всеми файлами dfm, pas, dpr. Не забудьте, что pas файлы содержат ассемблерный код.

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

MRIP
Позволяет извлекать из Delphi приложения любые ресурсы: курсоры, иконки, dfm файлы, pas файлы и т.д. Но главная его особенность - это способность извлекать файлы, хранящиеся в других файлах. Поддерживается более 100 форматов файлов. MRip работает под DOS.

5 Reply by PunBB 2015.07.10 02:39

Нашел уникальное решение проблемы распаковки файлов exe, но платное. Хотя есть тестовый период.

Тюнер ресурсов позволяет просматривать, извлекать, заменять, изменять и удалять внедренные ресурсы исполняемых файлов: иконы, строки, изображения, звуки, диалоги, меню - все, что составляют визуальную часть ваших программ Windows.

Тюнер ресурсов о единственном инструменте вы, вероятно, доверять изменять ресурсы в PE исполняемого файла. Откройте для себя уникальные свойства этого редактора ресурсов , в том числе, как открыть проблемные исполняемые файлы и редактировать скрытые данные, которые другие редакторы просто не может видеть, широкий спектр поддерживаемых типов ресурсов, для распаковки UPX, и многое другое. Вы узнаете, стандартную программу промышленности для перевода и настройки пользовательского интерфейса.

Тюнер ресурсов с огромным количеством функций, которые делают его важным инструментом для тех, кто настройки еще программы. Удачи персонализации любое приложение на свой неповторимый вкус. С помощью мощных Resource Tuner, вам больше не нужно страдать с уродливыми икон и картин по умолчанию. Использование очень просто, просто запустите программу и выберите EXE или DLL файл, чтобы прочитать данные из.

После того, как вы попробуете это, мы думаем, вам будет трудно вернуться на другой ресурс хакерских утилит.

Я довольно часто сталкивался с тем, что разработчики на Delphi (можно сказать традиционно) компилируют свои приложения "ручками", что далеко не production-решение, а со стороны выглядит кустарщиной и "делаем на-коленке", хотя продукты бывают весьма серьёзными и продаваемыми. Вероятно, это пошло ещё с тех пор, когда для автоматизации нужно было придумывать свои батнички, которые запускали компилятор командной строки dcc32 с нужными параметрами. Некоторые даже сделали свой "Публикатор" — Delphi-expert, который делает работу сервера сборок: компилирует (правда, открытый в IDE) проект, выставляя ему взятый из какой-то БД инкрементированный номер версии, записывает некий changelog и копирует это куда-то в сетевой каталог.

Я не буду вдаваться в исторический экскурс как было раньше. Я расскажу как есть/можно сейчас, и как это использовать для повышения эффективности своей работы.

Файл проекта современной версии Delphi — это .dproj -файл (здесь и далее я буду ориентироваться на Delphi 10 Rio, но с небольшими отличиями это верно для всех более ранних версий Delphi, начиная с 2007). В нём хранятся все настройки проекта, которые обычно изменяют в IDE (меню Project - Options (Ctrl+Shift+F11) ). В рамках данной статьи я сконцентрируюсь на "основных", которые понадобятся для демонстрации общих принципов: это Config — конфигурация, Platform — платформа, OutputDirectory — путь выходного файла и ConditionalDefines (директивы условной компиляции). Остальные настройки, если таковые нужно менять при сборке, я предлагаю выявить самостоятельно. Этот же .dproj -файл, если в него заглянуть обычным текстовым редактором, является ничем иным как скриптом сборки MSBuild (давайте создадим простое консольное приложение и назовём его DelphiAutomatedBuild):

Скрипты сборки MSBuild также используются для описания проектов, например, Visual Studio. Я коснусь некоторых деталей MSBuild, но я предлагаю читателю самостоятельно освоить его азы. Что нам это даёт? Это позволяет нам выполнить сборку Delphi-проекта из командной строки одной строчкой (что, в свою очередь, позволяет автоматизировать сборку проекта)

Если же читатель откроет командную строку в каталоге с проектом (hint: это можно быстро сделать, щёлкнув правой кнопкой мыши (ПКМ) на проекте в IDE — Show in Explorer, затем в Проводнике ПКМ — Открыть окно команд), то вышеприведённая команда не сработает:

т.к по умолчанию, пути к MSBuild-у в PATH нет. Так что добавим его туда:

Сборка запустилась, но завершилась с ошибкой. В чём же дело? Почему нет задачи build ?

Тут мы заглянем в .dproj -файл, там мы найдём следующее:

И если мы откроем файл в каталоге Delphi
c:\Program Files\Embarcadero\Studio\20.0\Bin\CodeGear.Delphi.Targets , то мы увидим там ещё один MSBuild-скрипт, в котором объявлена задача Build :

Т.е. нужно задать переменную окружения BDS ( $(VAR) в MSBuild разыменовывает как свойство (Property) VAR , заданное в скрипте, так и одноимённую переменную окружения), указать в ней путь к той версии Delphi, которая будет компилировать проект (да-да, один и тот же проект можно компилировать разными версиями Delphi, лишь заменив значение переменной окружения BDS ). Тогда скрипт проекта разыменует $(BDS) , найдёт общий .Targets файл из каталога Delphi и запустит задачу Build .
Сделаем это:

Та-дам! Проект скомпилировался. В выходном каталоге Win32\Debug лежит наш DelphiAutomatedBuild.exe .

Но это отладочная сборка (по умолчанию, новый проект активируется в Debug-конфигурации), а мы хотим для выпуска релиза собирать Release-конфигурацию (подробнее про конфигурации). В IDE это сделать легко, но это ручная работа, и это то, чего мы хотим избежать, то ради чего мы читаем эту статью. Заглянем опять в .dproj -файл, и заметим в его начале такую строку

Мы ж программисты, и понимаем, что если свойство/переменная Config , не задана, то по умолчанию она принимается равной Debug . Это как раз то, что мы меняем в IDE (поменяйте в IDE текущую конфигурацию на Release и сохраните проект — строка сменится на

в коде для контроля исполняемого файла добавим такое:

и убедимся, что conditional defines в настройках проекта для Release и Debug-конфигураций содержат RELEASE и DEBUG, соответственно

Так что нужно лишь задать свойство Config в нужное нам значение, и собираться будет нужная конфигурация:

Часто разработчики указывают путь отладочной (а то и релизной) сборки в какой-то каталог на своём диске, но мы автоматизируем сборку и подразумеваем, что выполняться она будет на сервере сборок, а получать выходные файлы непонятно где в файловой системе сервера — как-то неправильно. Значит, мы должны уметь задавать этот выходной путь. Заглянем опять в .dproj :

но что это? тут нет условия (если не задано), и свойство задаётся всегда, сможем ли мы его переопределить? попробуем

Та-дам! Появился каталог binaries , в котором — наш DelphiAutomatedBuild.exe . Как же так? Тот, кто уже освоил MSBuild , знает, что свойства, заданные при запуске MSBuild -а, имеют высший приоритет, и уже не могут быть переопределены в скрипте. Сейчас нас это устраивает. Но с этим мы ещё столкнёмся.

Выходной каталог мы менять научились. Теперь нужно собирать сразу и релизную, и отладочную версии (надеюсь, не надо объяснять зачем такое надо). Конечно, можно запустить сначала с одним параметром Config — Debug , затем — с другим — Release , но это потребует, во-первых, дублирования остальных параметров (например, DCC_ExeOutput и параметра версии сборки (об этом — ниже)), а во-вторых, это придётся учитывать и при конфигурировании сервера сборок, что влечёт дублирование и там (либо написание очередного батничка, что лишает встроенной поддержки MSBuild-а сервером сборок). Так что требуется выполнить всё ту же одну команду

но она бы выполнила сборку обеих конфигураций. Можно так? Конечно!
Напишем свою задачу Build . Поскольку есть нежелание менять что-то в файле, который меняет IDE (часто самым дурацким образом; кстати, есть три замечательных инструмента от автора эксперта MMX: DProjNormalizer, DProjSplitter и сумма их — ProjectMagician — для удобства отслеживания изменений .dproj -файлов), то сделаем отдельный файл проекта. Назовём его DAB.ciproj (CI-project, от CI — Continuous Integration):

и… получаем один файл DelphiAutomatedBuild.exe в binaries , той конфигурации, что собралась последней:

DCC_Exeoutput задался и для каждой задачи MSBuild — это хорошо, но каждая конфигурация скомпилировала файл в один и тот же каталог. Тогда зададим подкаталоги соответственно конфигурации:

и теперь на выходе мы имеем два файла

binaries\Debug\DelphiAutomatedBuild.exe и binaries\Release\DelphiAutomatedBuild.exe .

Теперь представим, что у нас есть желание/необходимость временно задавать conditional define при сборке проекта (например, у нас есть демо-версия, в которой мы ограничиваем функциональность нашей программы, если задано переменная условной компиляции TRIAL )

В нашем демо-коде это выглядит так

Добавим в Debug-конфигурацию conditional define TRIAL и посмотрим, куда оно прописывается в .dproj:

Ага, т.е. если задать /p:DCC_Define=TRIAL,

Сработало, но как-то не так, куда-то делись DEBUG и RELEASE, а нам такого не надо, т.к. у нас там обычно куча полезных define-ов.
А дело в том, что свойства заданные через командную строку имеют высший приоритет, и переопределяют значения в скриптах. Но выход есть.
Определяем переменную окружения DCC_Define :

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

Однако ж, при таких частых сборках может стать проблема нумерации версий. Какая? Каждая новая сборка будет иметь ровно ту версию, которая прописана в свойствах проекта, а менять её с каждым коммитом — как-то рутинно и не "по-нашенски", к тому же, зависит от разработчика человека (а что такое "человеческий фактор" — не мне вам рассказывать).

В рамках обычной для Windows/Delphi-проектов нумерации Major.Minor.Release.Build , нормальный сервер сборок, как правило, умеет увеличивать для каждой сборке число Release , и, естественно, передавать её в скрипты сборки. Однако ж, если мы посмотрим на то, как задаётся информация о версии в .dproj-файле

Любознательный читатель наверняка уже догадывается как примерно такое использовать.
Добавим в наш DelphiAutomatedBuild.dproj

(Условие "$(MSBuildToolsVersion) >= 4.0" необходимо для того, чтобы проект не падал с ошибкой при сборке в IDE, которая, как мы помним, использует MSBuild 3.5, который не поддерживает UsingTask)

Поставим в свойствах проекта "Include version information in project" и добавим вывод текущей версии (оставим это за скобками), и:

Заключение

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

В дальнейшем я ещё планирую рассказать

  1. как запускать статический анализ кода (на примере FixInsight, не реклама!) во время сборки
  2. как писать unit-тесты на Delphi (увы, некоторым приходится объяснять ))). И запускать их в пайплане сборки )
  3. как "прикрутить" сборку Delphi-проектов к GitLab CI
  4. а также, как можно использовать отладчик WinDbg, например, для поиска причин сбоя/падения приложений из-за библиотек, написанных на Delphi (ну, конечно же, как при этом интегрировать формирование необходимых для этого PDB-файлов в автосборку)

З.Ы. Буду рад ответить на любые вопросы, в том числе, в телеграме, как в личке, так и в чатах @Delphi_Lazarus и @DelphiCommunity

Использование компилятора Delphi (dcc32.exe) - 2. Компиляция

Содержание материала

  • Использование компилятора Delphi (dcc32.exe)
  • Вопросы реализации.
  • 1. Генерация кода
  • 2. Компиляция
  • 3. Диагностика ошибок
  • 4. Исполнение кода
  • 5. Взаимодействие с DLL
  • Пример реализации
  • Все страницы

После того , как исходный код создан , требуется его откомпилировать . Компилятор dcc32 замечательно подходит для этой роли - он очень быстрый , качественный и объединяет в себе все , что необходимо для построения exe- файлов , dll- библиотек и пакетов . Размер файла dcc32.exe ( версия 12.0, из Delphi 5) всего 545 Кб , ранние версии имеют еще меньший размер . К нему нужно добавить только три файла - rlink32.dll, sysinit.dcu и system.dcu ( это минимум ). Компилятор и указанные файлы можно разместить в подкаталоге прикладной программы , например , bin. Генерировать текст целесообразно в подкаталоге компилятора , например , bin\pas, чтобы использовать короткие пути файлов и не засорять каталог компилятора .

Для вызова dcc32.exe в библиотеке DccUsing определена функция ExecDcc32. Она устанавливает текущий каталог , создает файл для перехвата ошибок компиляции , вызывает компилятор , дожидается завершения компиляции и определяет наличие ошибок .

function ExecDcc32( const aDccDir, aOptions,

aProjectPath, aErrorPath: String ;

aCheckPaths: Boolean = False): Boolean;

// сохранение текущего каталога и установка нового

if not SetCurrentDir(DccDir) then

raise Exception.Create(SCantChangeDir + DccDir);

// установки атрибутов безопасности

with SecurAtt do begin

// разрешить наследование дочернему процессу

// создание файла, в который будут направляться ошибки

hStdOut := CreateFile(PChar(aErrorPath), GENERIC_ WRITE , 0 ,

@SecurAtt, CREATE_ALWAYS, FILE _ATTRIBUTE_NORMAL, 0 );

if hStdOut = INVALID_HANDLE_VALUE then

raise Exception.Create(SCantCreateFile + aErrorPath);

// заполнение структуры, специфицирующей создание процесса

with StartupInfo do begin

// скрывать окно компилятора и наследовать потоки ввода-вывода

dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;

// создать и стартовать процесс компилятора

s := 'dcc32.exe ' + aOptions + ' ' + aProjectPath;

if not CreateProcess( 'dcc32.exe' , PChar(s), @SecurAtt, @SecurAtt,

BOOL(True), 0 , nil , PChar(DccDir), StartupInfo, ProcessInfo) then

raise Exception.Create(SCantCreateProcess + 'dcc32.exe' );

// ждать завершение компиляции неопределенное время

// получить результат компиляции

result := ResultCode = 0 ;

// закрыть файл ошибок

if hStdOut <> INVALID_HANDLE_VALUE then

// восстановить прежний каталог по умолчанию

Компилятору , вместе с исходным файлом ( файлами ), нужно также передать файл проекта (dpr) и уточнить в опциях , что же будет результатом компиляции . Возможных вариантов много - GUI или консольное приложение , dll, пакет , ActiveX ( наверное , есть еще варианты ). Выбор вида компиляции связан со спецификой задачи , требованиями пользователя и вкусами разработчика . К этому вопросу я еще раз вернусь в разделе Исполнение кода .

Помогите пожалуйста, как можна в Делфи скомпилировать свою программу в единый exe файл, чтобы.

Мы поддерживаем старое приложение написанное с использованием С++ Буилдер 5.5 (ЕХЕ) и Буилдер.

Уважаемый автор, гуглю уже который день и у Вас как у всех "кидаем.." "даже не создаем проект".

Доброе время суток! Пишу приложение в C++ Builder6 для формирования файлов Excel. Требуется.

Достали, Эта статья не о плагинах а о подключении dll и возможности использования ресурсов в.

Есть приложение скомпилированное в Delphi6. Для построения отчетов я использовал компонеты из.

Как напечатать на принтер вертикальные и горизонтальные строки, например, нарисовать заголовки.

Справедливости ради, следует заметить, что большинство новшеств, описанных в статье появилось в.

Ситуация: Перетаскиваю приложение с Delphi 6 на Delphi 2010 под Windows 7. Приложение работает.

Как выделить строку в DBGrid (dgRowSelect=true), которая соответствует текущей записи в наборе.

при реализации экспорта ключевой пары появляеться ошибка MessageDlg('Ошибка получения размера.

Подскажите пожалуйста как сделать чтобы база данных содержала поле с изображением (*.jpg) при.

Вы автора забыли указать. Не нарушайте закон об авторском праве.

Братва! Если кто может что нибудь путное посоветовать, посоветуйте! Проблема такая - написал.

Помогите плиз. Нужно написать программу которая бдет отслеживать запущенные приложения на.

Необходимо проверить пустое ли поле типа Дата в SQL запросе TQuery.(Borland Delphy 5 ). Свойство.

Куда подевался DefineIT - ни новых версий, ни старых на сайте

Добро все. Второй день мучаюсь с Delphi/DBExpress. Написанная програмка работает только на.

Доброго дня или вечера. Комрады и господа, поможите кто знает. Проблема в.

Можно ли на delphi 10 lite делать коммерческие программы?

Кто силен, подскажите! Пробовал установить Builder с диска от Alex Soft (до этого дисками этой.

Среда - Borland C++. Элемент формы Button имеет обработчик события на Clic где код работы с.

Отличная новость - StarTeam Express Edition - бесплатен до 10 пользователей. Ссылка.

Встроенная утилита для мерджа файлов не очень то функциональна, как можно подключить внешнюю.

Срочно нужна библиотека из сабжа. Как ни странно стандартная установка произошла без нее.

Подскажите, plz, как в Rave Reports в Delphi7 программно скрыть кнопки Save, Open и т.п.

Базы данных .gdb были созданы для работы с interbase 5.1. При инсталяции программного продукта.

Помагите реализовать программу конвертер графических файлов на Delphi. 1. Конвертирование BMP.

А как определить текущее дату/время сервера InterBase?

Нужно создать таблицу в Ворде из Дельфей через WordApplication и поместить туда текст. Простой.

как узнать серийный номер CD в CD-ROM и если мою прогу переписали на другой CD то не запускать.

Уважаемый народ, ПОМОГИТЕ. Пишу прогу на СУБЖ, необходим runtime вызов компонента (своего.

Подскажите, как лучше организовать учет тестирования требований в CaliberRM - заводить новые.

Подскажите, пожалуйста, если ли среди продуктов Borland/Microfocus продукты для багтрекинга.

Добрый день! Подскажите, как SilkPerformer определяет загрузку сервера (например UNIX), если у.

Пишу многоуровневое приложение – не пойму, в чем дело. Помогите, кто знает. Использую.

Помогите разобратся с компанентом TWebConnection (D6) +SSL Пример работы и доки. Можно ли.

Кто знает что это за ошибка такая: SQL erroe code = -502 "Declared cursor already.

Есть ли возможность перейти? Все предыдущие проекты были на VSS6.0d. На сайте у борланда нету.

наверно тут какая то ошибка, статья должна была называться "Работа с массивами". Динамический.

Приветствую всех. У нас стоит задача- снять фотоизображение с web-камеры. А программа.

У меня такая проблема: программа, написанная на Delphi работает с dbf-файлом. Иногда происходит.

Похожая фигня. Не могу создавать Win32 Application. При загрузке С++Builder6 выдает.

1) Код: Reg:=TRegIniFile.Create; в первом примере должен быть заменен на.

Что у Борланда есть из средств тестирования, есть ли поддержка автоматизированного тестирования.

Читайте также: