Обратная разработка программного обеспечения — процедура получения информации об алгоритме. При этом получение этих данных напрямую зависит от того, насколько много есть информации о приложении в документации, и от того, какой использовался способ для создания файла. Всё еще больше усложняется, если алгоритм заимствует фрагменты из других приложений или операционной системы. Эта статья расскажет о механизмах, которые заложены в ОС Windows, благодаря которым процесс обратной разработки может стать весьма сложным процессом.
С чего всё началось
Появление парадигмы объектно-ориентированного программирования подарило программистам очень мощные инструменты для обработки информации. Начали появляться новые языки, которые использовались для разных спектров задач, программное обеспечение становилось модульным. Написание новой программы с функционалом, который использовал стандартные механизмы ввода/вывода стало тривиальной задачей. Нужно было только подключить нужную библиотеку, которая уже содержала все необходимые функции.
Результатом использования парадигмы объектно-ориентированного подхода стали методы логического разбиения приложений на отдельные фрагменты, при этом можно было создавать уже скомпилированные части кода, которые собирались в новые приложения. Модульность позволила задуматься о механизмах, которые могли бы позволить объединять код, фрагменты которого были бы написаны на разных языках программирования, в одну систему, которая решала бы отдельно взятую проблему или целый класс проблем.
В операционной системе Windows подход к созданию отдельных компонентов был реализован в предоставлении унифицированных интерфейсов, которыми приложения пользуются и по сей день. Эти интерфейсы называются WinAPI. Их исследование достаточно тривиально, большая часть интерфейсов задокументирована и поэтому их обратная разработка заключается в том, чтобы найти в документации название и прочитать данные о параметрах и возвращаемом значении.
Каждый WinAPI интерфейс позволяет сделать минимальное действие, которое может произвести ОС, то есть если программист решит написать приложение, то для его реализации придётся задействовать несколько сотен, а то и тысяч интерфейсов. Отдельно стоит упомянуть, что это далеко не единственный способ, который доступен в ОС для реализации алгоритмов. ОС Windows также предлагает компонентный подход для построения приложений. Это означает, что программист может объединять целые программы вместе, чтобы реализовать выполнение алгоритма. Возможно это за счет использования механизма Component Object Module.
Появление COM не случайно, реализация этого механизма — логичный этап развития. На схеме ниже можно увидеть ретроспективу создания механизмов в ОС Windows:
Картинка наглядно показывает, как связано появление того или иного механизма. Реализация каждого нового механизма это решение проблем, которые возникли при реализации предыдущего механизма. Картинка включает в себя такие механизмы как OLE, COM+, DCOM, которые тоже, надо сказать очень сложные с точки зрения реализации и изучения.
Некоторые полезные определения
Представленная выше картинка с годами внедрения механизмов в ОС дает наглядное представление, что механизмы, которые сегодня используются, были созданы почти 22 года назад. Создание актуальной документации для такого длительного периода времени весьма сложная задача и соответственно, когда встает вопрос об обратной разработке ПО, которое использует указанные выше механизмы, нужно точно знать, ЧТО делает каждый из них.
COM дает возможность переиспользовать куски приложения. Работает за счет того, что можно собрать исполняемый кусок кода и расположить его в реестре ОС. Кусок кода получит уникальный идентификатор и будет вызывать ОС каждый раз, как приложения будут запрашивать обработку данных по идентификатору. Для создания кода можно использовать любой компилируемый язык программирования.
OLE - механизм связывания и внедрения данных в различные приложения. Больше всего распространен в приложениях, которые используются для офисных задач. Открытие таблицы Excel в документе Word самый распространенный пример использования механизма.
DCOM - механизм, который предоставляет возможность работать с объектами COM в рамках локальной сети или Интернета.
COM+ - механизм, который может быть использован для создания распределенного на целые кластера программного обеспечения. Включается в себя COM, предоставляет для объектов механизмы, которые позволяют с ними общаться по сети. Предоставляет механизмы по синхронизации, отказоустойчивости и разграничению доступа.
Примеры и практика
Давайте попробуем посмотреть, как обозначенные выше механизмы выглядят в ПО при обратной разработке. Начнем с OLE. Как было сказано выше, этот механизм проще всего обнаружить в офисных документах. Попробуем найти такой документ.
Для исследования был выбран вот этот документ. Он представляет собой docx файл, по сути это архив, который содержит некоторое количество файлов с инструкциями, как его рендерить. Заглянем внутрь: в этом формате все данные, которые могут быть добавлены через OLE это файлы, которые расположены в директории "word/embeddings". Заголовок содержимого объекта можно видеть ниже:
Ничего особенно примечательного, такие объекты можно анализировать с использованием набор инструментов oletools.
OLE объект представляет собой файловую систему, в которую можно положить информацию необходимую для встраивания данных. Если воспользоваться инструментом oleobj, то можно увидеть, что внутри объекта находится txt файл. Кстати, это можно увидеть и из шестнадцатеричного редактора:
Объект COM - представление зависит от типа предоставляемого функционала, чаще всего в программном обеспечении используется в совокупности с WinAPI CoCreateInstance. Визуально исследовать объекты можно через относительно простой инструмент - COMView. Пример работы инструмента:
Почти все элементы пользовательского интерфейса, которыми мы пользуемся каждый день, это COM объекты.
Как найти объекты COM+? Если в COMView вы обнаружили объект, который имеет интерфейс IUnknown, перед вами COM+ объект. Например:
Таким образом можно установить, за какой функционал отвечает тот или иной объект, который используется программным обеспечением. При этом не нужно вникать в имплементацию и можно сразу разобраться в алгоритме приложения, прочитав описание объекта в интерфейсе COMView.
Статья подготовлена Александром Колесниковым в рамках курса "Reverse-Engineering. Professional". Если интересно узнать больше о программе и формате обучения на этом курсе, приходите на день открытых дверей онлайн, на котором вы также сможете познакомиться с преподавателем.
Emelian
Статья ни о чем. Ни пользы, ни смысла, всем этим заниматься, никакого. Полезных примеров тоже нет. Если вы готовы реверсить бинарный код Windows, особенно в части довольно старой технологии (судя по картинке, 1999 год – последний), то не проще ли найти в Интернете ранее утекшие туда исходники WinNT, Win2003 Server и WinXPsp1? Там все прочитаете открытым текстом.
А есть еще бинарно совместимая с Windows открытая и свободная операционная система ReactOS. Смотрите ее сколько угодно, зачем еще декомпилировать бинарный код и восстанавливать его на Си (соответствующим плагином IdaPro)? Конечно, вы этого не говорили, но это следует из вашей логики.
Я не знаю ни одного реально практического примера, где была бы полезной технология COM. Вот фирма «1С» обожала эту технологию, пока не стала портировать свой продукт под Linux. А все, что есть на эту тему в Интернете – отстой. Поэтому, самый лучший COM, это программирование собственного виртуального интерфейса, для собственных целей, безо всяких GUID'ов и реестров…
staticmain
"Штрих" вот только только перешла на СОМ с нормальных драйверов и прямо заявляет, что linux им неинтересен. Действительно, куда же еще ставить фискальные принтеры, кроме как в самую защищённую ОС windows 10?
da-nie
А Direct-X?
Emelian
Ну, как бы понятно, что M$ изобрела эту технологию для себя. Сама и использует, причем много где. Вот только обычному программисту от этого профита не очень много. Гораздо более эффективен старый добрый опенсорс.
Я лично много раз пытался найти хороший COM сервер, чтобы использовать в собственных проектах. Но все, что доступно, оказалось так себе. Например, в Visual FoxPro отличный движок БД, но ужасный интерфейс. Сами длл-ки этого движка это COM сервера. Казалось бы, бери и работай, тем более, что компилируемые в VFP exe-шники, тоже используют эти сервера. Но нет, открытые интерфейсы вполне себе закрыты, поскольку по ним нет никакой конкретики. Может быть, там нужные GUID'ы секретные или еще что, но достучаться до реальных функций почти невозможно. У меня были кое-какие успехи, но на реальный проект я так и не вышел. В итоге, пришел к выводу, что гораздо более эффективней использовать SQLite тем более, что его можно внедрять в 64-битные приложения.
Другой пример, мультимедиа (плюс веб-броузеры, pdf-ридеры и тому подобное). Да, как бы можно, в своем окне, вывести несжатый avi-ролик, но что-то серьезное фиг кто даст. Мол, покупайте коммерческую версию. Однако, зачем это надо, если есть опенсорсный FFplay.c, который я прекрасно внедрил в собственный проект. Причем, никаких ограничений на кодеки и все такое. И так во всем. Тот же Direct-X тоже. Есть неплохие, более удобные альтернативы, для разных целей.
kaleman
Это потому что вы не занимаетесь разработкой под Windows, поэтому и не знаете. Любое технологическое оборудование типа касс, сканеров штрихкодов, весов, турникетов, принтеров и т.д. Просто втыкаете в комп, ставите SDK и через COM моментально получаете доступ к этому железу из скриптов в 1C, Excel, любой ERP. Решение собирается как из кубиков лего моментально. В Линукс так и не сумели создать что-то сопоставимое по удобству использования и технологичности. Даже в 2021 без COM разработчику под Windows никуда.
Emelian
Я занимаюсь «разработкой под Windows», но не работаю с технологическим и торговым оборудованием. Как по мне это не разработка, а обслуживание чужих девайсов. Естественно, раз технология существует, то у нее есть применение. Другое дело, что для собственных, достаточно интересных проектов, применения COM я не вижу.
Уже приводил пример с FoxPro9r.dll / FoxPro9t.dll. Это «интересные» COM сервера, но попробуйте поработайте с ними независимо! А вот с SQLite.c / SQLite.h – пожалуйста, проблем нет. И так во всем. А работа с чужим оборудованием, в своих проектах, как-то не греет, хотя, согласен, если за это платят деньги, то может быть полезной. Но, я как раз не это имел в виду. Больше пользы я вижу в опенсорсе, WTL, например. Да, есть еще ATL, для работы с COM’ом, но применения ему я пока, для себя, не нашел.
OCTAGRAM
У вас часть кода на Аде, часть кода ещё на чём-то. Чем их сопрягать собираетесь?
Разновидности COM встречаются и под Mac OS. Ну не реестр там, по-другому было. Для Linux я видел и в p7zip автономный COM, и VirtualBox XPCOM с возможностью RPC.
Emelian
Есть два подхода. Первый, вы используете существующие СОМ-сервера для своих целей. Здесь все плохо, использовать особо нечего, по разным причинам. Хотя могут быть какие-то вынужденные варианты, типа драйверов оборудования от производителей, но это не столько разработка, сколько работа с уже готовым ПО. А, второй, это когда вы используете СОМ с нуля для каких-то своих целей, типа приведенного вами примера. Тут ведь нет стандартного решения, правда?
А уж, какую интеграцию вы придумаете для разнородных продуктов, это уже отдельный разговор. СОМ здесь не единственный вариант, причем, чужими серверами воспользоваться маловероятно, а свои делать трудоемко. Когда мне надо было делать транскрибацию видео, то я взял две программы, видео проигрыватель и Эксел, установил их в смежных окнах, и написал скрипт на AHK, который обеспечивал согласованные команды для обеих программ и вполне успешно получил то, что мне было нужно. Да, это решение на скорую руку, но рабочее. Хотя для серьезной работы лучше найти или сделать специализированный продукт.
Сама идея СОМ, как виртуальных интерфейсов, реализованных на чем угодно, достаточно продуктивная. Другое дело, что СОМ, был изначально заточен на коммерческое использование, расширяющий возможности, относительно dll, бинарной совместимости. Именно это я и имел в виду, когда выказывал свое разочарование данной технологией. За что-либо путное надо платить деньги, а бесплатное, как правило, не стоит выеденного яйца. Но, платить надо тогда, когда нет другой возможности, однако в ИТ отрасли, альтернативных и бесплатных технологий вполне достаточно, особенно для специалистов.
Что касается использования реестра (именно это главная причина неприязни к СОМ), то это нужно не пользователю, а ИТ гигантам, которые рассматривают Интернет и персональные компьютеры как элементы своей собственной глобальной операционной системы, к которой именно монополисты имеют максимальный доступ, а не формальные владельцы компьютеров, ноутбуков, смартфонов и т.п.
OCTAGRAM
И что там трудоёмкого? Берём и клепаем интерфейс за интерфейсом
Emelian
Не, ну если делать «вообще», да еще с помощью ATL, то, как бы обозримо. А если «конкретно», для взаимодействия, в данном случае, двух произвольных разнородных программ, то, наверняка, возникнут «нюансы».
OCTAGRAM
Тут в соседней ветке пишут:
И если при рефакторинге для ссылок/умных указателей можно взять сразу комовские, то почему бы и нет, заодно и интероп.
Может быть, дело не в COM, а в ATL? Я иногда слышу жалобы на COM, и часто при этом всплывает какой-то ATL, наверное, одно с другим как-то коррелирует.
Ну и что есть путного за деньги?