Исходный код раскрыть невозможно если для этого постарались обеспечить безопасность (особенно если это фирменная вещь).
Но есть способы полностью или частично раскрыть код.
- 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, иконки, картинки, таблицы ресурсо-строк). - Если извесно чем создан код — думаю есть специальные утилиты способные его раскрыть (они платные и малодоступные).
Опять-же, это при условии что нету паковщика кода (тогда нужно сначала применить депаковщик), шифровальщика/самомодифицирующегося кода. Если не разбит обфускатором так что не распутать. Чем больше код — тем сложнее разобраться.
P.S. Лично моё мнение — раскрывается-взламывается всё, но на это нужно потратить много-много времени. Возможно год и более (зависит от опыта и инструментов, в свободном доступе хороших инструментов нету).
Как посмотреть код программы
Программы делятся на открытые и закрытые. В первом случае для всех пользователей интернета доступно скачивание ее исходного кода с официального сайта и других ресурсов, во втором – код системы закрыт и его просмотр нарушает правила пользования программным обеспечением.
Вам понадобится
- — декомпилятор;
- — дезассемблер.
Инструкция
Просмотрите исходный код программы при помощи ее исходника. Исходный файл содержит в себе код, написанный программистом при создании программного обеспечения, после этого он компилируется при помощи специальных иснструментов и превращается в файл установки.
Если вами был утерян файл исходного кода, или он недоступен вам по другим причинам, воспользуйтесь специальными программами-декомпиляторами. Также имеются программы-дизассемблеры. Обратите внимание, что просмотр исходного кода зачастую может стать невозможным в случаях, когда вам не известно, какой язык программирования использовался при его разработке.
Если вы хотите найти код свободной программы, выполните поиск в интернете с соответствующим запросом. Также попробуйте скачать данную программу и в ее меню найти пункт «Просмотр исходного кода». Обычно это доступно для бесплатно распространяемых программ.
Будьте осторожны при их использовании, в частности это относится к программам, скачанных не с сайта разработчика, поскольку в исходник может быть заложен вредоносный код, который при установке на ваш компьютер также инсталлирует трояны, клавиатурные шпионы и так далее.
Будьте внимательны при использовании программ-декомпиляторов, поскольку многие разработчики программного обеспечения пользуются специальными программами, которые затрудняют процесс воссоздания исходного кода. Если программа была написана на ассемблере, также принимаются специальные программы.
Средств обратной программной разработки достаточно немало, не используйте их в мошеннических целях или для внесения изменений в программы с закрытым кодом, поскольку зачастую за данные действия предусмотрена определенная ответственность в соответствии с законодательством.
Полезный совет
Не просматривайте код закрытых программ и тем более не вносите в него изменения.
Войти на сайт
или
Забыли пароль?
Еще не зарегистрированы?
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.
I’ve got some old Windows executable files. How can I edit them with Visual Studio 2010? What are the ways to see an exe’s source code?
MPelletier
16.1k15 gold badges85 silver badges136 bronze badges
asked Apr 17, 2010 at 18:37
You can’t get the C++ source from an exe, and you can only get some version of the C# source via reflection.
answered Apr 17, 2010 at 18:41
i_am_jorfi_am_jorf
53.5k15 gold badges130 silver badges222 bronze badges
2
If the program was written in C# you can get the source code in almost its original form using .NET Reflector. You won’t be able to see comments and local variable names, but it is very readable.
If it was written C++ it’s not so easy… even if you could decompile the code into valid C++ it is unlikely that it will resemble the original source because of inlined functions and optimizations which are hard to reverse.
Please note that by reverse engineering and modifying the source code you might breaking the terms of use of the programs unless you wrote them yourself or have permission from the author.
answered Apr 17, 2010 at 18:40
Mark ByersMark Byers
805k190 gold badges1576 silver badges1450 bronze badges
1
If it is native code, you can disassemble it. But you won’t see the original code as written by the programmer. You will see the code produced by the compiler. This code is possibly optimized and although it is semantically equivalent, it can be much harder to read than normal ASM.
If it is bytecode (MSIL or javabytecode), there are decompiler which can product pretty good sourcecode. For .net, this would be reflector.
answered Apr 17, 2010 at 18:40
HenriHenri
5,06522 silver badges24 bronze badges
I would (and have) used IDA Pro to decompile executables. It creates semi-complete code, you can decompile to assembly or C.
If you have a copy of the debug symbols around, load those into IDA before decompiling and it will be able to name many of the functions, parameters, etc.
answered Apr 17, 2010 at 18:43
ssubessube
46.7k7 gold badges100 silver badges140 bronze badges
There’s nothing you can do about it i’m afraid as you won’t be able to view it in a readable format, it’s pretty much intentional and it’ll show the interpreted machine code, there would be no formatting or comments as you normally get in .cs/.c files.
It’s pretty much a hit and miss scenario.
Someone has already asked about it on another website
answered Apr 17, 2010 at 18:42
Jamie KeelingJamie Keeling
9,77617 gold badges65 silver badges102 bronze badges
7
For Any *.Exe file written in any language .You can view the source code with hiew (otherwise Hackers view). You can download it at www.hiew.ru. It will be the demo version but still can view the code.
After this follow these steps:
-
Press alt+f2 to navigate to the file.
-
Press enter to see its assembly / c++ code.
Yogiraj
1,94217 silver badges29 bronze badges
answered May 28, 2014 at 13:14
Вася — молодой программист. Получив задачу и засучив рукава, он берется за написание кода. Уже через день решение задачи готово, Вася запускает его… И сталкивается с неожиданной досадной ошибкой. Вася старательно исправляет ее и повторно запускает решение. В результате — снова неприятная ошибка. Так Вася долго наступает на грабли, пару раз значительно переписывает программу, пока, наконец, через неделю задача окончательно не решена.
Петя — опытный программист. Получив постановку, он ищет, нет ли исходного кода, решавшего аналогичную задачу. Пару дней Петя проводит, читая материалы и разбираясь в чужих модулях, а на третий — запускает свое решение, основанное на уже существующем коде. В нем есть пара незначительных ошибок, которые удается быстро исправить. Ура! Все работает так, как нужно, уже на третий день.
Как найти нужный вам кусок исходного кода? Как его понять? А главное — зачем все это делать? В поиске ответов на эти вопросы добро пожаловать под кат.
Почему важно уметь искать и читать код?
Д. Томас и Д. Спинеллис в книге «Анализ программного кода на примере проектов Open Source» формулируют несколько важных тезисов.
Чтение кода — это повседневное занятие программиста.
Со стороны кажется, что основная работа программиста состоит в написании исходников, но это не так. Чаще всего код приходится читать, а не писать. Вчера ваш товарищ написал модуль, а сегодня перед вами стоит задача усовершенствовать его или исправить ошибку, что невозможно без предварительного изучения трудов вашего товарища.
90 % ошибок можно устранить при чтении кода.
С цифрой 90 %, как мне кажется, можно поспорить, но основная мысль ясна: при чтении (в данном случае — рецензировании) программы можно (и нужно) выявлять и устранять ошибки.
Нас часто учат писать код, но редко — читать его.
И напрасно, поскольку без чтения существующих исходников приходится постоянно изобретать велосипед. Даже если вы можете написать что-то с нуля, гораздо эффективнее будет осмотреться вокруг и использовать чужой исходный код напрямую или как аналогию. Чужой код проверен, отлажен и, скорее всего, уже содержит какие-то «фичи», которые будут полезны и при решении вашей задачи.
Итак, читайте код, чтобы не писать велосипедов. Читайте код, чтобы вносить изменения быстрее. Читайте код, чтобы в программах было меньше ошибок.
О чем эта статья?
Основная цель статьи заключается в том, чтобы систематизировать существующие подходы к поиску и чтению кода. Знание конкретных подходов дает возможность применять те из них, которые наиболее приемлемы в том или ином случае. Кроме того, статья содержит обзор инструментов, которые позволят эффективно применять описанные в статье подходы. Стоит отметить, что искать и понимать исходный код можно и без специальных инструментов, однако их применение делает процесс более наглядным и менее рутинным.
Я расскажу о наиболее универсальных концепциях: иными словами, эти концепции применимы ко всем или почти всем языкам программирования. Некоторые инструменты, которые облегчают поиск и чтение исходников, также универсальны, однако большинство актуально только для Visual Studio и .NET. Тем не менее тот факт, что большая часть инструментов применяется исключительно в VS, не означает, что для других IDE нет подобных средств: я уверен, что они есть, поскольку приведенные в статье подходы универсальны. Также оговорюсь, что все описанные инструменты бесплатны, исключение составляет только ReSharper.
Приведенные в статье примеры кода взяты из приложений ShareX и Greenshot (оба распространяются под лицензией GNU GPL) из репозитория ShareX по состоянию на 30 июня 2015. Я благодарю авторов этих приложений за возможность воспользоваться их кодовой базой. Также благодарю моих коллег, в особенности Дениса Гаврилова и Владислава Иофе, за высказанные ими замечания во время работы над статьей.
Поиск кода
Поиск кода представляет собой процесс, результатом которого выступают части исходного кода, связанные с тематикой решаемой задачи.
Поиск вне кода
Начинать искать исходники можно и нужно вне кодовой базы. Предварительное общение с командой, чтение документации и баг-трекера могут существенно упростить непосредственный поиск кода. Подробнее о работе с артефактами можно узнать из семинара Д. Гаврилова «Практики командной работы: о пользе письменных артефактов». Помимо чтения документации и общения с командой полезно вспомнить, что вы уже знаете о том, что предстоит найти. Например, если предстоит найти экранную форму, то стоит вспомнить, что название экранных форм в вашем проекте обычно заканчивается на Form, а все формы лежат в сборе ”UI”.
Можно запустить приложение на исполнение и искать экранную форму перебором. При переборе программист открывает в случайном (или не очень) порядке формы до тех пор, пока не найдет окно, кнопку, пункт меню или любой другой элемент интерфейса, который, как кажется, использует искомый функционал. Перебор применяется, когда задача поиска размыта или программист плохо знаком с системой. Например, вы ни разу не работали с приложением, а от вас требуется добавить функцию, которая бы экспортировала все открытые картинки в буфер обмена. Логичным представляется для начала исследовать приложение: посмотреть, умеет ли оно экспортировать картинки в буфер обмена по одной, есть ли какие-то настройки, связанные с буфером или экспортом и т. д.
Поиск по ключевым словам
Ключевое слово — это слово или словосочетание из текста документа или запроса, несущее существенную смысловую нагрузку с точки зрения информационного поиска. Необходимая для поиска подборка ключевых слов формируется через общение с пользователями, просмотр экранных форм перебором и другие методы, описанные выше в качестве поиска «вне кода». Ключевые слова можно взять из описания задачи, экранных форм и действий пользователя, текста ошибки или сообщения, SQL-запроса, то есть из любых артефактов, связанных с решаемой задачей.
Чтобы поиск по ключевым словам был максимально эффективным, необходимо подбирать редкие ключевые слова. Например, если вы работаете над проектом, в котором много разных документов (Document), то поиск по слову Document даст множество лишних результатов. Однако бывают ситуации, когда подобрать редкие ключевые слова нет возможности. В этом случае сначала нужно найти множество потенциально полезной информации, а затем сузить поиск. Например, найти все существующие упоминания Document, а затем исключить из результатов тесты, поискать в найденных файлах дополнительные ключевые слова и т. д. В целом следует стремиться найти хотя бы что-то (чуть больше или чуть меньше), а не именно то, что нужно.
В большинстве случаев для поиска по ключевым словам достаточно встроенного в IDE поиска (обычно он вызывается сочетанием клавиш Ctrl + F). Иногда может быть полезен файловый менеджер — для поиска в папках, которые не входят в программное решение, — или поисковые движки: например, OpenGrok и DocFetcher (о них речь пойдет ниже). Так, ReSharper содержит полезную функцию Search by Pattern, с помощью которой можно найти, например, все свойства классов, объявленные как нулябельные перечисления (public TEnum? Enum { get; set; }). Конечно же, не стоит забывать и про мощный механизм регулярных выражений; да, он требуется редко, но иногда здорово выручает.
Давайте поговорим чуть подробнее про поисковые движки, работающие с исходным кодом. Главное преимущество поисковых движков состоит в том, что они позволяют осуществлять гибкий поиск. Например, нужно найти все классы, в которых есть упоминания Clipboard и Image. Обычные средства, встроенные в IDE, дадут вам возможность найти либо файлы с Clipboard, либо файлы с Image. Здесь за скобками оставляем пресловутый механизм регулярных выражений: он может помочь, но конструкция поиска будет громоздкой. Более сложный пример, с которым встроенные средства поиска не справятся: необходимость найти свойства классов, помеченные атрибутом A, но не помеченные атрибутом B. Помимо гибкости поисковые движки увеличивают скорость поиска. Если вашей IDE нужна пара-тройка, а иногда и не один десяток секунд, чтобы пробежаться по всем файлам проекта, то поисковый движок имеет индекс, позволяющий делать то же самое в доли секунды.
Существуют различные поисковые движки по исходному коду, можно почитать их обсуждение на StackOverflow или ознакомиться с подборкой на сайте beyondgrep.com. В своей работе я использую OpenGrok: он бесплатный и умеет работать с различными языками, такими как C#, C, PHP, SQL и с десяток других. Движок состоит из 2-х модулей: модуля индексации исходников и веб-приложения для поиска и навигации по коду. Первый модуль индексирует папки проекта в файловой системе. Веб-приложение работает под Apache, позволяет вводить разные поисковые запросы и просматривать полученные результаты. OpenGrok написан на Java, доступен для скачивания на официальном сайте проекта, а в соответствующих статьях можно прочитать о том, как установить движок под Windows и под Linux.
OpenGrok поддерживает различные виды поиска: по тексту всего документа или только в определениях, то есть названиях классов, функций. Кроме того, он позволяет задавать фильтрацию папок и названия искомого файла, выбирать язык, на котором должен быть написан код и т. д. Этот движок показывает результаты в наглядной форме, сгруппированными по файлам, а также позволяет в один клик перейти к нужной строчке в файле и умеет показывать код с подсветкой или в «сыром» виде.
Поисковый запрос и результаты поиска в OpenGrok по ShareX
У OpenGrok есть несколько ограничений: во-первых, отсутствует интеграция с Visual Studio, во-вторых, он не умеет работать с кириллицей (по крайней мере, мне не удалось добиться этого при помощи настроек). Если вам часто приходится искать русский текст, то можно использовать DocFetcher: данный инструмент не заточен напрямую под поиск в исходниках, но умеет индексировать любые текстовые файлы и отлично справляется с русским языком.
В таблице ниже представлено сравнение возможностей поисковых движков OpenGrok и DocFetcher.
Сравнение поисковых движков
С помощью этой таблицы можно выделить для себя необходимые параметры поиска и выбрать наиболее подходящий инструмент.
Параметр | OpenGrok | DocFetcher |
---|---|---|
Гибкость поиска (через поддержку поискового языка) | Да | Да |
Быстрота поиска (через индексацию) | Да | Да |
Специальные инструменты для поиска кода | Да | Нет |
Работа с кириллицей | Нет | Да |
Интеграция с Visual Studio | Нет | Нет |
Мультиплатформенность | Да | Да |
Лицензия | CDDL | Eclipse Public License |
Поиск по классификаторам
Классификатор — это систематизированный перечень наименованных объектов. Наиболее востребованным программистами классификатором, на мой взгляд, является список всех классов программного решения. Примерами других классификаторов могут быть список членов классов, упорядоченных по классам, список файлов, упорядоченных по папкам и др.
Классы приложения ShareX
С одной стороны, классификатором можно пользоваться как инструментом работы с древовидным списком. Вы «разворачиваете» базовое пространство имен программного решения, далее «разворачиваете» пространство имен нужного модуля и так далее, пока, наконец, не доберетесь до нужного класса. С другой стороны, внутри классификатора можно осуществлять сквозной поиск. Например, вы набираете *Document*, а классификатор показывает все классы, в названиях которых встречается Document.
Если вы работаете с ReSharper, то наверняка знаете про функцию Go to Everything, которая позволяет перейти к любому классу, методу, свойству или файлу во всем программном решении. В Visual Studio «из коробки» есть следующие классификаторы: Solution Explorer (классифицирует сборки, папки, файлы, классы и их члены), Class View (классифицирует пространства имен, классы и их члены) и Object Browser (классифицирует сборки, пространства имен, классы и их члены). Solution Explorer и Class View выдают перечень классов внутри вашего решения, а Object Browser — как в вашем решении, так и в сторонних используемых сборках. OpenGrok позволяет искать по определениям (Definition), в том числе с использованием символов подстановки (*Document*). Еще один классификатор — это обычный файловый менеджер, который отображает артефакты, упорядоченные по папкам.
Когда следует применять классификаторы? Чтобы успешно использовать классификатор, программист должен хорошо знать программный продукт. Особенно важно, в частности, знать соглашения об именах (например, *Form — это экранная форма, а DocumentNameListForm — списочная форма документов типа DocumentName), а также принципы, по которым классы упорядочиваются в папках и пространствах имен (в Dictionaries лежат справочники, а в Documents — документы). Еще одна возможность применения поиска по классификатору — ситуация, когда известно точное название класса или его члена.
Поиск ошибки
Периодически возникает задача найти строчку кода, в которой возникает некоторая ошибка. Как вариант, нужную строчку можно найти по известному номеру ошибки. В данном случае номер ошибки — ключевое слово, по которому осуществляется поиск (про поиск по ключевым словам было рассказано выше). В иной ситуации может быть известна трассировка стека ошибки. В ReSharper есть удобный инструмент Stack Traces, который позволяет просматривать стек и перемещаться по методам, которые вызывались перед тем, как произошла ошибка. Чтобы использовать Stack Traces, необходимо скопировать стек ошибки в буфер обмена, после чего в Visual Studio нажать Shift + Ctrl + E.
Просмотр стека ShareX и навигация по нему в Stack Traces
Если у вас нет информации ни о номере ошибки, ни о трассировке стека, можно запустить проект и включить прерывания по ошибке. Для Visual Studio создано удобное дополнение Exception Breaker, позволяющее включать и выключать прерывание по ошибке одним кликом мыши.
По действию пользователя
Иногда требуется узнать, какой метод вызывается при нажатии кнопки или другом действии пользователя. В этом случае можно сначала найти класс, в котором находится вызываемый метод (например, поиском по ключевым словам или по классификатору), а затем расставить точки останова во всех членах этого класса и запустить приложение. В веб-приложениях в некоторых случаях бывает полезен Fiddler, в частности, в нем можно посмотреть название вызываемой WCF-функции и значения переданных в нее параметров.
Итоги
Перед тем как приступать к поиску кода, стоит потратить немного времени на общение с командой, чтение документации и перебор экранных форм. Это необходимо для того, чтобы собрать ключевые слова, узнать названия классов и методов, без которых дальнейший поиск будет затруднительным. Начинать его стоит с самого простого, при этом можно найти чуть больше или чуть меньше, чем требуется. Искать исходники также можно при помощи ключевых слов или классификаторов. Для поиска ошибок и функций, вызываемых по действию пользователя, есть специальные методики.
В следующей таблице представлены рассмотренные выше методы поиска кода.
Метод | Описание | Инструменты |
---|---|---|
Поиск вне кода | Предварительная подготовка к непосредственному поиску кода, особенно когда задача поиска размыта или программист плохо знаком с системой |
|
Поиск по ключевым словам | Поиск кода, в котором встречаются заданные ключевые слова |
|
Поиск по классификаторам | Поиск классов или других объектов, упорядоченных по категориям (например, по пространствам имен), особенно когда программист хорошо знаком с приложением или известно точное название класса или его члена |
|
Поиск ошибки | Поиск строчки кода, в которой возникает ошибка |
|
Поиск по действию пользователя | Поиск метода, который вызывается по действию пользователя |
|
Понимание кода
Поиск кода неразрывно связан с его пониманием. Понимание необходимо, чтобы выделить из всех найденных действительно полезные для решения задачи блоки исходников, чтобы понять, как надо модифицировать и как можно использовать полученные при поиске результаты.
Понимание без чтения кода
Вне кодовой базы начинается не только поиск кода, но и процесс его понимания. Запуск приложения, чтение документации, баг-трекера, лога приложения или системы контроля версий, общение с командой и (или) пользователями дают хорошее представление о том, что происходит внутри приложения. Так же, как и при поиске исходников, перед непосредственным чтением кода важно вспомнить, что уже известно про разбираемую область.
Чтение «черного ящика»
Чтение кода как «черного ящика» предполагает, что по некоторым внешним признакам мы пытаемся установить, что происходит внутри функции или класса. О назначении объекта можно догадаться, посмотрев на его имя, принимаемые параметры и возвращаемое значение. Например,
public ResultOrError SetToClipboard(Image image)
по всей видимости, помещает изображение image в буфер обмена, а информацию о произошедших ошибках помещает в возвращаемый ResultOrError.
Для чтения «черного ящика» важно знать соглашения об именах, то есть о принятых в проекте префиксах, постфиксах и других частях названий. К «черному ящику» относится чтение описаний или комментариев внутри функций.
Чтобы убедиться в правильности предположений о назначении функции, можно изучить ее использование. Также можно найти, какие действия пользователя приводят к вызову функции (например, пользователь нажал на кнопку «Копировать в буфер») и на основе этих знаний понять, что пользователь ожидает получить в результате выполнения функции (в нашем случае, очевидно, скопировать некий объект в буфер обмена).
ReSharper предлагает мощные инструменты Inspect This и Find Usages, которые позволяют найти места, из которых вызывается функция. Inspect This представляется более удобным, поскольку позволяет легко и наглядно осуществлять дальнейший поиск фрагментов кода, из которых вызываются места, где вызывается функция, и так далее. В самой Visual Studio «из коробки» доступен инструмент Call Hierarchy, который имеет возможности, аналогичные Inspect This.
Места, в которых используется функция (ShareX.UploadManager.UploadFile: 66-80)
- Inspect This (слева);
- Find Usages (в центре);
- Call Hierarchy (справа).
Чтение «белого ящика»
Если в «черном ящике» код метода был для нас «закрыт» (мы изучаем исходники на границе и вокруг функции), то в «белом ящике» предполагается изучение кода внутри исследуемого метода.
При «белом ящике» важен порядок чтения исходников. С одной стороны, чтобы понять код, не надо читать его целиком, поэтому начинать чтение стоит с наиболее важных его частей, пропуская менее значимые строки. С другой стороны, от последовательности чтения зависит быстрота понимания. Чтение слева направо и сверху вниз — не лучший способ погружения в исходники.
Один из приемов чтения «белого ящика» состоит в чтении «вглубь»: вначале читаем код первого уровня, затем переходим ко второму и так далее по уровням.
Чтение «вглубь» (ShareX.UploadManager.UploadFile: 43-64)
Для Visual Studio есть дополнение C# outline, которое позволяет сворачивать и разворачивать текст внутри if, for и других управляющих конструкций («из коробки» Visual Studio умеет сворачивать и разворачивать пространства имен, классы, регионы и методы, но не if, for и подобные им конструкции).
Другой способ чтения кода как «белого ящика» состоит в чтении «от ключевых мест». Как правило, это места, где функция возвращает или вычисляет результат, каким-то образом использует входные параметры, делает вывод в файл, на экран или другое устройство. Ключевые места в разных функциях могут быть различными. Важно уметь их найти и прочитать в первую очередь.
Для Visual Studio есть дополнение RockMargin, которое подсвечивает в редакторе и на полосе прокрутки все места, в которых встречаются вхождения выбранного ключевого слова. Например, вы два раза щелкаете на taskSettings, а RockMargin подсвечивает все места, где встречается taskSettings в файле:
Подсветка RockMargin для ShareXUploadManager.cs
В вашем приложении, скорее всего, есть много однотипных, шаблонных кусков. Это могут быть как общеиспользуемые шаблоны (например, Singleton), так и шаблоны, специфичные для вашего проекта (например, какие-то особенности в построении UI). Понять, что делает шаблон, можно по двум-трем ключевым словам, поэтому шаблоны надо учиться читать «целиком», без «разбора букв». Например, на картинке ниже — класс-Singleton, о чем можно догадаться по двум строкам кода, которые выделены красным.
Класс-Singleton (Greenshot.Drawing.Fields.Binding.DecimalFloatConverter:29-52)
Еще одна последовательность, которую следует соблюдать при чтении исходников, состоит в чтении от простого к сложному. Вначале разберитесь с тем, что понятно и так, а затем переходите к более сложным конструкциям.
В заключение раздела о «белом ящике» я бы хотел сказать несколько слов о чтении при рецензировании кода. Перед непосредственным чтением (особенно если прорецензировать предстоит объемную доработку) следует просмотреть названия всех измененных файлов, а затем понять, в каких файлах произошли ключевые изменения. Чтение необходимо начинать с файлов с ключевыми изменениями, из которых вы схватите общую суть и лучше поймете все остальные доработки.
Улучшение кода
Чтобы понять исходный код, можно не только читать его, но и улучшать. Самый простой способ улучшить восприятие кода — правильно расставить отступы. Другой способ улучшить читабельность — рефакторинг. Простейшие переименования и разделение длинных функций на несколько коротких позволяют быстро сделать текст программы более понятным.
Для понимания сложных логических конструкций можно применять законы де Моргана:
!(a && b) = (!a) || (!b)
!(a || b) = (!a) && (!b)
В качестве инструмента по улучшению кода можно порекомендовать ReSharper, который справляется с улучшениями разной степени сложности.
Режим отладки
Режим отладки дает возможность проверить сделанные во время чтения исходников предположения. Чтение в режиме отладки предполагает использование таких инструментов, как точки останова (в том числе точки останова «по условию», например, срабатывающие только при определенном значении переменных), просмотр трассировки стека, пошаговое выполнение программы, просмотр и модификация значений переменных.
Общая картина
При чтении важно поддерживать общее представление о том, что происходит в разбираемом модуле, и уметь быстро перемещаться по разным местам «паззла».
Чтобы удержать в голове общую картину, можно использовать диаграммы, как уже существующие в проекте, так и новые. Некоторые диаграммы можно строить автоматически, особенно это актуально для SQL-запросов. В PL/SQL Developer, например, есть Query Builder, который показывает, какие таблицы участвуют в запросе и как они между собой связаны. Автоматизированно можно строить диаграммы классов, к примеру, в Visual Studio для этого применяется инструмент View Class Diagram. Однако чаще всего достаточно даже нарисованной от руки схемы.
Читать вызываемые методы удобно при помощи ReSharper, Inspect This или встроенного в Visual Studio View инструмента Call Hierarchy. В разделе про «черный ящик» эти инструменты уже рассматривались, но там исследовались места, из которых вызывается функция. Здесь же речь идет о просмотре методов, которые вызываются внутри функции. Inspect This и View Call Hierarchy дают целостную картину — вы видите дерево вызовов целиком — и позволяют быстро по нему перемещаться.
Для быстрых переходов по произвольным блокам кода можно закреплять вкладки (чтобы отличать те 5–10 классов, с которыми вы плотно работаете, от других 20–100, которые пришлось открыть в процессе работы), делать закладки в редакторе или записи от руки, например, выписывать названия классов и их членов.
Для быстрых переходов внутри файла будут полезны: в ReSharper — File Structure (отображает члены текущего класса), в Visual Studio — Member (аналог File Structure) или RockMargin (отображает уменьшенный исходный код на широкой полосе прокрутки, подкрашивает закладки и точки останова).
Итоги
Перед непосредственным чтением исходников важно обратиться к различным источникам вне кодовой базы: пообщаться с командой, почитать документацию, запустить приложение на выполнение. Это даст некоторое базовое понимание приложения, которое поможет в непосредственном чтении кода. Читать исходники можно как «черный ящик», анализируя названия методов, принимаемые ими параметры и т. д. как «белый ящик», производя разбор того, что находится внутри метода. Для облегчения восприятия кода его можно улучшить, например, расставить отступы. Запуск приложения дает возможность проверять сделанные предположения в режиме отладки. Наконец, при чтении важно удерживать общую картину в голове и уметь быстро перемещаться по разным частям исследуемого модуля.
В следующей таблице представлены рассмотренные выше методы понимания кода.
Метод | Описание | Инструменты |
---|---|---|
Понимание без чтения кода | Получение общего представления о модуле без просмотра исходников |
|
Чтение «черного ящика» | Понимание происходящего внутри функции или класса по некоторым внешним признакам (имя, принимаемые параметры, возвращаемое значение и т. д.) |
|
Чтение «белого ящика» | Изучение кода внутри исследуемого метода |
|
Улучшение кода | Улучшение читабельности кода |
|
Режим отладки | Запуск приложения в режиме отладки |
|
Общая картина | Удержание общего представления о том, что происходит в разбираемом модуле; быстрое перемещение по разным местам кода |
|
Заключение
Поиск и понимание кода — важный этап в работе над программным продуктом. Поиск и понимание начинаются за пределами репозитория: с общения с командой, чтения документации, баг-трекера, запуска приложения на исполнение. Поиск и понимание необходимы как при доработке существующих модулей (чтобы доработать существующий модуль, надо понять, как он работает), так и при разработке нового функционала: да, новый модуль иногда можно разработать, не прочитав ни строчки кода, но в проекте, скорее всего, есть отдельные блоки, реализующие схожий функционал, которые можно взять в качестве шаблона для реализации функций и классов.
По моему мнению, чтение кода в широком смысле этого слова (то есть как поиск исходников, так и их понимание) должно выделяться разработчиком в отдельный этап работы над задачей. Результатом этого этапа является набор закладок в методах и файлах, который будет полезен при работе над задачей, а также общее представление о работе некоего блока кода. Уже в рамках непосредственного программирования поиск исходников необходимо продолжать. Например, так: встретил новый класс, нашел места, где он используется, обновил список полезных закладок. Возможно, подбор закладок можно выделить отдельной функцией в команде: технический лидер или ответственный разработчик составляет список полезных закладок, после чего программист берет задачу в работу.
Как для поиска, так и для понимания исходников важно знать соглашения об именах и способах упорядочивания классов (по папкам, пространствам имен). По опыту автора, такое понимание приобретается в процессе работы в проекте, однако соглашения можно формализовывать и сообщать новым разработчикам так же, как соглашения по оформлению кода (Code Style Guide).
Перспективным представляется разработка автоматизированных средств, выявляющих фактически сложившиеся соглашения об именах и способах упорядочивания классов. Как кажется, полезными будут средства, выявляющие наиболее часто встречающиеся названия папок, суффиксы, постфиксы и т. д.
При чтении кода, как и при чтении обычной книги, важно осознать и держать в голове цель чтения. Для чтения кода можно применять некоторые приемы из статей о способах чтения обычного текста (см., например: «Как улучшить свою способность понимать прочитанный текст?»).
Насколько можно оценить, поиск и понимание кода является темой, слабо затронутой в отечественной и зарубежной литературе. Надеюсь, что представленная статья была полезной в освоении приемов эффективной работы с кодовой базой.
Инструменты
Для поиска кода
- OpenGrok
- DocFetcher
- Fiddler
- ReSharper
- Go to Everything
- Stack Traces
- Search by Pattern
- Visual Studio
- Встроенный поиск (Ctrl + F)
- Solution Explorer
- Class View
- Object Browser
- Точки останова
- Дополнения к Visual Studio
- Exception Breaker
- Файловый менеджер
- Перебор экранных форм
Для понимания кода
- ReSharper
- Inspect This
- Find Usages
- File Structure
- Инструменты для рефакторинга
- Visual Studio
- Call Hierarchy
- View Class Diagram
- Member
- Средства отладки
- Дополнения к Visual Studio
- RockMargin
- C# outline
- Запуск приложения
Общие методы
- Общение с командой или пользователями
- Чтение документации и баг-трекера
Когда разработчики выпускают свое программное обеспечение с открытым исходным кодом, это показывает, что они заслуживают доверия и щедры. Программное обеспечение с открытым исходным кодом был одним из главных моментов, которые лично помогли мне начать работать программистом-самоучкой.
Чтобы проект был открытым, разработчик должен сделать его исходный код общедоступным, чтобы любой желающий мог его изучить и извлечь уроки. Важно отметить, что это также показывает, что у разработчика нет злонамеренных намерений, поскольку открытый исходный код позволяет пользователям компилировать свои собственные двоичные файлы, а не использовать предоставленные.
Если вам когда-либо приходилось сталкиваться с двумя программами, и вы не можете определить, какое из них использовать, проверьте, является ли один из них открытым, а другой — нет. Если это так, ваш выбор должен быть ясным.
Однако, если вы хотите учиться или даже добавлять к коду исходного кода программного обеспечения, это также вариант. Для этого вам нужно знать, как просматривать исходный код. В этой статье давайте поговорим о том, как вы можете это сделать.
Как найти исходный код
После того, как вы нашли часть программного обеспечения с открытым исходным кодом, которое вы хотели бы просмотреть в исходном коде, первым делом нужно выяснить, как сделать исходный код проекта доступным.
В большинстве случаев исходный код будет размещаться на крупнейшей веб-платформе управления версиями, GitHub,
Что такое GitHub?
GitHub был основан в 2008 году и приобретен Microsoft в 2018 году. Это глобальная платформа для разработки программного обеспечения, которая предлагает все функции управления исходным кодом: Гитнаряду с собственными функциями, которые расширяют возможности совместной работы и функции контроля версий.
Чаще всего разработчики размещают свой открытый исходный код на GitHub. Несколько примеров программного обеспечения, о котором вы, вероятно, слышали, с исходным кодом, доступным на GitHub: LibreOffice, GIMP, а также VLC медиаплеер,
С помощью Функция поиска GitHubвы должны быть в состоянии найти и просмотреть исходный код практически для каждого крупного программного проекта с открытым исходным кодом.
Как просмотреть исходный код
Найдя репозиторий GitHub, в котором находится исходный код программного обеспечения, вы обнаружите, что все организовано в базовом дереве каталогов. Для файлов GitHub делает просмотр кода очень простым.
Как платформа для разработки, GitHub аккуратно форматирует исходный код через веб-интерфейс. Почти все авторитетные проекты будут включать README.md, который представляет собой файл уценки, который отображает полезную информацию о хранилище и его структуре. Когда вы перейдете к хранилищу, прокрутите вниз, и вы увидите содержимое этого файла.
README.md репозитория важно проверить, потому что он часто указывает пользователям направление исходного кода, который их может заинтересовать. Репозиторий может быть заполнен всеми видами кода и другими данными, некоторые из которых совершенно бесполезны для вас. , так что этот файл — ваша дорожная карта.
Как только вы выясните, где в репозитории находится интересующий вас код, все, что вам нужно сделать, — это щелкнуть по дереву каталогов репозитория, чтобы найти, куда вы хотите перейти.
Щелчок по файлу отобразит его с правильной подсветкой синтаксиса.
Для быстрой проверки веб-интерфейс GitHub отлично подходит. Однако для более сложного исходного кода вам может потребоваться просмотреть несколько файлов одновременно или в течение длительного периода времени. В этом случае мы рекомендуем скачать и просмотреть исходный код через Текстовый редактор, например, Sublime Text.
Загрузка исходного кода
Загрузка репозитория с GitHub занимает всего два клика.
В верхней части каждого репозитория, под строкой, отображающей общее количество коммитов, веток, пакетов, выпусков и участников, вы увидите зеленую кнопку с надписью Клонировать или загрузить. Нажмите на нее и выберите Скачать ZIP.
По умолчанию начнется загрузка главной ветви текущего репозитория в виде файла ZIP. По завершении все, что вам нужно сделать, это извлечь архив в локальную папку на вашем компьютере. Затем, используя текстовый редактор, вы можете открыть любой из файлов репозитория гораздо быстрее, не требуя браузера.
Если вы не опытный кодер, GitHub может сначала немного запутать. Если вы просто думаете об этом как об открытом каталоге исходного кода, с readme на верхнем уровне, это не слишком пугающе. Просмотр исходного кода с помощью GitHub прост, как локально, так и через его веб-интерфейс.