Каталог расширений

Популярные теги

3gp       avi       fb2       jpg       mp3       pdf      

Как открыть исходный код exe файла


Как отлаживать и профилировать любой EXE-файл с помощью Visual Studio

Вам когда-нибудь нужно было отлаживать или профилировать исполняемый файл (файл .exe), для которого у вас нет исходного кода или вы не можете его собрать? Тогда наименее известный тип проекта Visual Studio, проект EXE, для вас!

В Visual Studio вы можете открыть любой EXE-файл как «проект». Просто перейдите в Файл -> Открыть -> Проект/Решение и перейдите к файлу .exe . Как если бы это был файл .sln . Visual Studio откроет этот EXE-файл как проект. Эта функция существует уже давно. Она работает на всех поддерживаемых в настоящее время версиях Visual Studio, и документация по ней находится на странице Отладка приложения, которое не является частью решения Visual Studio.

 

Отладка


Как и в обычном проекте, вы можете начать отладку с помощью F5, которая запустит EXE и подключит отладчик. Если вы хотите отладить запуск, вы можете запустить с помощью F11, который запустит EXE и остановится на первой строке пользовательского кода. Оба эти параметра доступны в контекстном меню для проекта EXE в окне Solution Explorer, как показано ниже:

Для отладки понадобятся символы, файлы PDB, для EXE и любых DLL, которые нужно отладить. Visual Studio будет следовать тому же процессу и попытается получить символы также, как и при отладке обычного проекта. Поскольку маловероятно, что файлы PDB были распространены вместе с EXE-файлом, возможно, вы захотите найти их в сборке или, что еще лучше, на сервере символов. Дополнительную информацию и рекомендации по использованию символов можно найти в этом блоге.

Для эффективной отладки вам также понадобится исходный код, который использовался для сборки EXE, или даже для нескольких файлов, которые вас интересуют. Вам нужно найти эти файлы и открыть их в Visual Studio. Если исходный код не совпадает с исходным кодом, который был собран, EXE Visual Studio предупредит вас, когда вы попытаетесь вставить точку останова, и точка останова не будет привязана. Это поведение может быть изменено в окне Settings peek window. В окне просмотра параметров щелкните текст ссылки Must match source, а затем установите флажок, чтобы разрешить несоответствующий источник, как показано ниже. Конечно, с несоответствующим источником вы никогда не знаете, что произойдет, так что используйте это только на свой страх и риск.

Если EXE был собран с SourceLink, то информация об источнике будет включена в PDB, и Visual Studio попытается загрузить источник автоматически. Это действительно хорошая причина использовать SourceLink с вашими проектами. Даже если у вас есть локальный набор, у вас может не быть той версии, которая использовалась для сборки двоичного файла. SourceLink — ваш надежный способ убедиться, что правильный источник связан с правильным двоичным файлом.

Если вы не можете получить исходный код, у вас еще есть несколько вариантов:

  1. Используйте инструмент для декомпиляции сборок обратно в C#, который вы можете перекомпилировать в новую сборку, чтобы исправить старую.
    1. ILSpy — отличный выбор для этого, но есть и множество других хороших платных и бесплатных инструментов.

  2. Используйте окно инструмента «Disassembly» в Visual Studio.
    1. Документ Source Not Found содержит ссылку на view disassembly. Имейте в виду, что если вы привыкли к отладке кода на C#, представление о разборке (view disassembly) является крайним средством.


Наконец, если вам нужно передать какие-либо аргументы в отлаживаемый EXE-файл, вы можете настроить их вместе с другими параметрами на странице Свойства проекта (Щелкните правой кнопкой мыши -> Свойства в узле проекта в обозревателе решений).

Профилирование


Вы также можете использовать инструменты профилирования с EXE-файлом, запустив их из Отладка -> Профилирование производительности. На странице запуска инструментов профилирования вы можете выбрать, какие инструменты использовать против EXE. Дополнительную информацию о профилировании можно найти в этих документах ( https://docs.microsoft.com/en-us/visualstudio/profiling/profiling-feature-tour?view=vs-2019).

Заключение


Вот и все. Краткий обзор того, как вы можете использовать Visual Studio для отладки и профилирования приложений, которые вы не создаете и которые могут даже не иметь исходного кода. В следующий раз, когда вам понадобится отладить или профилировать EXE-файл, не забудьте, что вы можете открыть его как решение в Visual Studio!

как посмотреть код проги по exe файлу?

 
1000times ©   (2006-09-19 20:35) [0]

собственно сабж


 
GanibalLector ©   (2006-09-19 20:37) [1]

нажимаешь F3 в Total Commander и наслождаешся ;)


 
SergP ©   (2006-09-19 20:46) [2]

> [1] GanibalLector ©   (19.09.06 20:37)
> нажимаешь F3 в Total Commander и наслождаешся ;)

А если в шестнадцатеричном виде нужно, то после F3 нужно F4 нажать


 
anton773 ©   (2006-09-19 21:10) [3]

Если интересуют рисунки и текст на кнопочках (менюшках) то ресторатор или exescop тебе в помощь


 
SergP ©   (2006-09-19 21:13) [4]

> [2] SergP ©   (19.09.06 20:46)
> > [1] GanibalLector ©   (19.09.06 20:37)
> > нажимаешь F3 в Total Commander и наслождаешся ;)
>
>
> А если в шестнадцатеричном виде нужно, то после F3 нужно
> F4 нажать

Ой, блин... Это если в ФАР. А в Тотал Командере нужно 3 нажать.


 
1000times ©   (2006-09-19 21:19) [5]

просто хотелось подсмотреть как некоторые функции и процедуры реализовывались :)


 
TUser ©   (2006-09-19 21:19) [6]

В общем случае - никак, кроме приколов.


 
1000times ©   (2006-09-19 21:26) [7]

печально прийдеться тогда заново изобретать велосипед, а времени мало :(


 
Весь в делах   (2006-09-19 21:27) [8]

Воспользуйся дизассемблером


 
1000times ©   (2006-09-19 21:42) [9]

спасибо всем, буду пытаться дизассемблировать :)
только там вроде кривовато получаеться


 
1000times ©   (2006-09-19 22:07) [10]

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


 
ArtemESC ©   (2006-09-19 22:09) [11]

1000times ©   (19.09.06 22:07) [10]
 Какой еще листинг с адресами, должен быть ассемблерный код...


 
1000times ©   (2006-09-19 22:14) [12]

оо прошу прощения в 5 утра подтупляю конечно же ассемблерный код, извеняюсь за назойливость и нубство, а как его переделать в код дельфи?


 
Весь в делах   (2006-09-19 22:20) [13]

НИКАК


 
Kolan ©   (2006-09-19 22:46) [14]


> 1000times ©   (19.09.06 22:14) [12]

Не трать время, ничего не получится...


 
ProgRAMmer Dimonych   (2006-09-19 22:51) [15]

Слышал я, кажись, декомпилер для Дельфей есть, DeDe именуемый. В Yahoo! на запрос DeDe download выдаёт кучу ссылок. Наверное, какая-нибудь поможет.


 
RASkov   (2006-09-19 23:26) [16]

> [13] Весь в делах   (19.09.06 22:20)

Ну это уж больно громко сказано

> [12] 1000times ©   (19.09.06 22:14)

Это можно, но нужно знать ассемблер и суметь выудить из дизассемблированного листинга программы то что тебе надо. Там ведь (в exe) помимо того что пишет программист на Delphi есть еще уйма кода, зачастую больше даже чем написано программером, который вставляет IDE.


 
DrPass ©   (2006-09-19 23:37) [17]


> ProgRAMmer Dimonych   (19.09.06 22:51) [15]
> Слышал я, кажись, декомпилер для Дельфей есть, DeDe именуемый

...который тоже декомпилирует в ассемблерный код :)


 
ProgRAMmer Dimonych   (2006-09-19 23:57) [18]

Для [17]
Во, блин! А я уже и скачивать собирался! Спасибо за ценную информацию.

Да, ещё прога есть такая, при взломе программ можно использовать, IDA называется (Interactive Disassembler). Я пользовался версией 3.7. Что мне нравится, там можно в настройках покопаться, чтобы она (IDA) распознавала отдельные хитрости разных компиляторов (там и VCL, и MFC, и ещё всякого)...


 
KilkennyCat ©   (2006-09-20 00:00) [19]

мда-а....


 
Весь в делах   (2006-09-20 06:54) [20]


> ProgRAMmer Dimonych

В принципе можно скачать, я когда-то изучал программы по нему, не код, а само визуальное оформление. Также можно узнать какие компоненты были использованы при создании приложения. Декомпилит не только приложения Делфи, но и Borland C.


 
Elen ©   (2006-09-20 08:40) [21]


> просто хотелось подсмотреть как некоторые функции и процедуры
> реализовывались :)

Пиши в Делфи функции ставь бряки и смотри код асма в Делфийском Дебуггере CPU.
А это правда из любопытства или бяку задумали?...


 
Весь в делах   (2006-09-20 09:19) [22]


> Elen ©

Скорее всего реализацию слизать хочет


 
Elen ©   (2006-09-20 09:23) [23]


> Весь в делах

А не выйдет. Не так просто. Мне когда-то тоже хотели навесить восстановление прогу из дизасма, сделанного когда-то с рабочего варианта.
Вовремя мастера отговорили. Шиш получится...


 
Наиль ©   (2006-09-20 09:35) [24]


> Шиш получится...

Получится, получится ... лет этак через 10 закончит.


 
Весь в делах   (2006-09-20 09:47) [25]


> Наиль ©

А может он там не один?


 
Elen ©   (2006-09-20 09:58) [26]


>  лет этак через 10 закончит

Ага! Световых ;-). Сначала нужно мануалы порулить


> А может он там не один?

Да хоть легион... без мануалов никуда.


 
Игорь Шевченко ©   (2006-09-20 10:49) [27]


> Шиш получится...

У кого шиш, у кого не шиш. Большую программу нет смысла восстанавливать - времени уйдет больше, чем на написание своей, а фрагменты - почему бы и нет ?


 
Elen ©   (2006-09-20 10:52) [28]


> Игорь Шевченко

Это да, но нужно еще и значь что и как делать, а судя по сабжу автор далек от этого (без обид)


извлекаем ресурсы или запускаем файлы под Windows, Linux и Mac OS

Формат exe – это исполняемый файл, который используется в данном виде еще с далеких времен первой ОС DOS. Бывают ситуации, когда нужно открыть такой файл для редактирования. Какой программой можно воспользоваться в таком случае и как это вообще можно сделать, будет сказано далее.

Где используется формат EXE

Такие файлы использовались ранее и существуют сейчас в таких ОС, как MS-DOS, OS/2, Windows, Symbian и OpenVMS. Такие файлы задействуются в 16-, 32- и 64-разрядных ОС.

Основной частью файла exe является исполняемый код, но в дополнение к нему там могут содержаться такие элементы графики, как иконки, и другие данные. Поэтому в большинстве случаев никакой дополнительной программой пользоваться не придется — exe сам по себе программа. Однако есть ряд случаев, когда все же необходимо залезть в сам исполняемый файл. Что делать в таком случае?

Программы для работы с форматом EXE

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

При помощи Resource Hacker можно открыть и вытянуть информацию и ресурсы из EXE файла — иконки, версии, и другие

Resourse Hacker (сокращенно — Reshack). Это приложение бесплатное, и его размер всего 545 кб. В этой программке можно менять такие элементы, как курсоры, и конки и проч., но доступа к программному коду она не дает. То же самое можно сделать в программе Resource Tuner.

При попытке открыть файл EXE, вы можете столкнуться с тем, что программа будет выдавать одно из сообщений о ошибке:

  1. Файл сжат упаковщиком или поврежден. Действительно, файлы часто бывают сжаты, так как разработчики стремятся уменьшить их объем. Resource Tuner может осуществить распаковку только наиболее популярного упаковщика – UPX. Другие упаковщики программа не поддерживает, поэтому файл вам придется распаковывать самостоятельно.
  2. Файл — 16-битный NE Executable. Такие файлы не поддерживаются, и открыть их не удастся.
  3. Файл не является исполняемым. Даже если у файла, который не является исполняемым, будет расширение exe, программа выдаст данную ошибку. Ведь расширение могли поменять специально.

Файлы exe используются для распространения вирусов, в частности, троянов. Поэтому при открытии таких файлов соблюдайте осторожность и не забывайте проводить сканирование системы, например, с помощью бесплатной лечащей утилиты Dr.Web CureIt.

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

Какие файлы не стоит открывать в редакторах ресурсов

  1. EXE более гигабайта величиной. В программе установлены ограничения – образ открываемого файла должен разместиться в пределах первого гигабайта памяти.
  2. Файлы, которые создавались в Visual Basic. Секция ресурсов таких файлов содержит только иконку и номер версии. Сам код на VB находится в специальном формате, который не откроется в редакторе ресурсов.
  3. Установщики других программ. В ресурсах хранятся только номер версии и иконка. Внутри таких файлов находится контейнер, который содержит другой, сжатый файл EXE, и программу-распаковщик. Кроме того, для сохранения данных в таких программах используются разные технологии.
  4. Самораспаковывающиеся архивы в виде exe-шников. Это просто архивированная информация и программа для ее распаковки.

Какие еще существуют программы для открытия exe

Другие распространенные программы, позволяющие открыть exe под Windows:

  • VMware ThinApp;
  • Microsoft Windows. Для открытия и работы с установочными файлами EXE ОС Windows пользуется программой под названием Windows Installer. Скачивать и устанавливать данный компонент вручную не придется — изначально он присутствует в операционной системе, а при необходимости обновить его это производится автоматически через центральный сервер обновлений Microsoft — WSUS;
  • IcoFX;
  • Microsoft Visual Studio. Среда для разработчиков с широким функционалом для написания приложений под Windows.

Если ваш ПК является «обладателем» Mac OS, то подойдут такие приложения:

  • Parallels Desktop 7, VMware Fusion 4, Oracle VM VirtualBox. Для использования функционала по работе с файлами формата EXE на любой из этих 3-х программ должна быть установлена Microsoft Windows. Т.е. фактически каждая такая программа — среда виртуализации, которая будет открывать и работать с exe файлами.
  • Darwine;
  • CrossOver;
  • Kronenberg WineBottler.

В Linux работают Cedega, Wine и DataFlex.

Если под операционную систему Linux при выборе, чем открывать exe файлы, вы остановитесь на Wine, то рекомендуем обратить внимание на версию от Ethersoft. В нее включен ряд модулей, которые ориентированы на запуск и работу с приложениями для бизнеса — 1С Предприятие и продукты Microsoft. Также хочется отметить, что Wine уже длительное время умеет стабильно работать с MS Office, включая текстовый редактор Word.

Итак, какой программой открывать exe, пользователь может выбрать сам. Каждая из них характеризуется различным функционалом, поэтому перед тем, как остановиться на каком-то одном приложении, стоит протестировать несколько программ.

Как посмотреть и редактировать исходный код open source программы

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

Несмотря на то, что открытый исходный код абсолютно точно можно назвать хорошим выбором, вам также надо будет инвестировать в «правильное» сообщество. Мы расскажем про сервис, который представляет собой один из лучших подобных ресурсов не только из-за огромной численности пользователей, но также и благодаря свойствам, которые предлагает система. Если вы найдете любую программу с открытым исходным кодом на GitHub, вам будет представлено несколько опций, включая просмотр, редактирование и создание форка (использование кодовой базы  в качестве старта для другого – прим. Wikipedia).

Создаем аккаунт

Перед тем, как начать пользоваться GitHub, следует создать аккаунт. Это можно сделать бесплатно, после чего у вас будет доступ ко множеству опций, включая форкинг. Он также предлагает различные уровни членства, кроме бесплатного (но для личного пользования вам с лихвой хватит и бесплатного аккаунта).

Просматриваем программу

Как только вы создадите аккаунт, вы сразу же можете приступать к рассмотрению приложений с открытым исходным кодом. Здесь вы можете видеть страницы приложений, включая папки и файлы, присущие приложению, сетевую графу, список запросов, проблемные места, wiki-страницу и другие графы. Очевидно, если вам небходимо будет увидеть код из файлов, кликните по ним, и перед вами предстанет полноценный исходный код. В зависимости от представленного кода, вам могут понадобиться фоновые знания различных языков программирования, на одно из которых может быть написана программа, будь то Java, C++, Python или какой-нибудь еще. Если вам до сих пор что-то не понятно, взгляните на представленный ниже скриншот:

Форкинг проекта

Редактирование кода требует несколько дополнительных этапов. Если вы хотите скопировать код без официального форкинга на GitHub, то скачайте файлы, а затем отредактировать их локально. Тем не менее, если вы хотите взять доступный код, и на его основе создать собственный проект, вам следует сделать форкинг. Форкинг можно сделать посредством зарегистрированного аккаунта –  нажмите «Fork» на странице, как показано на скриншоте. Следующие инструкции предназначены для пользователей Linux, которым нужно установить пакет Git для дальнейшей дистрибуции.

Если вы хотите получить файлы из репозитория на свой компьютер, вам нужно запустить команду git clone, заменив username на ваш логин в GitHub, а project_name на название приложения, с которого вы реализуете форкинг. Запустите эту команду в папке, которая должна содержать все  проекты, так как каждая команда git clone создает новую папку внутри той, с которой вы работаете. Это еще один способ скачать файлы, так как для этого не требуется авторизация. Теперь вы можете изменить файлы по собственному усмотрению, используя любой текстовый редактор или IDE. Что касается пользователей Linux, я порекомендовал бы Eclipse или Geany, так как они представляют собой отличные редакторы для программирования – Eclipse больше укомплектован функциями, а Geany более удобный. Пользователи Windows также могут воспользоваться родным GitHub-клиентом.

Загружаем изменения 

Как только вы закончите вносить правки, вы можете загрузить обновленные файлы обратно на Github посредством команды git push origin master, находясь внутри папки приложения. Это позволит перенести изменения в «источник» (на основе которого вы делаете личный), и в главную ветвь (стандартное расположение исходного кода).

Следим за потоком

Если вы хотели бы и дальше следить за развитием проекта, с которого вы использовали основу, то вам нужно добавить кое-что, что принято называть дополнительным удаленным. Это просто еще один ключ, который вы можете использовать, находясь внутри папки приложения. Чтобы создать новый удаленный проект, запустите команду git remote add upstream, где username нужно заменить на логин из исходног, а project_name нужно заменить на название его проекта.

Если вы заметили, что главный проект обновляется, и вы хотели бы принять эти правки, то нужно запустить команду git pull upstream после того, как будет создан дополнительный удаленный, и GitHub скачает и внесет изменения из основного в файлы вашего. Если все будет работать после запуска, вы можете сразу же запустить команду git push origin master, чтобы извлечь обновления для вашего собственного проекта.

Предлагаем редактирование

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

В завершение

GitHub – это невероятный инструмент с большим объемом открытого кода проектов, которыми уже пользуются многие разработчики. В то время, как этот сервис использует Git-утилиту, которую каждый может настроить на собственных серверах, сервис также включает в себя отличное сообщество разработчиков – неотъемлемую и важную часть открытого кода. Данное введение в курс дела должно помочь вам познакомиться с основами. Если вам хочется узнать больше о самом процессе разработки кода, вы можете взглянуть статью, в которой описываются лучшие сайты, помогающие изучить C++.

Использовали ли вы когда-нибудь этот сервис? О какой функции, как вы считаете, следует рассказывать людям в первую очередь? Пожалуйста, расскажите в комментариях!

Источник: http://god-sobaki.com

Алексей Повловский

Создаем EXE / Хабр

Самоизоляция это отличное время приступить к тому, что требует много времени и сил. Поэтому я решил заняться тем, чем всегда хотел — написать свой компилятор.

Сейчас он способен собрать Hello World, но в этой статье я хочу рассказать не про парсинг и внутреннее устройство компилятора, а про такую важную часть как побайтовая сборка exe файла.

Начало


Хотите спойлер? Наша программа будет занимать 2048 байт.

Обычно работа с exe файлами заключается в изучении или модификации их структуры. Сами же исполняемые файлы при этом формируют компиляторы, и этот процесс кажется немного магическим для разработчиков.

Но сейчас мы с вами попробуем это исправить!

Для сборки нашей программы нам потребуется любой HEX редактор (лично я использовал HxD).

Для старта возьмем псевдокод:

Исходный код
func MessageBoxA(u32 handle, PChar text, PChar caption, u32 type) i32 ['user32.dll'] func ExitProcess(u32 code) ['kernel32.dll'] func main() { MessageBoxA(0, 'Hello World!', 'MyApp', 64) ExitProcess(0) } 


Первые две строки указывают на функции импортируемые из библиотек WinAPI. Функция MessageBoxA выводит диалоговое окно с нашим текстом, а ExitProcess сообщает системе о завершении программы.
Рассматривать отдельно функцию main нет смысла, так как в ней используются функции, описанные выше.

DOS Header


Для начала нам нужно сформировать корректный DOS Header, это заголовок для DOS программ и влиять на запуск exe под Windows не должен.

Более-менее важные поля я отметил, остальные заполнены нулями.

Стуктура IMAGE_DOS_HEADER
Struct IMAGE_DOS_HEADER { u16 e_magic // 0x5A4D "MZ" u16 e_cblp // 0x0080 128 u16 e_cp // 0x0001 1 u16 e_crlc u16 e_cparhdr // 0x0004 4 u16 e_minalloc // 0x0010 16 u16 e_maxalloc // 0xFFFF 65535 u16 e_ss u16 e_sp // 0x0140 320 u16 e_csum u16 e_ip u16 e_cs u16 e_lfarlc // 0x0040 64 u16 e_ovno u16[4] e_res u16 e_oemid u16 e_oeminfo u16[10] e_res2 u32 e_lfanew // 0x0080 128 } 


Самое главное, что этот заголовок содержит поле e_magic означающее, что это исполняемый файл, и e_lfanew — указывающее на смещение PE-заголовка от начала файла (в нашем файле это смещение равно 0x80 = 128 байт).

Отлично, теперь, когда нам известна структура заголовка DOS Header запишем ее в наш файл.

(1) RAW DOS Header (Offset 0x00000000)
4D 5A 80 00 01 00 00 00 04 00 10 00 FF FF 00 00 40 01 00 00 00 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 



Уточнение

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

Поэтому для удобства в первой скобке каждого блока указан порядок добавления в файл, а в последней смещение в файле (Offset) по которому должен располагаться данный блок.

Например, первый блок мы вставляем по смещению 0x00000000, и он займет 64 байта (0x40 в 16-ричной системе), следующий блок мы будем вставлять уже по этому смещению 0x00000040 и т.д.

Готово, первые 64 байта записали. Теперь нужно добавить еще 64, это так называемый DOS Stub (Заглушка). Во время запуска из-под DOS, она должна уведомить пользователя что программа не предназначена для работы в этом режиме.

Но в целом, это маленькая программа под DOS которая выводит строку и выходит из программы.
Запишем наш Stub в файл и рассмотрим его детальнее.

(2) RAW DOS Stub (Offset 0x00000040)
0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68 69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F 74 20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20 6D 6F 64 65 2E 0D 0A 24 00 00 00 00 00 00 00 00 



А теперь этот же код, но уже в дизассемблированном виде Asm DOS Stub
0000 push cs ; Запоминаем Code Segment(CS) (где мы находимся в памяти) 0001 pop ds ; Указываем что Data Segment(DS) = CS 0002 mov dx, 0x0E ; Указываем адрес начала строки DS+DX, которая будет выводиться до символа $(Конец строки) 0005 mov ah, 0x09 ; Номер инструкции (Вывод строки) 0007 int 0x21 ; Вызов системного прерывания 0x21 0009 mov ax, 0x4C01 ; Номер инструкции 0x4C (Выход из программы) ; Код выхода из программы 0x01 (Неудача) 000c int 0x21 ; Вызов системного прерывания 0x21 000e "This program cannot be run in DOS mode.\x0D\x0A$" ; Выводимая строка 


Это работает так: сначала заглушка выводит строку о том, что программа не может быть запущена, а затем выходит из программы с кодом 1. Что отличается от нормального завершения (Код 0).

Код заглушки может немного отличатся (от компилятора к компилятору) я сравнивал gcc и delphi, но общий смысл одинаковый.

А еще забавно, что строка заглушки заканчивается как \x0D\x0D\x0A$. Скорее всего причина такого поведения в том, что c++ по умолчанию открывает файл в текстовом режиме. В результате символ \x0A заменяется на последовательность \x0D\x0A. В результате получаем 3 байта: 2 байта возврата каретки Carriage Return (0x0D) что бессмысленно, и 1 на перевод строки Line Feed (0x0A). В бинарном режиме записи (std::ios::binary) такой подмены не происходит.

Для проверки корректности записи значений я буду использовать Far с плагином ImpEx:

NT Header


Спустя 128 (0x80) байт мы добрались до NT заголовка (IMAGE_NT_HEADERS64), который содержит в себе и PE заголовок (IMAGE_OPTIONAL_HEADER64). Несмотря на название IMAGE_OPTIONAL_HEADER64 является обязательным, но различным для архитектур x64 и x86. Структура IMAGE_NT_HEADERS64
Struct IMAGE_NT_HEADERS64 { u32 Signature // 0x4550 "PE" Struct IMAGE_FILE_HEADER { u16 Machine // 0x8664 архитектура x86-64 u16 NumberOfSections // 0x03 Количество секций в файле u32 TimeDateStamp // Дата создания файла u32 PointerToSymbolTable u32 NumberOfSymbols u16 SizeOfOptionalHeader // Размер IMAGE_OPTIONAL_HEADER64 (Ниже) u16 Characteristics // 0x2F } Struct IMAGE_OPTIONAL_HEADER64 { u16 Magic // 0x020B Указывает что наш заголовок для PE64 u8 MajorLinkerVersion u8 MinorLinkerVersion u32 SizeOfCode u32 SizeOfInitializedData u32 SizeOfUninitializedData u32 AddressOfEntryPoint // 0x1000 u32 BaseOfCode // 0x1000 u64 ImageBase // 0x400000 u32 SectionAlignment // 0x1000 (4096 байт) u32 FileAlignment // 0x200 u16 MajorOperatingSystemVersion // 0x05 Windows XP u16 MinorOperatingSystemVersion // 0x02 Windows XP u16 MajorImageVersion u16 MinorImageVersion u16 MajorSubsystemVersion // 0x05 Windows XP u16 MinorSubsystemVersion // 0x02 Windows XP u32 Win32VersionValue u32 SizeOfImage // 0x4000 u32 SizeOfHeaders // 0x200 (512 байт) u32 CheckSum u16 Subsystem // 0x02 (GUI) или 0x03 (Console) u16 DllCharacteristics u64 SizeOfStackReserve // 0x100000 u64 SizeOfStackCommit // 0x1000 u64 SizeOfHeapReserve // 0x100000 u64 SizeOfHeapCommit // 0x1000 u32 LoaderFlags u32 NumberOfRvaAndSizes // 0x16 Struct IMAGE_DATA_DIRECTORY [16] { u32 VirtualAddress u32 Size } } } 


Разберемся что хранится в этой структуре: Описание IMAGE_NT_HEADERS64 Signature — Указывает на начало структуры PE заголовка

Далее идет заголовок IMAGE_FILE_HEADER общий для архитектур x86 и x64.

Machine — Указывает для какой архитектуры предназначен код в нашем случае для x64
NumberOfSections — Количество секции в файле (О секциях чуть ниже)
TimeDateStamp — Дата создания файла
SizeOfOptionalHeader — Указывает размер следующего заголовка IMAGE_OPTIONAL_HEADER64, ведь он может быть заголовком IMAGE_OPTIONAL_HEADER32.

Characteristics — Здесь мы указываем некоторые атрибуты нашего приложения, например, что оно является исполняемым (EXECUTABLE_IMAGE) и может работать более чем с 2 Гб RAM (LARGE_ADDRESS_AWARE), а также что некоторая информация была удалена (на самом деле даже не была добавлена) в файл (RELOCS_STRIPPED | LINE_NUMS_STRIPPED | LOCAL_SYMS_STRIPPED).

SizeOfCode — Размер исполняемого кода в байтах (секция .text)
SizeOfInitializedData — Размер инициализированных данных (секция .rodata)
SizeOfUninitializedData — Размер не инициализированных данных (секция .bss)
BaseOfCode — указывает на начало секции кода блок
SectionAlignment — Размер по которому нужно выровнять секции в памяти
FileAlignment — Размер по которому нужно выровнять секции внутри файла
SizeOfImage — Размер всех секций программы
SizeOfHeaders — Размер всех заголовков вместе (IMAGE_DOS_HEADER, DOS Stub, IMAGE_NT_HEADERS64, IMAGE_SECTION_HEADER[IMAGE_FILE_HEADER.NumberOfSections]) выровненный по FileAlignment
Subsystem — Указывает тип нашей программы GUI или Console
MajorOperatingSystemVersion, MinorOperatingSystemVersion, MajorSubsystemVersion, MinorSubsystemVersion — Говорят о том на какой системе можно запускать данный exe, и что он может поддерживать. В нашем случае мы берем значение 5.2 от Windows XP (x64).
SizeOfStackReserve — Указывает сколько приложению нужно зарезервировать памяти под стек. Этот параметр по умолчанию составляет 1 Мб, максимально можно указать 1Гб. Вроде как умные программы на Rust умеют считать необходимый размер стека, в отличии от программ на C++ где этот размер нужно править вручную.
SizeOfStackCommit — Размер по умолчанию составляет 4 Кб. Как должен работать данный параметр пока не разобрался.
SizeOfHeapReserve — Указывает сколько резервировать памяти под кучу. Равен 1 Мб по умолчанию.
SizeOfHeapCommit — Размер по умолчанию равен 4 Кб. Подозреваю что работает аналогично SizeOfStackCommit, то есть пока неизвестно как.

IMAGE_DATA_DIRECTORY — массив записей о каталогах. В теории его можно уменьшить, сэкономив пару байт, но вроде как все описывают все 16 полей даже если они не нужны. А теперь чуть подробнее.

У каждого каталога есть свой номер, который описывает, где хранится его содержимое. Пример:
Export(0) — Содержит ссылку на сегмент который хранит экспортируемые функции. Для нас это было бы актуально если бы мы создавали DLL. Как это примерно должно работать можно посмотреть на примере следующего каталога.

Import(1) — Этот каталог указывает на сегмент с импортируемыми функциями из других DLL. В нашем случае значения VirtualAddress = 0x3000 и Size = 0xB8. Это единственный каталог, который мы опишем.

Resource(2) — Каталог с ресурсами программы (Изображения, Текст, Файлы и т.д.)
Значения других каталогов можно посмотреть в документации.


Теперь, когда мы посмотрели из чего состоит NT-заголовок, запишем и его в файл по аналогии с остальными по адресу 0x80. (3) RAW NT-Header (Offset 0x00000080)
50 45 00 00 64 86 03 00 F4 70 E8 5E 00 00 00 00 00 00 00 00 F0 00 2F 00 0B 02 00 00 3D 00 00 00 13 00 00 00 00 00 00 00 00 10 00 00 00 10 00 00 00 00 40 00 00 00 00 00 00 10 00 00 00 02 00 00 05 00 02 00 00 00 00 00 05 00 02 00 00 00 00 00 00 40 00 00 00 02 00 00 00 00 00 00 02 00 00 00 00 00 10 00 00 00 00 00 00 10 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 B8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 


В результате получаем вот такой вид IMAGE_FILE_HEADER, IMAGE_OPTIONAL_HEADER64 и IMAGE_DATA_DIRECTORY заголовков:

Далее описываем все секции нашего приложения согласно структуре IMAGE_SECTION_HEADER

Структура IMAGE_SECTION_HEADER
Struct IMAGE_SECTION_HEADER { i8[8] Name u32 VirtualSize u32 VirtualAddress u32 SizeOfRawData u32 PointerToRawData u32 PointerToRelocations u32 PointerToLinenumbers u16 NumberOfRelocations u16 NumberOfLinenumbers u32 Characteristics } 


Описание IMAGE_SECTION_HEADER

Name — имя секции из 8 байт, может быть любым
VirtualSize — сколько байт копировать из файла в память
VirtualAddress — адрес секции в памяти выровненный по SectionAlignment
SizeOfRawData — размер сырых данных выровненных по FileAlignment
PointerToRawData — адрес секции в файле выровненный по FileAlignment
Characteristics — Указывает какие данные хранит секция (Код, инициализированные или нет данные, для чтения, для записи, для исполнения и др.)


В нашем случае у нaс будет 3 секции.

Почему Virtual Address (VA) начинается с 1000, а не с нуля я не знаю, но так делают все компиляторы, которые я рассматривал. В результате 1000 + 3 секции * 1000 (SectionAlignment) = 4000 что мы и записали в SizeOfImage. Это полный размер нашей программы в виртуальной памяти. Вероятно, используется для выделения места под программу в памяти.

 Name | RAW Addr | RAW Size | VA | VA Size | Attr --------+---------------+---------------+-------+---------+-------- .text | 200 | 200 | 1000 | 3D | CER .rdata | 400 | 200 | 2000 | 13 | I R .idata | 600 | 200 | 3000 | B8 | I R 

Расшифровка атрибутов:

I — Initialized data, инициализированные данные
U — Uninitialized data, не инициализированные данные
C — Code, содержит исполняемый код
E — Execute, позволяет исполнять код
R — Read, позволяет читать данные из секции
W — Write, позволяет записывать данные в секцию

.text (.code) — хранит в себе исполняемый код (саму программу), атрибуты CE
.rdata (.rodata) — хранит в себе данные только для чтения, например константы, строки и т.п., атрибуты IR
.data — хранит данные которые можно читать и записывать, такие как статические или глобальные переменные. Атрибуты IRW
.bss — хранит не инициализированные данные, такие как статические или глобальные переменные. Кроме того, данная секция обычно имеет нулевой RAW размер и ненулевой VA Size, благодаря чему не занимает места в файле. Атрибуты URW
.idata — секция содержащая в себе импортируемые из других библиотек функции. Атрибуты IR

Важный момент, секции должны следовать друг за другом. При чем как в файле, так и в памяти. По крайней мере когда я менял их порядок произвольно программа переставала запускаться.

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

(4) RAW Sections (Offset 0x00000188)
 2E 74 65 78 74 00 00 00 3D 00 00 00 00 10 00 00 00 02 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 00 00 60 2E 72 64 61 74 61 00 00 13 00 00 00 00 20 00 00 00 02 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 40 2E 69 64 61 74 61 00 00 B8 00 00 00 00 30 00 00 00 02 00 00 00 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 40 



Следующий адрес для записи будет 00000200 что соответствует полю SizeOfHeaders PE-Заголовка. Если бы мы добавили еще одну секцию, а это плюс 40 байт, то наши заголовки не уложились бы в 512 (0x200) байт и пришлось бы использовать уже 512+40 = 552 байта выровненные по FileAlignment, то есть 1024 (0x400) байта. А все что останется от 0x228 (552) до адреса 0x400 нужно чем-то заполнить, лучше конечно нулями.

Взглянем как выглядит блок секций в Far:

Далее мы запишем в наш файл сами секции, но тут есть один нюанс.

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

Поэтому программы компилируются в несколько проходов. Например секция .rdata идет после секции .text, при этом мы не можем узнать виртуальный адрес переменной в .rdata, ведь если секция .text разрастется больше чем на 0x1000 (SectionAlignment) байт, она займет адреса 0x2000 диапазона. И соответственно секция .rdata будет находиться уже не в адресе 0x2000, а в адресе 0x3000. И нам будет необходимо вернуться и пересчитать адреса всех переменных в секции .text которая идет перед .rdata.

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

Секция .text


Asm segment .text
0000 push rbp 0001 mov rbp, rsp 0004 sub rsp, 0x20 0008 mov rcx, 0x0 000F mov rdx, 0x402000 0016 mov r8, 0x40200D 001D mov r9, 0x40 0024 call QWORD PTR [rip + 0x203E] 002A mov rcx, 0x0 0031 call QWORD PTR [rip + 0x2061] 0037 add rsp, 0x20 003B pop rbp 003C ret 


Конкретно для этой программы первые 3 строки, ровно, как и 3 последние не обязательны.
Последние 3 даже не будут исполнены, так как выход из программы произойдет еще на второй функции call.

Но скажем так, если бы это была не функция main, а подфункция следовало бы сделать именно так.

А вот первые 3 в данном случае хоть и не обязательны, но желательны. Например, если бы мы использовали не MessageBoxA, а printf то без этих строк получили бы ошибку.

Согласно соглашению о вызовах для 64-разрядных систем MSDN, первые 4 параметра передаются в регистрах RCX, RDX, R8, R9. Если они туда помещаются и не являются, например числом с плавающей точкой. А остальные передаются через стек.

По идее если мы передаем 2 аргумента функции, то должны передать их через регистры и зарезервировать под них два места в стеке, что бы при необходимости функция могла скинуть регистры в стек. Так же мы не должны рассчитывать, что нам вернут эти регистры в исходном состоянии.

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

Поэтому если не хотите, чтобы программа себя странно вела, всегда резервируйте как минимум 8 байт * 4 аргумента = 32(0x20) байт, если передаете функции хотя бы 1 аргумент.

Рассмотрим блок кода с вызовами функций

MessageBoxA(0, 'Hello World!', 'MyApp', 64) ExitProcess(0) 

Сначала мы передаем наши аргументы:

rcx = 0
rdx = абсолютный адрес строки в памяти ImageBase + Sections[".rdata"].VirtualAddress + Смещение строки от начала секции, строка читается до нулевого байта
r8 = аналогично предыдущему
r9 = 64(0x40) MB_ICONINFORMATION, значок информации

А далее идет вызов функции MessageBoxA, с которым не все так просто. Дело в том, что компиляторы стараются использовать как можно более короткие команды. Чем меньше размер команды, тем больше таких команд влезет в кэш процессора, соответственно, будет меньше промахов кэша, подзагрузок и выше скорость работы программы. Для более подробной информации по командам и внутренней работе процессора можно обратиться к документации Intel 64 and IA-32 Architectures Software Developer’s Manuals.

Мы могли бы вызвать функцию по полному адресу, но это заняло бы как минимум (1 опкод + 8 адрес = 9 байт), а с относительным адресом команда call занимает всего 6 байт.

Давайте взглянем на эту магию поближе: rip + 0x203E, это ни что иное, как вызов функции по адресу, указанному нашим смещением.

Я подсмотрел немного вперед и узнал адреса нужных нам смещений. Для MessageBoxA это 0x3068, а для ExitProcess это 0x3098.

Пора превратить магию в науку. Каждый раз, когда опкод попадает в процессор, он высчитывает его длину и прибавляет к текущему адресу инструкции (RIP). Поэтому, когда мы используем RIP внутри инструкции, этот адрес указывает на конец текущей инструкции / начало следующей.
Для первого call смещение будет указывать на конец команды call это 002A не забываем что в памяти этот адрес будет по смещению Sections[".text"].VirtualAddress, т.е. 0x1000. Следовательно, RIP для нашего call будет равен 102A. Нужный нам адрес для MessageBoxA находится по адресу 0x3068. Считаем 0x3068 — 0x102A = 0x203E. Для второго адреса все аналогично 0x1000 + 0x0037 = 0x1037, 0x3098 — 0x1037 = 0x2061.

Именно эти смещения мы и видели в командах ассемблера.

0024 call QWORD PTR [rip + 0x203E] 002A mov rcx, 0x0 0031 call QWORD PTR [rip + 0x2061] 0037 add rsp, 0x20 

Запишем в наш файл секцию .text, дополнив нулями до адреса 0x400: (5) RAW .text section (Offset 0x00000200-0x00000400)
55 48 89 E5 48 83 EC 20 48 C7 C1 00 00 00 00 48 C7 C2 00 20 40 00 49 C7 C0 0D 20 40 00 49 C7 C1 40 00 00 00 FF 15 3E 20 00 00 48 C7 C1 00 00 00 00 FF 15 61 20 00 00 48 83 C4 20 5D C3 00 00 00 ........ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 

Хочется отметить что всего лишь 4 строки реального кода содержат весь наш код на ассемблере. А все остальное нули что бы набрать FileAlignment. Последней строкой заполненной нулями будет 0x000003F0, после идет 0x00000400, но это будет уже следующий блок. Итого в файле уже 1024 байта, наша программа весит уже целый Килобайт! Осталось совсем немного и ее можно будет запустить.


Секция .rdata


Это, пожалуй, самая простая секция. Мы просто положим сюда две строки добив нулями до 512 байт. .rdata
0400 "Hello World!\0" 040D "MyApp\0" 


(6) RAW .rdata section (Offset 0x00000400-0x00000600)
48 65 6C 6C 6F 20 57 6F 72 6C 64 21 00 4D 79 41 70 70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 


Секция .idata


Ну вот осталась последняя секция, которая описывает импортируемые функции из библиотек.

Первое что нас ждет новая структура IMAGE_IMPORT_DESCRIPTOR

Структура IMAGE_IMPORT_DESCRIPTOR
Struct IMAGE_IMPORT_DESCRIPTOR { u32 OriginalFirstThunk (INT) u32 TimeDateStamp u32 ForwarderChain u32 Name u32 FirstThunk (IAT) } 


Описание IMAGE_IMPORT_DESCRIPTOR

OriginalFirstThunk — Адрес указывает на список имен импортируемых функций, он же Import Name Table (INT)
Name — Адрес, указывающий на название библиотеки
FirstThunk — Адрес указывает на список адресов импортируемых функций, он же Import Address Table (IAT)


Для начала нам нужно добавить 2 импортируемых библиотеки. Напомним:
func MessageBoxA(u32 handle, PChar text, PChar caption, u32 type) i32 ['user32.dll'] func ExitProcess(u32 code) ['kernel32.dll'] 

(7) RAW IMAGE_IMPORT_DESCRIPTOR (Offset 0x00000600)
58 30 00 00 00 00 00 00 00 00 00 00 3C 30 00 00 68 30 00 00 88 30 00 00 00 00 00 00 00 00 00 00 48 30 00 00 98 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 


У нас используется 2 библиотеки, а что бы сказать что мы закончили их перечислять. Последняя структура заполняется нулями.
 INT | Time | Forward | Name | IAT --------+--------+----------+--------+-------- 0x3058 | 0x0 | 0x0 | 0x303C | 0x3068 0x3088 | 0x0 | 0x0 | 0x3048 | 0x3098 0x0000 | 0x0 | 0x0 | 0x0000 | 0x0000 

Теперь добавим имена самих библиотек: Имена библиотек
063С "user32.dll\0" 0648 "kernel32.dll\0" 


(8) RAW имена библиотек (Offset 0x0000063С)
 75 73 65 72 33 32 2E 64 6C 6C 00 00 6B 65 72 6E 65 6C 33 32 2E 64 6C 6C 00 00 00 00 


Далее опишем библиотеку user32: (9) RAW user32.dll (Offset 0x00000658)
 78 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 78 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4D 65 73 73 61 67 65 42 6F 78 41 00 00 00 


Поле Name первой библиотеки указывает на 0x303C если мы посмотрим чуть выше, то увидим что по адресу 0x063C находится библиотека «user32.dll\0».

Подсказка, вспомните что секция .idata соответствует смещению в файле 0x0600, а в памяти 0x3000. Для первой библиотеки INT равен 3058, значит в файле это будет смещение 0x0658. По этому адресу видим запись 0x3078 и вторую нулевую. Означающую конец списка. 3078 ссылается на 0x0678 это RAW-строка

«00 00 4D 65 73 73 61 67 65 42 6F 78 41 00 00 00»

Первые 2 байта нас не интересуют и равны нулю. А вот дальше идет строка с названием функции, заканчивающаяся нулем. То есть мы можем представить её как "\0\0MessageBoxA\0".

При этом IAT ссылается на аналогичную таблице IAT структуру, но только в нее при запуске программы будут загружены адреса функций. Например, для первой записи 0x3068 в памяти будет значение отличное от значения 0x0668 в файле. Там будет адрес функции MessageBoxA загруженный системой к которому мы и будем обращаться через вызов call в коде программы.

И последний кусочек пазла, библиотека kernel32. И не забываем добить нулями до SectionAlignment.

(10) RAW kernel32.dll (Offset 0x00000688-0x00000800)
 A8 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 A8 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 45 78 69 74 50 72 6F 63 65 73 73 00 00 00 00 00 00 00 00 00 00 00 ........ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 



Проверяем что Far смог корректно определить какие функции мы импортировали:

Отлично! Все нормально определилось, значит теперь наш файл готов к запуску.
Барабанная дробь…

Финал


Поздравляю, мы справились!

Файл занимает 2 Кб = Заголовки 512 байт + 3 секции по 512 байт.

Число 512(0x200) ни что иное, как FileAlignment, который мы указали в заголовке нашей программы.

Дополнительно:
Если хочется вникнуть чуть глубже, можно заменить надпись «Hello World!» на что-нибудь другое, только не забудьте изменить адрес строки в коде программы (секция .text). Адрес в памяти 0x00402000, но в файле будет обратный порядок байт 00 20 40 00.

Или квест чуть сложнее. Добавить в код вызов ещё одного MessageBox. Для этого придется скопировать предыдущий вызов, и пересчитать в нем относительный адрес (0x3068 — RIP).

Заключение


Статья получилась достаточно скомканной, ей бы, конечно, состоять из 3 отдельных частей: Заголовки, Программа, Таблица импорта.

Если кто-то собрал свой exe значит мой труд был не напрасен.

Думаю в скором времени создать ELF файл похожим образом, интересна ли будет такая статья?)

Ссылки:

Можно ли открыть exe файл архиватором и как это сделать

«.exe» — самый распространенный формат для установки программного обеспечения на пользовательский персональный компьютер. Также данный формат используется при создании самораспаковывающегося архивного файла в архиваторах WinRAR или 7 Zip.

«EXE» расширение – это сокращение слова «executable» с английского языка.

Google Translate: Executable – исполнимый, выполняемый, выполнимый, исполнимый

Получив такого рода файл, пользователь рискует получить неприятный сюрприз в виде вируса, вредоносного или шпионского ПО, даже если этот файл скачан с надёжного и проверенного источника. Именно поэтому многие квалифицированные специалисты рекомендуют предварительно просматривать содержимое файлов с разрешением «.exe» перед запуском/ инсталляцией. Иным причинам тоже может быть место в необходимости открытия файла в формате «.exe». Это могут быть разного рода причины: просмотр содержимого для достоверности в правильном получении, внесение изменений в состав архивного файла, извлечение только необходимых объектов и так далее.

Как открыть exe файл архиватором

Для открытия и предварительного просмотра содержимого архивного файла в формате «.exe», а не извлечения содержимого или начала установки той или иной программы, рекомендуется использовать самые популярные программы-архиваторы WinRAR или 7 Zip. Оба продукта достойны звания самых популярных программных обеспечений среди всех своих аналогов.

Чтобы именно открыть файл для просмотра, а не запуска, необходимо выбрать в диалоговом окне правильную функцию. Например, в архиваторе ВинРАР, нажав правой кнопкой мыши на исполняемом файле, надо выбрать не «Открыть»,

а опцию «открыть с помощью WinRAR».

Теперь можно безопасно просмотреть содержимое, добавить или удалить определённый файл, либо извлечь только интересующий объект.

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

Visual Studio от компании Microsoft с функционалом редактора исходного кода с технологией IntelliSense и элементарного перепроектирования кода.

Restorator — продукт от компании «Bome», для возможности редактировать файлы ресурсов.

ResHacker сокращение от Resource Hacker – этопрограмма-редактор, с помощью которой можно просматривать, извлекать и менять ресурсы в исполнимых файлах «EXE» для 32/64 битных версий Microsoft Windows OS.

ExeScope – утилита для предварительного просмотра и анализа содержимого файлов в формате «EXE», а также для возможности редактирования данных файлов.

Скачав и установив на своём персональном компьютере бесплатный архиватор 7-Zip или условно-бесплатный WinRAR, пользователь сможет решить поставленную перед ним задачу. Но не все файлы с разрешением «.exe» могут быть открыты для просмотра и редактирования содержимого. Поэтому не стоит останавливать свой выбор только на одном продукте. Для полноценной работы рекомендуется иметь целый арсенал разнофункциональных инструментариев.

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

Похожие материалы

[решено] Преобразование .exe в читаемый исходный код.

В дополнение к тому, что написал Сергей, и ответам на вопросы в вашем комментарии:

Цитата:

Вы говорите .Net Assemblies, я говорю .Net Application, одно и то же? Сборки
.Net - это либо исполняемые файлы (.exe), либо библиотеки динамической компоновки (.dll), которые используются исполняемыми файлами. Обычно вы относитесь к приложению как к целому продукту со всеми частями, которые ему необходимы для запуска, включая сборки .Net.

Цитата:

Хорошо, давайте будем простыми, я сделал приложение на C #.Net, и теперь у меня есть файл .exe, который я могу использовать для запуска всего приложения.
Итак, может ли кто-нибудь преобразовать его в читаемый исходный код, а затем настроить?
Теоретически да. На практике это, очевидно, требует усилий, и вопрос будет в том, будет ли кто-то достаточно мотивирован для этого. Предполагая, что вы говорите о потенциальных потерях дохода при продаже приложения: подумайте, будет ли кто-то, кто взломает ваше приложение, платным клиентом, если он не сможет этого сделать. Возможно нет. Однако есть меры, которые вы можете предпринять, чтобы увеличить количество усилий, необходимых для взлома вашего.] изменяет сборки вашего приложения таким образом, что становится значительно труднее разобраться в исходном коде, полученном в результате декомпиляции, некоторые даже предусматривают меры, чтобы значительно усложнить сам процесс декомпиляции. .

Как просмотреть исходный код .NET EXE

Если вы хотите просмотреть исходный код .NET EXE, выполните простые шаги. Вы можете легко получить актуальный код C ++ или C # любого .NET exe с помощью декомпиляции файла .NET exe.

Получение исходного кода .NET EXE

Ну, ребята, связанные с программным обеспечением и компьютерными науками, понимают эту концепцию. Это если мы работаем в .NET и компилируем код приложения, написанный на C ++ или C #. Затем после компиляции и сборки мы получаем .EXE файл .NET. Вы когда-нибудь задумывались, как мы можем вернуть исходный код полного приложения C ++ или C #?

Ну это называется декомпиляцией.NET-приложение. Есть определенные инструменты, которые могут его декомпилировать. Вы просто вводите файл .EXE, созданный с использованием .NET, а декомпилятор предоставит вам исходный код, написанный на любом языке .NET, например. C ++ или C #. Так что это считается угрозой безопасности. Это также поднимает вопрос о том, что мы должны обезопасить наш .NET exe, прежде чем передавать кому-либо на рассмотрение или тестирование.

Как просмотреть исходный код файла .NET EXE - шаги

Итак, давайте обсудим шаги, которые вам необходимо предпринять.Обратите внимание, что вы можете декомпилировать и просматривать только исходный код .NET exe. Он будет работать только с .EXE, которые созданы и скомпилированы с использованием библиотек .NET framework.

Шаг 1: Загрузите декомпилятор - .NET Reflector

Прежде всего вам необходимо загрузить программу, которая называется .NET Reflector. Этот инструмент предоставит вам полный исходный код .NET из файла .EXE. Он построен компанией Red Gate. Нажмите кнопку ниже, чтобы начать загрузку этого декомпилятора .NET.

Шаг 2: Установите.NET Reflector Application

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

Шаг 3. Откройте сборку .NET EXE в .NET Reflector

  • Откройте приложение .NET-отражателя.
  • Щелкните "Параметры файла".
  • Выберите "Открыть сборку".
  • Вы можете выбрать файл .EXE. (Обратите внимание, что этот .EXE должен быть скомпилирован ранее с использованием .NET framework).
  • После загрузки вы увидите все файлы и исходный код, написанный на VB, C ++ или C #.

ПРИМЕЧАНИЕ. Если вы видите красную ошибку с надписью «Not a .NET Module», то .EXE либо не является скомпилированным .NET файлом, либо он мог быть защищен с помощью какого-либо инструмента шифрования, такого как Themida.

Сообщите мне, если у вас возникнут проблемы с просмотром исходного кода .NET exe. Оставьте комментарий ниже, и мы свяжемся с вами. Программное обеспечение .NET Reflector также встроено в Visual Studio 2013. Интеграция может помочь быстро декомпилировать и просмотреть код exe-файла, скомпилированного с использованием dot net.

Последнее обновление этого сообщения: 8 августа 2020 г.

.

Как отлаживать и профилировать любой EXE с помощью Visual Studio / Корпоративный блог Microsoft / Хабр

Вам когда-нибудь приходилось отлаживать или профилировать исполняемый файл (файл .exe), для которого у вас нет исходного кода или который вы не можете собрать? Тогда наименее известный тип проекта Visual Studio - проект EXE - для вас!

В Visual Studio вы можете открыть любой EXE как «проект». Просто перейдите в File-> Open-> Project / Solution и перейдите к файлу .exe . Как если бы это был файл .sln .Затем Visual Studio откроет этот EXE как проект. Эта функция существует уже давно. Он работает во всех поддерживаемых в настоящее время версиях Visual Studio, а документация по нему находится в разделе «Отладка приложения, не являющегося частью решения Visual Studio».

Эта статья в нашем блоге.

Отладка


Как и в обычном проекте, вы можете начать отладку с помощью F5, которая запустит EXE и подключит отладчик. Если вы хотите отладить запуск, вы можете запустить его с помощью F11, который запустит EXE и остановится на первой строке пользовательского кода.Оба эти параметра доступны в контекстном меню проекта EXE в окне Solution Explorer , как показано ниже:

Для отладки потребуются символы, файлы PDB, EXE и любые библиотеки DLL, которые необходимо отладить. Visual Studio будет следовать тому же процессу, чтобы попытаться получить символы, что и при отладке обычного проекта. Поскольку маловероятно, что файлы PDB были распределены вместе с EXE, вы можете найти их при сборке или, что еще лучше, с сервера символов.Дополнительную информацию и рекомендации по использованию символов можно найти в этом блоге.

Для эффективной отладки вам также понадобится исходный код, который использовался для сборки EXE, даже для нескольких файлов, которые вам нужны. Вам нужно будет найти эти файлы и открыть их в Visual Studio. Если исходный код не совпадает с исходным кодом, который был создан, EXE Visual Studio предупредит вас, когда вы попытаетесь вставить точку останова, и точка останова не будет привязана. Это поведение можно отменить в окне обзора Breakpoint Settings .В окне просмотра настроек щелкните текст ссылки Должен соответствовать источнику , а затем установите флажок, чтобы разрешить несоответствие источника, как показано ниже. Конечно, с несоответствующим источником вы никогда не знаете, что произойдет, поэтому используйте его на свой страх и риск.

Если EXE был собран с включенным SourceLink, информация об источнике будет включена в PDB, и Visual Studio попытается загрузить исходный код автоматически. Это действительно хорошая причина использовать SourceLink в ваших проектах.Даже если у вас есть локальное зачисление, у вас может не быть той версии, которая использовалась для сборки двоичного файла. SourceLink - это ваш верный способ убедиться, что правильный источник связан с правильным двоичным файлом.

Если вы не можете получить исходный код, у вас все еще есть несколько вариантов:

  1. Используйте инструмент для декомпиляции сборок обратно в C #, который вы можете перекомпилировать в новую сборку, чтобы исправить старую.
    1. ILSpy - отличный выбор для этого, но есть много других хороших платных и бесплатных инструментов.

  2. Используйте окно инструмента «Разборка» в Visual Studio.
    1. В документе Source Not Found есть ссылка на view disassembly . Имейте в виду, что если вы используете для отладки кода C #, представление дизассемблирования - это крайний инструмент.


Наконец, если вам нужно передать какие-либо аргументы в отлаживаемый EXE, вы можете настроить их вместе с другими параметрами на странице Project Properties ( Right Click-> Properties на узле проекта в проводнике решений).

Профилирование


Вы также можете использовать инструменты профилирования с EXE, запустив их из Debug -> Performance Profiling . На странице запуска инструментов профилирования вы можете выбрать, какие инструменты использовать против EXE. Дополнительную информацию о профилировании можно найти в этих документах (https://docs.microsoft.com/en-us/visualstudio/profiling/profiling-feature-tour?view=vs-2019).

Заключение


Это оно. Краткий обзор того, как вы можете использовать Visual Studio для отладки и профилирования приложений, которые вы не создаете и для которых может даже не быть исходного кода.Итак, в следующий раз, когда вам потребуется отладка или профилирование EXE, не забудьте, что вы можете открыть его как Решение в Visual Studio! .

c - Как восстановить исходный код из исполняемого файла?

Переполнение стека
  1. Около
  2. Товары
  3. Для команд
  1. Переполнение стека Общественные вопросы и ответы
  2. Переполнение стека для команд Где разработчики и технологи делятся частными знаниями с коллегами
.

EXE Расширение файла - Что такое EXE-файл и как его открыть?

EXE-файл содержит исполняемую программу для Windows. EXE - это сокращение от «исполняемый файл», и это стандартное расширение файла, используемое программами Windows. Для многих пользователей Windows EXE-файлы являются синонимами программ Windows, что делает ".exe" одним из самых узнаваемых расширений файлов.

EXE-файлы содержат двоичный машинный код, скомпилированный из исходного кода. Машинный код сохраняется таким образом, что он может выполняться непосредственно центральным процессором компьютера, тем самым «запуская» программу.EXE-файлы могут также содержать ресурсы, такие как графические ресурсы для графического интерфейса пользователя, значок программы и другие ресурсы, необходимые программе.

На платформах, отличных от Windows, таких как macOS и Linux, EXE-файлы не используются для исполняемых файлов. Например, macOS использует файлы .APP для запуска приложений. Однако, если вы хотите запустить EXE-файл на платформе, отличной от Windows, вы можете использовать виртуальную машину, такую ​​как Parallels Desktop или VM VirtualBox, которая позволяет запускать Windows в среде, отличной от Windows.

В Windows, чтобы запустить программу, содержащуюся в EXE-файле, найдите файл в проводнике Windows и дважды щелкните его. (Однако, как мы предупреждаем ниже, не щелкайте файл дважды, если вы не можете проверить его легитимность.)

На компьютерах Mac вы можете использовать виртуальную машину Windows, созданную Parallels Desktop или VMware Fusion, для запуска программы, содержащейся в EXE-файле.

В Linux вы можете использовать виртуальную машину Windows, созданную Oracle VM VirtualBox, для запуска программы, содержащейся в EXE-файле, или вы можете использовать Wine, приложение, специально разработанное для того, чтобы пользователи могли запускать приложения Windows без установки Windows.

Файлы

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

.

Смотрите также