Как посмотреть исходный код программы?
Я хочу подправить исходный код, ничего серьезного, только вывод нескольких строк. Программа написана скорее всего на С++. Мне использовать отладчик? Или как-то открыть в IDE? Просто я не хочу запускать программу, хочу просто поковыряться в коде. И может посоветуете какой нибудь? P.S. Сам файл — .exe
Исходный код раскрыть невозможно если для этого постарались обеспечить безопасность (особенно если это фирменная вещь).
Но есть способы полностью или частично раскрыть код.
- IDA Pro — самый лучший из безплатных взломщиков, некоторые макросы возможно позволяют преобразовать код назад. Но не всегда. Особо хорошо раскрываются borland-продукты.
- Hiew.Exe бесплатная утилита, очень маленькая, позволяет править код на языке ассемблера. Можно править текстовые и целые константы. Можно ею даже сделать «перевод» программы на другой язык, затереть имя фирмы и т.п.
- Если есть PDB-файл, или подшита debug-info к файлу то код можно получить в среде разработки (если debug-info полная) редко можно использовать. Исходный код получить нельзя, но можно получить «номера строк и имена исходников», а так же имена/значения всех констант, локальных переменных, избежать «раздроблености функций» а так же получить классы с начинкой класса (почти все структуры кроме текста программы) что значительно упростит понимание работы программы. Для некоторых библиотек (dll) pdb-файлы можно скачать отдельно. Врядли уважающая себя фирма допустит утечку pdb своего стоящего продукта.
- Debug info, существует DebugInfo-информация встроеная в exe. Если есть такая информация, и соответствующая утилита (Например на Borland Delphi собран, и он есть в наличии), то можно сделать аналогичное предыдущему пункту. Но врядли уважающая себя фирма допустит такую «глупую» ошибку (аналогично pdb).
- Если файл написан на с# его можно почти полностью просмотреть в кодах с помощью disSharp (такие программы «подключают» в таблице импорта лишь mscorlib и всё). DisSharp плохо дизассемблирует некоторые части программы, но возможно его платная версия или платная версия подобных утилит раскрывает код лучше.
- Если файл написан на FoхPro, clipper и других подобный байт-кодовых языках — он раскрывается спец-утилитами (Refox например).
- Утилита exescope.exe ResourceHacker.exe и её-подобные утилиты позволяют смотреть шапку, подключенные библиотеки (по ним можно понять на чём писана программа) и редактировать ресурсы программы (ресурс-формы в.т.ч. delphi, иконки, картинки, таблицы ресурсо-строк).
- Если извесно чем создан код — думаю есть специальные утилиты способные его раскрыть (они платные и малодоступные).
Опять-же, это при условии что нету паковщика кода (тогда нужно сначала применить депаковщик), шифровальщика/самомодифицирующегося кода. Если не разбит обфускатором так что не распутать. Чем больше код — тем сложнее разобраться.
Вытаскиваем исходник C# из exe-файла
Рабочие компьютеры у меня меняются не так уж редко. И далеко не всегда переносится вся информация. Что-то кажется ненужным сейчас, но может понадобится в дальнейшем или просто интересно вспомнить. Так и произошло с программой «Запомни домино». На днях я просматривал исходники и не обнаружил её – и на самом деле, писал пару лет назад, все потерялось. Что ж, так как я никак не шифровал exe и знаю, на чем написано (C# Net 4.0) и нет нативного кода, то попробуем вытащить исходник.
Для этого мы воспользуемся программой .NET Reflector 8. По сути это очень хороший декомпилятор. Открываем с помощью её наш экзешник и видим кучу непонятного. Не стоит пугаться, все на самом деле очень просто. В самом низу левой панели наш открывшийся файл: пару кликов по дереву и оппа – мы открываем нашу Form1!
Правда, здесь пока только перечисление полей, но это уже что-то. Так как программа простенькая, то нам надо только найти обработчики кнопок. Кнопки всего две, немного поискав находи обработчик для первой:
Сложного здесь ничего нет. Берем число секунд, все делаем невидимым, затем рандомно вытаскиваем на свет божий необходимое число костяшек. Один интересный момент: почему-то я сделал не циклом и для каждой костяшки идет отдельный выбор, хотя все можно сократить. Видимо, я рассчитывал именно на три, как сейчас вспоминается и когда делал для четырех – просто добавил, не переделывая код.
И еще: в каждом выборе костяшки есть дополнительный цикл do while – чтобы первое число (верхней половины костяшки) было меньше нижней. Почему так? Смотрим в папку с изображениями: нумерация изображений сделана именно таким образом: от меньшего к большему – видимо, чтобы избежать повторения. Кстати, в программе не реализован поиск повторяющихся – но, видимо, мне этого и не надо было.
Ну и в конце запускаем таймер на нужное число секунд. Код таймер прост:
После этого обработчик другой кнопки
Здесь тоже все просто. Сначала показываем, что нужно показать и скрываем, что ненужно. Затем сравниваем введённый пользователем результат и правильный и выводим ответ. Кстати, упражнение интересное, в реальности так рекомендуется тренировать внимание.
Ну и вот так просто мы достали исходный код из программы на C# с помощью .NET Reflector 8. Таким образом, если вам требуется помочь посмотреть исходники exe файла, то вы всегда можете написать мне. За небольшую плату я вам с удовольствием помогу.
Автор этого материала — я — Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML — то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.
статьи IT, .NET Reflector, декомпиляция
«Хакер»: Учимся анализировать программы для x86 с нуля
Исследование исполняемого файла можно разделить на три этапа: поверхностный, глубокий, хирургический. На первом мы малыми силами собираем информацию о подопытном файле. Под «малыми силами» я подразумеваю легкие в использовании и широко распространенные средства анализа. В этой статье мы поговорим о них и для наглядности взломаем несложную защиту.
Пятнадцать лет назад эпический труд Криса Касперски «Фундаментальные основы хакерства» был настольной книгой каждого начинающего исследователя в области компьютерной безопасности. Однако время идет, и знания, опубликованные Крисом, теряют актуальность. Редакторы «Хакера» попытались обновить этот объемный труд и перенести его из времен Windows 2000 и Visual Studio 6.0 во времена Windows 10 и Visual Studio 2019. Результатом стал цикл статей.
Мы публикуем эту статью в честь начала предзаказов обновленной версии книги Криса, получившей новый подзаголовок: «Анализ программ в среде Win64». Оставить предзаказ на книгу, чтобы приобрести ее со скидкой 25%, вы можете на сайте издательства «Солон-пресс».
Этап 1
Если работа ведется в Linux, среди инструментов поверхностного анализа можно отметить такие приложения:
file определяет тип файла, анализируя его поля;
readelf отображает информацию о секциях файла;
ldd выводит список динамических библиотек, от которых зависит данный исполняемый файл;
nm выводит список декорированных имен функций, которые создаются компиляторами языков, поддерживающих перегрузку функций. Затем утилита может декодировать эти имена;
c++filt преобразует декорированные имена функций в первоначальные с учетом передаваемых и получаемых аргументов;
strings выводит строки, содержащиеся в файле, с учетом заданного шаблона.
В Windows со многими из этих задач справляется утилита dumpbin, входящая в поставку Visual Studio.
Если мы получили общее представление о файле и не нашли ничего полезного для взлома, есть смысл переходить к следующему этапу.
Этап 2
Второй этап — это дизассемблирование. Его цель — обнаружить защитный механизм. Существует два вида дизассемблирования: статическое и динамическое (более известное как отладка или трассировка). В первом случае изучается дизассемблерный код, полученный с помощью автоматического анализа дизассемблером исполняемого файла без его запуска.
Динамическое дизассемблирование предполагает запуск программы и ее пошаговое исполнение. Обычно отладка проходит в специальной и обособленной среде. Это нужно на случай, если программа представляет какую-то угрозу для системы.
В качестве отладчика в Linux можно воспользоваться старым добрым GDB либо средствами трассировки в Radare2. В Windows выбор тоже невелик: OllyDbg постепенно устаревает и не обновляется. В нем отлаживать приложения можно только в режиме пользователя. После смерти SoftICE единственным нормальным отладчиком в Windows стал WinDbg. В нем можно отлаживать драйверы на уровне ядра.
Статические дизассемблеры тоже делятся на две группы: линейные и рекурсивные. Первые перебирают все сегменты кода в двоичном файле, декодируют и преобразуют их в мнемоники языка ассемблера. Так работает большинство простых дизассемблеров, включая objdump и dumpbin. Может показаться, что так и должно быть. Однако, когда среди исполняемого кода встречаются данные, возникает проблема: их не надо преобразовывать в команды, но линейный дизассемблер не в состоянии отличить их от кода! Мало того, после того как сегмент данных завершится, дизассемблер будет рассинхронизирован с текущей позиции кода.
С другой стороны, рекурсивные дизассемблеры, такие как IDA Pro, Radare2 и Ghidra, ведут себя иначе. Они дизассемблируют код в той же последовательности, в которой его будет исполнять процессор. Поэтому они аккуратно обходят данные, и в результате большинство команд благополучно распознается.
Но и здесь есть ложка дегтя. Не все косвенные переходы легко отследить. Следовательно, какие-то пути выполнения могут остаться нераспознанными. Помогает то, что современные дизассемблеры применяют разные эвристические приемы с учетом конкретных компиляторов.
Этап 3
Когда адрес защитного механизма найден, можно приступать к третьему этапу — хирургическому. Существует несколько видов непосредственного взлома. Самый простой вариант — воспользоваться шестнадцатеричным редактором.
Существует множество HEX-редакторов на любой вкус и цвет, например 010 Editor, HexEdit, HIEW. Вооружайся одним из них, и тебе останется только перезаписать команду по найденному адресу. Но в двоичном файле сильно не разбежишься! Существующий код не дает простора для манипуляций, поэтому нам приходится умещаться в имеющемся пространстве.
Противопоказано раздвигать или сдвигать команды, даже выкидывать имеющиеся конструкции можно только с большой осторожностью. Ведь подобные манипуляции с кодом приведут к сдвигу смещений остальных команд, а указатели в таком случае будут указывать в космос!
Этим способом, однако, можно хакнуть большое количество защитных механизмов. А как быть, если надо не просто взломать программу, а добавить или заменить в ней какие-то функции? Понятно, что HEX-редактор тут тебе не друг.
Здесь на помощь приходит техника оснащения двоичного файла. Оно позволяет вставить почти неограниченный блок кода в почти любое место файла. Понятно, что без посторонних средств этого не добиться. Оснащение реализуют специальные библиотеки, предоставляющие гибкие API.
С помощью статического оснащения производится модификация файла непосредственно на диске. То есть бинарный файл сначала надо дизассемблировать, найти подходящее место, обладающее достаточным пространством для включения полезной нагрузки, и, внедряя потусторонний код, уследить, чтобы не поломались существующие указатели на код и данные. В этом деле призваны помочь такие инструменты, как Dyninst и PEBIL. После модификации файла он записывается в измененном виде обратно на диск.
Динамическое оснащение работает по другому принципу. Подобно отладчикам движки динамического оснащения следят за выполняемыми процессами и вносят код прямо в память. Поэтому при динамическом оснащении не нужно ни дизассемблирование, ни изменение бинарника, от чего одним махом исчезают все негативные последствия.
Однако во время динамического оснащения, так как программа выполняется «под наблюдением», ее производительность заметно падает. Для динамического оснащения используются системы DynamoRIO (совместный проект HP и MIT) и Pin (Intel).
Может показаться, что динамическое оснащение лучше во всех отношениях. А вот и нет! Такую программу нельзя будет исполнить на другом компьютере, где нет никаких специальных средств. Тогда как в процессе статического оснащения мы заранее готовим бинарник и передаем его пользователю. Теми же средствами могут пользоваться и злоумышленники, желающие заразить программу вирусом или снабдить какой-то подлой функцией.
Практический взлом
Чтобы поупражняться на практике, проведем анализ и раскусим элементарную защиту.
Алгоритм простейшего механизма аутентификации заключается в посимвольном сравнении введенного пользователем пароля с эталонным значением, хранящимся либо в самой программе (как часто и бывает), либо вне ее, например, в конфигурационном файле или реестре (что встречается реже).
Достоинство такой защиты — крайне простая программная реализация. Ее ядро состоит фактически из нескольких строк, которые на языке С/C++ можно записать так:
Давай дополним этот код процедурами запроса пароля и вывода результатов сравнения, а затем испытаем полученную программу на прочность, т. е. на стойкость к взлому.
Пример простейшей системы аутентификации:
В популярных кинофильмах крутые хакеры легко проникают в любые жутко защищенные системы, каким-то непостижимым образом угадывая искомый пароль с нескольких попыток. Почему бы не попробовать пойти их путем?
Не так уж редко пароли представляют собой осмысленные слова наподобие Ferrari, QWERTY, имена любимых хомячков, названия географических пунктов и т. д. Угадывание пароля сродни гаданию на кофейной гуще — никаких гарантий на успех нет, остается рассчитывать на одно лишь везение. А удача, как известно, птица гордая — палец в рот ей не клади. Нет ли более надежного способа взлома?
Раз эталонный пароль хранится в теле программы, то, если он не зашифрован каким-нибудь хитрым образом, его можно обнаружить тривиальным просмотром двоичного кода программы. Перебирая все встретившиеся в ней текстовые строки, начиная с тех, что больше всего смахивают на пароль, мы очень быстро подберем нужный ключ и откроем им программу! Причем область просмотра можно существенно сузить — в подавляющем большинстве случаев компиляторы размещают все инициализированные переменные в сегменте данных (в PE-файлах он размещается в секции .data или .rdata ). Исключение составляют, пожалуй, ранние компиляторы Borland с их маниакальной любовью всовывать текстовые строки в сегмент кода — непосредственно по месту их вызова. Это упрощает сам компилятор, но порождает множество проблем. Современные операционные системы, в отличие от старушки MS-DOS, запрещают модификацию кодового сегмента, и все размещенные в нем переменные доступны лишь для чтения. К тому же на процессорах с раздельной системой кеширования они «засоряют» кодовый кеш, попадая туда при упреждающем чтении, но при первом же обращении к ним вновь загружаются из медленной оперативной памяти в кеш данных. В результате — тормоза и падение производительности.
Что ж, пусть это будет секция данных! Остается только найти удобный инструмент для просмотра двоичного файла. Можно, конечно, нажать клавишу F3 в своей любимой оболочке (FAR, DOS Navigator) и, придавив кирпичом Page Down, любоваться бегущими циферками до тех пор, пока не надоест.
Можно воспользоваться любым HEX-редактором (QVIEW, HIEW. — кому какой по вкусу), но в данном случае, по соображениям наглядности, приведен результат работы утилиты dumpbin из штатной поставки Microsoft Visual Studio.
Натравим утилиту на исполняемый файл нашей программы, содержащей пароль, и попросим ее распечатать содержащую только для чтения инициализированные данные секцию — rdata (ключ /SECTION:.rdata ) в «сыром» виде (ключ /RAWDATA:BYTES ), указав значок > для перенаправления вывода в файл (ответ программы занимает много места, и на экране помещается один лишь «хвост»).
Среди всего прочего тут есть одна строка, до боли похожая на эталонный пароль. Испытаем ее? Впрочем, какой смысл — судя по исходному тексту программы, это действительно искомый пароль, открывающий защиту, словно золотой ключик. Слишком уж видное место выбрал компилятор для его хранения — пароль не мешало бы запрятать и получше.
Один из способов сделать это — насильно поместить эталонный пароль в собственноручно выбранную нами секцию. Такая возможность не предусмотрена стандартом, и потому каждый разработчик компилятора (строго говоря, не компилятора, а линкера, но это не суть важно) волен реализовывать ее по-своему или не реализовывать вообще. В Microsoft Visual C++ для этой цели предусмотрена специальная прагма data_seg , указывающая, в какую секцию помещать следующие за ней инициализированные переменные. Неинициализированные переменные по умолчанию располагаются в секции .bss и управляются прагмой bss_seg соответственно.
В примере аутентификации выше перед функцией main добавим новую секцию, в которой будем хранить наш пароль:
Внутри функции main проинициализируем массив:
Немного изменилось условие сравнения строк в цикле:
Натравим утилиту dumpbin на новый исполняемый файл:
Ага, теперь в секции данных пароля нет и хакеры «отдыхают»! Но не спеши с выводами. Давай сначала выведем на экран список всех секций, имеющихся в файле:
Нестандартная секция .kpnc сразу же приковывает к себе внимание. А ну-ка посмотрим, что там в ней.
Вот он, пароль! Спрятали, называется. Можно, конечно, извратиться и засунуть секретные данные в секцию неинициализированных данных ( .bss ) или даже секцию кода ( .text ) — не все там догадаются поискать, а работоспособность программы такое размещение не нарушит. Но не стоит забывать о возможности автоматизированного поиска текстовых строк в двоичном файле. В какой бы секции ни содержался эталонный пароль, фильтр без труда его найдет (единственная проблема — определить, какая из множества текстовых строк представляет собой искомый ключ; возможно, потребуется перебрать с десяток-другой потенциальных кандидатов).
Знакомство с дизассемблером
Пароль мы узнали. Но как же утомительно вводить его каждый раз с клавиатуры перед запуском программы! Хорошо бы ее хакнуть так, чтобы никакой пароль вообще не запрашивался или любой введенный пароль программа воспринимала как правильный.
Хакнуть, говорите?! Что ж, это несложно! Куда проблематичнее определиться, чем именно ее хакать. Инструментарий хакеров чрезвычайно разнообразен, чего тут только нет: и дизассемблеры, и отладчики, и API-, и message-шпионы, и мониторы обращений к файлам (портам, реестру), и распаковщики исполняемых файлов, и. Сложновато начинающему кодокопателю со всем этим хозяйством разобраться!
Впрочем, шпионы, мониторы, распаковщики — второстепенные утилиты заднего плана, а основное оружие взломщика — отладчик (динамический дизассемблер) и дизассемблер (статический).
Итак, дизассемблер применим для исследования откомпилированных программ и частично пригоден для анализа псевдокомпилированного кода. Раз так, он должен подойти для вскрытия парольной защиты passCompare1.exe. Весь вопрос в том, какой дизассемблер выбрать.
Не все дизассемблеры одинаковы. Есть среди них и «интеллектуалы», автоматически распознающие многие конструкции, как то: прологи и эпилоги функций, локальные переменные, перекрестные ссылки и т. д., а есть и «простаки», чьи способности ограничены одним лишь переводом машинных команд в ассемблерные инструкции.
Логичнее всего воспользоваться услугами дизассемблера-интеллектуала (если он есть), но. давай не будем спешить, а попробуем выполнить весь анализ вручную. Техника, понятное дело, штука хорошая, да вот не всегда она оказывается под рукой, и неплохо бы заранее научиться работе в полевых условиях. К тому же общение с плохим дизассемблером как нельзя лучше подчеркивает «вкусности» хорошего.
Воспользуемся уже знакомой нам утилитой dumpbin, настоящим «швейцарским ножиком» со множеством полезных функций, среди которых притаился и дизассемблер. Дизассемблируем секцию кода (как мы помним, носящую имя .text ), перенаправив вывод в файл, так как на экран он, очевидно, не поместится:
Заглянем еще раз в секцию данных (или в другую — в зависимости от того, где хранится пароль).
Запомним найденный пароль: myGOODpassword . В зависимости от версии и настроек дизассемблера dumpbin инициализированные переменные, к которым обращается код, могут быть представлены по-разному: на их месте могут быть или символьные константы, или непосредственно шестнадцатеричное смещение. Попробуем найти выявленный ранее пароль в дизассемблированном листинге тривиальным контекстным поиском с помощью любого текстового редактора.
Центральная часть этого листинга сравнивает значения регистров EAX и ECX. В последний, как мы видим в первой строке листинга, записывается эталонный пароль, следовательно, в первом — введенный пользователем. Затем происходит сравнение и выполняются переходы почти в одну и ту же точку: 0x4010A2 и 0x40109E . Интересно, что там. Заглянем:
Здесь центральную роль играет инструкция TEST EAX,EAX , размещенная по смещению 0x4010A7. Если EAX равен 0, следующая за ней команда JE совершает прыжок на 0x40110E.
В противном же случае (то есть если EAX !=0 ) происходит выталкивание на вершину стека строки «Wrong password».
А следом — вызов функции с говорящим названием:
Значит, ненулевое значение EAX свидетельствует о ложном пароле, а ноль — об истинном.
Тогда переходим к анализу валидной ветви программы, что делается после прыжка на 0x40110E. А тут притаилась инструкция, которая помещает строку «Password OK» на вершину стека, а после этого вызывается процедура _printf , которая, очевидно, выводит строку на экран:
Оперативные соображения следующие: если команду JE заменить JNE, то программа отвергнет истинный пароль как неправильный, а любой неправильный пароль воспримет как истинный. А если TEST EAX,EAX заменить XOR EAX,EAX , то после исполнения этой команды регистр EAX будет всегда равен нулю, какой бы пароль ни вводился.
Дело за малым — найти эти самые байтики в исполняемом файле и малость подправить их.
Примечание: если в секции кода эталонный пароль не находится, возможно, он скрывается за шестнадцатеричным смещением. Поэтому надо сначала заглянуть в секцию данных и узнать, по какому смещению он там находится.
Очевидно, нам надо выровнять смещение, чтобы пароль начинался с начала строки. Прибавим к смещению 8 — число символов, на которые надо сместить ( ssword:. ). В результате будем искать итоговое смещение — 402108 в секции кода. Тем самым мы найдем ту же самую инструкцию, что и прежде:
Только вместо символьной константы мы обнаруживаем шестнадцатеричное смещение в секции данных.
Хирургическое вмешательство
Как мы обсуждали выше, внесение изменений непосредственно в исполняемый файл — дело серьезное. Стиснутым существующим кодом, нам приходится довольствоваться только тем, что есть, и ни раздвинуть команды, ни даже сдвинуть их, выкинув из защиты «лишние запчасти», не получится. Ведь это привело бы к сдвигу смещений всех остальных команд, тогда как значения указателей и адресов переходов остались бы без изменений и стали бы указывать совсем не туда, куда нужно!
Ну, с «выкидыванием запчастей» справиться как раз таки просто — достаточно забить код командами NOP (опкод которой 0x90, а вовсе не 0x0, как почему-то думают многие начинающие кодокопатели), т. е. пустой операцией (вообще-то NOP — это просто другая форма записи инструкции XCHG EAX,EAX , если интересно). С «раздвижкой» куда сложнее! К счастью, в PE-файлах всегда присутствует множество «дыр», оставшихся от выравнивания, в них-то и можно разместить свой код или свои данные.
Но не проще ли просто откомпилировать ассемблированный файл, предварительно внеся в него требуемые изменения? Нет, не проще, и вот почему: если ассемблер не распознает указатели, передаваемые функции (а как мы видели, наш дизассемблер не смог отличить их от констант), он, соответственно, не позаботится должным образом их скорректировать, и, естественно, программа работать не будет.
Приходится резать программу вживую. Легче всего это делать с помощью утилиты HIEW, которая «переваривает» PE-формат файлов и упрощает тем самым поиск нужного фрагмента. Подойдет любая версия этого HEX-редактора. Например, я использовал далеко не самую новую версию 6.86, прекрасно уживающуюся с Windows 10. Запустим ее, указав имя файла в командной строке ( hiew32 passCompare1.exe ), двойным нажатием клавиши Enter, переключимся в режим ассемблера и при помощи клавиши F5 перейдем к требуемому адресу. Как мы помним, команда TEST, проверяющая результат на равенство нулю, располагалась по адресу 0x4010A7.
Чтобы HIEW мог отличить адрес от смещения в самом файле, предварим его символом точки: .4010A7 .
Ага, как раз то, что нам надо! Нажмем клавишу F3 для перевода HIEW в режим правки, подведем курсор к команде TEST EAX, EAX и, нажав клавишу Enter, заменим ее командой XOR EAX,EAX .
С удовлетворением заметив, что новая команда в аккурат вписалась в предыдущую, нажмем клавишу F9 для сохранения изменений на диске, а затем выйдем из HIEW и попробуем запустить программу, вводя первый пришедший на ум пароль:
Получилось! Защита пала! Хорошо, а как бы мы действовали, не умей HIEW «переваривать» PE-файлы? Тогда пришлось бы прибегнуть к контекстному поиску. Обратим свой взор на шестнадцатеричный дамп, расположенный дизассемблером слева от ассемблерных команд. Конечно, если пытаться найти последовательность 85 C0 — код команды TEST EAX, EAX , ничего хорошего из этого не выйдет — этих самых тестов в программе может быть несколько сотен, а то и больше. А вот адрес перехода, скорее всего, во всех ветках программы различен, и подстрока TEST EAX,EAX/JE 0040110E имеет хорошие шансы на уникальность. Попробуем найти в файле соответствующий ей код: 85 C0 74 63 (в HIEW для этого достаточно нажать F7).
Оп-с! Найдено только одно вхождение, что нам, собственно, и нужно. Давай теперь попробуем модифицировать файл непосредственно в HEX-режиме, не переходя в ассемблер. Попутно возьмем себе на заметку: инверсия младшего бита кода команды приводит к изменению условия перехода на противоположное, т. е. 74 JE → 75 JNE .
Работает? В смысле защита свихнулась окончательно — не признает истинные пароли, зато радостно приветствует остальные. Замечательно!
Как просмотреть исходный код .exe файла
Иногда возникает необходимость посмотреть код исполняемого файла .exe, например, если вы хотите узнать, как работает некоторая программа, переписать ее на другом языке программирования или проверить на наличие вредоносного кода.
Однако сам исходный код .exe файла недоступен для просмотра, ведь компилятор переводит исходный код на языке высокого уровня в машинный код, который и содержится в исполняемом файле.
В данной статье мы рассмотрим несколько методов, которые помогут вам просмотреть сгенерированный машинный код .exe файла и декодировать его обратно в исходный код на языке C, C++ или другом языке программирования.
Важно отметить, что эти методы не гарантируют 100% правильность и точность получаемого кода, так как некоторые секции и данные могут быть сжаты или изменены при компиляции.
Что такое .exe файлы
В операционных системах семейства Windows .exe файлы являются исполняемыми файлами. Эти файлы содержат программный код, который может быть запущен и выполнен на компьютере. Название .exe происходит от английского слова «executable», что означает «исполнимый».
Структура .exe файла
Структура .exe файла обычно состоит из заголовка файла и секций кода и данных. Заголовок файла содержит информацию о файле, такую как имя файла, размер файла и версию операционной системы, для которой предназначен файл. Секции кода и данных содержат фактический программный код, который делает что-то на компьютере.
Запуск .exe файла
Процесс запуска .exe файла начинается с загрузки файла в оперативную память компьютера. Затем процессор начинает выполнение кода из секции кода. Если все идет нормально, то программа может начать свою работу и выводить результаты на экран или выполнять другие задачи.
Для запуска .exe файла нужно дважды щелкнуть по файлу или использовать командную строку для запуска файла.
Несмотря на то, что .exe файлы являются исполняемыми файлами, просмотр их исходного кода не всегда возможен из-за особенностей компиляции кода в исполнимый файл.
Зачем нужно смотреть исходный код?
Понимание работы программы
Просмотр исходного кода позволяет понять, как программа работает, какие алгоритмы используются, какие функции вызываются и т.д. Понимание работы программы может помочь в дальнейшей работе с ней, например, при отладке или расширении функциональности.
Безопасность
Исходный код может содержать информацию о том, как программа обрабатывает данные, каковы ее уязвимости и как их эксплуатировать. Просмотр кода может помочь выявить и устранить уязвимости и повысить безопасность программы.
Учебные цели
Просмотр исходного кода является одним из лучших способов изучения программирования. Через анализ кода можно изучить различные языки программирования, научиться различным алгоритмам и понять общие принципы работы компьютерных программ.
Как преобразовать .exe в исходный код
Используйте декомпилятор
Декомпилятор — это инструмент, который может помочь вам преобразовать .exe файл обратно в исходный код. Существует множество программ для декомпиляции, но они все работают похожим образом: они преобразовывают бинарный код в читаемый язык программирования. Декомпиляторы доступны для различных языков, таких как C++, Java, C# и других.
Выберите подходящий декомпилятор
Выбор декомпилятора зависит от вашего .exe файла. Если файл был скомпилирован на C++, следует обратить внимание на ILSpy, IDA Pro или Ghidra. Для Java-файлов вы можете использовать JD-Gui или Java Decompiler. Для C#-файлов вы можете воспользоваться dnSpy или Telerik JustDecompile.
Следуйте инструкциям декомпилятора
Каждый декомпилятор поставляется с инструкциями по использованию. Сначала откройте .exe файл в декомпиляторе, выбрав файл на компьютере. Затем выберите опцию декомпиляции, и декомпилятор начнет преобразование файла в исходный код. В результате вы получите понятный и читабельный код, который можно редактировать и адаптировать под свои нужды.
Несмотря на то, что декомпиляция может помочь вам разобраться в том, как работают некоторые .exe файлы, стоит помнить, что декомпиляция иногда может нарушать авторские права. Поэтому следует использовать декомпилятор только в тех случаях, когда это необходимо для образовательных или исследовательских целей.
Как просмотреть и изменить исходный код
1. Использование декомпилятора
Декомпилятор – это программное обеспечение, которое используется для преобразования исполняемого файла обратно в исходный код. Для просмотра кода .exe файла нужно установить декомпилятор и загрузить в него нужный файл. После этого, файл будет открыт и покажет исходный код, который можно изменять.
2. Изменение .exe файла с помощью Resource Hacker
Resource Hacker – это бесплатная утилита для изменения .exe файлов. Она позволяет просматривать внутренности файлов и изменять их вывод в интерфейсе. Выполнив поиск в окне Resource Hacker, можно найти нужный исходный код для просмотра и изменения.
- Скачайте программу Resource Hacker и установите ее на компьютер.
- Откройте .exe файл.
- Найдите нужный код и отредактируйте его.
- Сохраните изменения.
3. Использование отладчика
Отладчик – это программа, которая используется для поиска ошибок в программном обеспечении. Он также может помочь в просмотре и изменении исходного кода .exe файла. Для этого необходимо установить отладчик, открыть нужный файл и выполнить поиск нужных фрагментов кода.
4. Использование дизассемблера
Дизассемблер – это программное обеспечение, которое выполняет перевод машинного кода в исходный код на ассемблере. Он поможет просмотреть содержимое .exe файла и определить, как он работает. Однако, в отличие от декомпилятора, дизассемблер не может сгенерировать полный код в исходном формате.
5. Просмотр данных через HEX-редактор
HEX-редактор – это программа, которая может просмотреть и изменить данные, которые хранятся в файлах в hex формате. Она не может показать весь исходный код .exe файла, но может помочь в выявлении фрагментов кода. HEX-редактор может быть полезен для работы с бинарными файлами и настройки определенных байтов в файле.
Как скомпилировать измененный исходный код
1. Установите необходимые инструменты
Для компиляции измененного исходного кода вам понадобятся необходимые инструменты, в зависимости от языка программирования. Например, если вы работаете с языком С, вам понадобится компилятор gcc.
Настройте необходимые переменные окружения, чтобы ваш компьютер мог находить инструменты компиляции при выполнении команд в командной строке.
2. Откройте измененный исходный код
Откройте исходный код программы в редакторе кода. Внесите необходимые изменения и сохраните файл с расширением .c или .cpp в директории вашего проекта.
3. Компилируйте изменения
В командной строке выполните команду для компиляции измененного исходного кода. Например, для языка С можно выполнить команду:
gcc main.c -o main
Где main.c — имя измененного файла, а main — имя собранного исполняемого файла.
4. Запустите исполняемый файл
После успешной компиляции вы можете запустить полученный исполняемый файл. Для этого в командной строке выполните команду:
Где main — имя собранного исполняемого файла.
Если все прошло успешно, изменения, которые вы внесли в исходный код программы, теперь будут отражены в запущенном приложении.
Вопрос-ответ:
Какой программой можно просмотреть исходный код .exe файла?
Для просмотра исходного кода .exe файла можно использовать специальные декомпиляторы, например IDA Pro, OllyDbg, Ghidra, Jadx и другие.
Могут ли быть обратные связи от просмотра исходного кода .exe файла?
Если вы пытаетесь просмотреть исходный код .exe файла, то это может нарушать авторские права и являться незаконным действием, которое может привести к негативным последствиям для вас и вашей компании. Кроме того, при попытке изменить программу, используя просмотренный исходный код, вы можете нарушить лицензионные соглашения и повредить работу программы, что приведет к уголовной ответственности.
Могу ли я использовать просмотренный .exe файл в личных целях?
Если у вас есть законные права на использование программы, то вы можете просмотреть исходный код .exe файла на личных целях. Но если вы не уверены в своих правах или не имеете соответствующих документов, лучше воздержаться от просмотра исходного кода.