Как изменить код программы

Бывают ситуации, когда под рукой нет исходника, а Вам срочно требуется внести изменения в коде, написанной ранее Вами программы. Например, дано приложение «TextEdit.exe» — текстовый редактор, написанный на языке c#, который имеет простой пользовательский интерфейс, состоящий из двух кнопок и текстового поля.

При нажатии на кнопку “Чтение” из файла 1.txt считываются и выводятся все строки в окно элемента управления textBox, а при нажатии на кнопку “Запись” данные из текстового поля сохраняются в файле 2.txt

Для хранения путей в программе используются две текстовых переменных: filePathIn и filePathOut

Прошёл год, как программа была написана и отдана заказчику, но вдруг ему потребовалось изменить имя папки, в которой должны храниться оба файла, c 123 на Text. Задача простая, но прошло уже много времени, и исходник был потерян, что делать в такой ситуации?

Для начала вспомним, как образуется .NET сборка

Полученный в результате компиляции файл (сборка) содержит внутри себя метаданные, манифест, код на языке IL (MSIL).

КАК ИЗМЕНИТЬ КОД СТРАНИЦЫ

Метаданные описывают типы данных и их члены

Манифест описывают саму сборку

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

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

Дизассемблер ILDASM

Правка чужого кода

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

Старожилы знают, что в комплекте с различными версиями ДОС шли дополнительные утилиты, и среди них была «замечательная» утилита debug , которая убога чуть более, чем полностью. Ещё во времена моей молодости эта утилита вызывала у меня самые противоречивые чувства, то сейчас и подавно. Пользоваться ей без успокоительных очень сложно, с другой стороны, хорошо, что она есть. Но мне возможностей и удобства этой утилиты не хватало, поэтому пришлось искать другой подходящий инструмент. После длительного гугления наткнулся на исходники утилиты RAM View.

К сожалению, исполняемого файла найти не удалось, только исходные коды под Borland C++ 3.1 , и как впоследствии оказалось, сама программа содержала ошибки.

Всё это вылилось в интересный квест по поиску старого компилятора, исправления ошибок в программе 25-летней давности и создания запроса на слияние.

❯ Компиляция

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

Читайте также:
Linux как переустановить программу

Как посмотреть исходный код android приложения? Декомпиляция .apk файла (реверс инжиниринг)

Для того чтобы собрать и проверить эту утилиту, мне понадобится программа DOSBOX. До того как запускать коробку с ДОС, создаю папку DOS в корне диска C, либо ~/DOS в любимом Linux.

Перехожу в эту папку и клонирую туда этот проект:

git clone https://github.com/aurelitec/ramview.git

Сборка старых программ – это определённый квест, доступный не каждому: старые компиляторы, у которых есть свои особенности работы с ними, описанные в книгах, сданных в макулатуру. Поскольку ранее с компилятором Borland C++ дел не имел, пришлось идти в ретрочатик t.me/retrocomps и просить помощи.

Согласно описанию в гите, мне нужен Borland C++ 3.1 , который я скачал отсюда. Выбрал портабельную последнюю версию, чтобы не заниматься установкой, и распаковываю её в папку C:DOSBC .

После чего запускаю DOSBOX и монтирую локальную папку C:DOS , как диск C: :

Если просто открыть проект в компиляторе BC и попробовать собрать, то вылезет ошибка, что библиотеки не найдены, и тут начинается главная магия. Идея в том, что надо понять в какую папку был установлен компилятор у автора, чтобы пути к библиотекам в его проекте совпали с реальным их расположением, но как это сделать? Всё достаточно просто, возможно вариант не самый элегантный, но рабочий.

Первое – это нужно получить Makefile из самого проекта, делается это командой PRJ2MAK (не забываем указать пути к исполняемому файлу):

PRJ2MAK RAMVIEW.PRJ

После этого у нас появится Makefile RAMVIEW.MAK , в котором уже можно посмотреть пути, где должен обитать компилятор.

Теперь осталось перенести компилятор в папку BORLANDC и должно произойти чудо.

Переименование папки

Запускаю компилятор, собираю и да, полный успех!

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

После всех неочевидных манипуляций запускаю программу и вижу такую картину:

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

Ну что ж, пришла пора исправлять чужие ошибки в старой программе.

❯ Исправление ошибок в чужом коде

Проблема достаточно банальная, автор программы писал во времена DOS, в кодировке IBM CP866, а потом исходники видимо кочевали по разным дискам, вот и потерялись различные спецсимволы, которые затем были некорректно декодированы при заливке на github.

В этом можно убедиться, если открыть Notepad++ и посмотреть исходники, то достаточно быстро можно найти подобные места:

Некорректное отображение символов

Если в настройках сменить кодировку на CP866 (в моём случае это кириллица), то места станут намного более очевидными. А главное, они сразу будут узнаваемы с теми символами, что на скриншоте.

Читайте также:
Ниже приведена программа записанная на пяти языках программирования было проведено 9 запусков 1 2

Проблемные места в кодировке CP866

Всё достаточно банально, нужно просто подобрать в ASCII-кодах подходящие символы и вставить их в нужные места. Первые две «сломанные» строки – это явно вертикальный символ, а нижний – это красивая деталь разделитель рамки.

Таблица ASCII – кириллица

Результатом стал выбор символа 0xB3 для вертикальной черты, и 0xBA для детали рамки.

cputs(» Version 0.1 xb3 Copyright (c) 1997 Aurelitec»); … cputs(«xb3 F10 = Exit»); … strcat(buffer, » xba»);

Очень удобно редактировать код в Notepad++, а затем собирать в DOSBOX, новейшие технологии стучатся в наши двери (сарказм). После перекомпиляции получаем программу, которая выглядит и работает, так как надо:

Область памяти с ROM BIOS

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

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

Поскольку автор предоставляет нам как лицензионную, так и просто человеческую возможность вносить изменения в свою программу:

Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Этой возможностью мы и воспользуемся.

❯ Оформление изменений в чужой проект

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

Если попробовать закоммитить полученные изменения в репозиторий, из которого мы склонировали, то ничего не выйдет. Для этого в github есть другой механизм, по-русски называемый запросом на слияние. В gitlab он называется merge request, в github именуется pull request. Так как мне довелось достаточно долго поработать с github и gitlab, то я больше люблю за удобство gitlab, он сделан людьми для людей. Но человек ко всему привыкает и даже к таким ужасным вещам, как неочевидный интерфейс github.

Первое, что потребуется сделать – это создать ответвление от родительского проекта (fork). Для этого нужно клацнуть по соответствующей кнопке в родительском репозитории.

Кнопка — создание форка репозитория

Клонирование репозитория к себе, в моём случае форк уже создан

В локальном репозитории выполняем:

git remote set-url origin https://github.com/dlinyj/ramview.git

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

git add git commit -m «Fixed minor bugs with the display of symbols» git push

Читайте также:
Свойство которым должна обладать программа

И тут начинается самое интересное. Вообще, как я понимаю, можно сделать и локально запрос на слияние, но мне удобнее через web-интерфейс.

В веб-интерфейсе вашего удалённого репозитория нужно зайти «Pull requests» и там нажать кнопку «New pull request».

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

Как выглядит запрос на слияние

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

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

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

Самое неприятное и распространённое – это исправление замечаний от владельца репозитория. Вы вносите эти изменения точно так же локально, но когда вы делаете коммит, то не создаёте новый, а добавляете изменения в старый коммит, так чтобы его hash не менялся.

Делается это следующей командой:

git commit —amend

Но git push у вас сделать не получится, потому что это вы будете вносить исправления в уже существующие коммиты на удалённом сервере. Поэтому надо его запихать туда принудительно, без предварительных ласк и грубой силой, используя опцию —force . Крайне не рекомендуется её использовать, но других вариантов я не знаю.

git push —force

У такого подхода есть недостаток, что стираются замечания, которые владелец вам оставил (это особенность github, у нормального gitlab таких проблем нет), так что рекомендую сохранять все замечания до финального коммита.

❯ Выводы

Реальное применение исправленной программы

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

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

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

❯ Полезные ссылки:

  1. Оригинальный репозиторий.
  2. Моя исправления копия.
  3. Оформленный запрос на слияние.
  4. Готовая собранная программа.

Источник: habr.com

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru