Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
выпущен 12 ноября!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

Обзор защит программного обеспечения под Linux

Обсудить статью на форуме

Очень удобно, когда все крэкерские инструменты, книги и статьи в одном месте. Используйте сборник от EXELAB - вот тут.

Автор: Red Plait <mailto:redplait@usa.net>

Дети в сугробах шумно играют в Афганистан.
Я через двор не пойду.
Электрики вешают красные гирлянды в саду.
Синие флаги на ветру.
Поутру новый год - все снова.
Снова, снова все танцуют, все играют в снежки.
Взвожу курки -
Так я стал предателем...

Аукцион, "Новогодняя песня"
альбом "Как я стал предателем", 1989



В этой статье я попытался сделать обзор Linux`а с точки зрения матёрого крякера, для которого нет ничего святого :-). OpenSource, без сомнения, штука хорошая и полезная. Но - отчего-то постоянно хочется кушать, в том числе и программистам, и даже жителям Villabajo (как Вы думаете, почему у них постоянно грязная посуда ?). Представим, что Вы потратили кучу времени и ресурсов, разрабатывая последние несколько месяцев неплохую программу, и даже отчего-то имеете версию для Linux`а. Видимо, Вы хотите окупить затраченные усилия - проще говоря, заработать на своей программе кучу денег. И если Вы не опубликовали свой исходный код, в надежде заработать другими способами (кстати, рассказали бы тогда, какими именно), то необходимо как-то защитить Вашу программу от

1) несанкционированного копирования. Т.е. программа должна работать только у того, кто её купил, и не должна работать (или работать неправильно, или, что бывает чаще всего, иметь функциональные ограничения) у халявщиков и крякеров.

2) плагиата. Или reverse engeneering`а. Проще говоря, чтобы Ваш уникальный алгоритм не смогли своровать

Если разработке/снятию защит под DOS/Windows посвящено множество сайтов (включая приснопамятную Fravia), то я лично не видел ни одной работы, посвящённой тому же самому, но под Linux. Между тем уже имеется множество коммерческих программ под эту в общем не самую плохую из распространённых OS. С прискорбием должен отметить, что вся их "защита" составляет максимум 1% от их Windows аналогов, и снимается в худшем случае за пару часов. Я постараюсь объяснить почему происходит именно так, почему под Linux`ом не работают многие традиционно используемые для защиты Win32 программ способы, и возможно после прочтения этого шедевра творчества душевнобольных, Вы даже сможете придумать что-то действительно эффективное.
"А кто такой автор, чтобы судить о столь высоких материях ?" - вполне справедливо может спросить читатель. А никто, в сущности. Так, сломал пару десятков программ и решил сделать что-нить полезное. См. эпиграф, в общем...

Итак, в чём же главное отличие Linux от прочих OS ? В доступности исходного кода всего (ну, кроме разве что Вашей программы, стоящей мегабаксы), что работает (или не работает) на Вашей машине. Это делает написание защиты под Linux просто кошмаром - Вы не можете быть уверены, что функция strcmp из стандартной C run-time library - это действительно strcmp, а не её изменённый (обычно не в Вашу пользу) эмулятор. Вы не можете доверять ничему в такой операционной системе - вследствие доступности исходного кода любая её часть может быть модифицирована крякером для взлома Вашей программы, включая такие важнейшие компоненты, как ядро и run-time library. Ваша программа работает в самой агрессивной среде, какую только можно себе представить. В самом деле, если бы Вы могли изменить в Windows 9x, скажем, kernel32.dll (я имею в виду не ковыряние в машинном коде с помощью дизассемблера, хотя +tsehp использовал и такой метод - нет, просто редактирование исходного кода и последующая перекомпиляция - намного эффективнее, не правда ли ?) - разве было бы возможно существование защит вроде VBox ? Я настоятельно рекомендую хорошо подумать об этом как-нибудь на досуге.
А пока у меня для Вас плохие новости - Ваша программа обязательно будет сломана. Это на самом деле "чиста" экономический вопрос. Представим, что Ваш программный продукт стоит 1000 $. Среднемесячная зарплата неплохого программиста из нашей страны едва ли составляет 200 $. Таким образом, если какой-нибудь парнишка из Сибири затратит на слом Вашего творения меньше 5 месяцев - он будет экономически выгоден. Заметьте, что здесь ни слова не было сказано ни об операционной системе, под которой работает Ваш шедевр, ни о сложности и стоимости использованной системы защиты.
Что же делать - идти в монастырь (хотя, в женский иногда наведываться - наверное, неплохая идея :-) ? Вы должны рассматривать защиту своего программного продукта не как 100% средство от Ваших головных болей, а всего лишь как средство, затрудняющее жизнь крякеру. Скажем, если Ваша защита остановит 9 крякеров из 10 - это очень неплохой результат. Конечно, не все 9 остановленных купят Вашу программу, но их будет явно больше, чем для случая, когда Ваша защита сломана 9-тью из 10. Впрочем, возможно, что я жёстко не прав - я лично никогда не покупал программных продуктов :-)
Итак, довольно пустых разговоров. Для начала я сделаю краткий обзор применяемых крякерами инструментов (хотя я склонен рассматривать Linux как один большой инструмент крякера).


Отладчики


Странно, но до сих пор никто не переписал SoftIce под Linux - я лично не вижу этому никаких препятствий. Более того, у меня есть веские доказательства, что это не просто возможно сделать, но и что его реализация будет значительно легче и проще, чем под всякие глючные операционные системы от не-будем-показывать-пальцем-кого. Так что пока с отладчиками намного хуже (для крякеров, для авторов защит - наоборот, хотя ведь отлаживаться всё-равно как-то нужно), чем под Win32. Итак, что есть/годно к употреблению (см. также раздел Debuggers на LinuxLinks [http://www.linuxlinks.com/Software/Programming/Development/Debugging/]):

- GDB. Отладчик userlevel mode. Загружает файлы с помощью BFD. Что-то вроде старого недоброго debug из DOS`а. Также оформлен как библиотека. К нему есть множество интерфейсов, наиболее удобный для X Windows IMHO DDD (требует LessTif). Также заслуживает отдельного упоминания SmartGDB (http://hegel.ittc.ukans.edu/projects/smartgdb/brief.html). Крайне интересная идея прибить сбоку отладчика script engine. Я не знаю аналогов под Win32, но вещь в результате получилась очень любопытная с точки зрения автоматизации труда крякера - Вы можете написать script (в данной конкретной реализации это TCL; я лично предпочёл бы Perl, или что-либо C-like, но ради такой штуки можно и TCL выучить), который посадить затем как триггер на точку останова. Ваш script смог бы, например, проверить переменные в отлаживаемой программе, и в зависимости от их значения, например, поставить новую точку останова (с новым script`ом), сбросить кусок памяти в файл, сварить какаву..

- Remote host Linux kernel debugger via GDB from SGI (http://oss.sgi.com/projects/kgdb/)

- Kernel level debugger от всё той же SGI (http://oss.sgi.com/projects/kdb/). Пока крайне сырая вещь (и требует нестабильной версии кернела), но может служить прототипом для более пригодных к использованию изделий :-)


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


Без сомнения, IDA Pro. Также иногда можно на скорую руку использовать Biew, objdump (или даже ndisasm, дизассемблер от Netwide Assembler), но это несерьёзно. Мне больше неизвестны инструменты, которые позволяют дописывать к ним новые процессорные модули, загрузчики для нестандартных форматов файлов, а также plugins, облегчающие автоматический/интерактивный анализ. К тому же Ильфак грозился выпустить как раз версию под Linux (как иронично :-). Хит третьего сезона подряд, в общем. Ладно, на этот раз обойдусь без обычных наездов :-).

strace

или truss под UnixWare. Аналог regmon/filemon/BoundsChecker в одном флаконе. Ядро Linux`а имеет поддержку перехвата системных вызовов (функция ptrace). Т.е. можно запустить любой процесс как подлежащий трассировке через ptrace, и Вы сможете отследить все системные вызовы с их параметрами. Более того, после небольшой модификации эта функция (которая имеет доступ к виртуальной памяти трассируемого процесса) может быть использована, например, для run-time patching, внедрения кода в адресное пространство любого процесса, и так далее, и тому подобное. Пусть кинет в меня камень после всего описанного считающий, что Linux написали не крякеры :-). Если же серьёзно, то я пока не смог выдумать способа, как на userlevel противодействовать этой кувалде. Более того, я пока даже не могу узнать, что мой процесс в настоящий момент трассируется ядром ! Впрочем, пару решений можно придумать:

1) можно написать свой модуль ядра, вследствие монолитной структуры Linux kernel`а он будет иметь доступ ко всем структурам ядра, в том числе и к отвечающим за ptrace...

2) Менее надёжное, но более простое в реализации средство. Можно вызвать ptrace для самого себя. Если вызов был неудачен - значит, нас уже трассируют, нужно сделать что-нить по этому поводу (sys_exit, например, а не то, что Вы подумали :-). Впрочем, ведь если нас уже трассируют, ничего не стоит перехватить данный вызов и вернуть всё что угодно...


Memory dumpers


Ну, здесь даже и писать ничего не нужно. Файловая система /proc может использоваться для таких целей. Файл maps используется как карта выделенной процессу виртуальной памяти, а файл mem является её отображением, можно сделать в нём seek на нужный адрес и легко сохранить необходимый участок в файл или куда-Вы-там-хотите. Простая программа на Perl`е размером 30 строчек может быть использована для снятия дампа памяти Вашей драгоценной программы и сохранения её в файл. Намного проще, чем под Win32 :-)


Шестнадцатеричные редакторы


С этим тоже никогда не было больших проблем. Даже стандартный просмотрщик Midnight (или Mortal его второе имя) Comander`а умеет редактировать в шестнадцатеричном представлении. Для гурманов рекомендую Biew.


Стандартные средства разработки


Это не шутка. Для модификации ядра/runtime библиотек (а также для создания patch`ей и keygen`ов) нужен как минимум компилятор "C". Впрочем, я как-то пару раз писал keygen`ы на Perl`е :-).


Способы защиты


Итак, я надеюсь, Вы ещё не уснули и впали в депрессию. Что же можно противопоставить всему вышеописанному ? Явно годятся далеко не все методы, используемые в Win32. Тем не менее, я смог придумать несколько, и я уверен, что это далеко не всё...


Против BFD (GDB, objdump, strings etc)


BFD - это библиотека для манипуляций с бинарными файлами. По счастливому стечению обстоятельств она используется также отладчиком GDB. Но для ELF формата (наиболее распространённый формат исполнимых файлов под всеми современными Unix`ами) она реализует неправильный алгоритм загрузки (подробности см. в моей статье "Как сделать Linux программы меньше"). Для этого можно использовать sstrip или мой ELF.compact (собственно, они делают одно и то же, просто когда я писал свой tool, я не знал о существовании sstrip). Преимущества:

- Очень простой метод. Берёте Вашу готовую отлаженную программу и вместо команды strip (кстати, а Вы знаете о её существовании и что она делает ? Если нет, настоятельно рекомендую почитать man на ночь) запускаете elf_compact (или sstrip).

- Помимо всего прочего Вы уменьшите размер размер Вашего дистрибутива. Хотя, глядя на размеры современных дистрибутивов Linux`а, этот аргумент кажется просто смешным...

на этом преимущества заканчиваются и начинаются Сплошные недостатки:

- Поскольку исходники BFD публично доступны, теоретически любой может доработать этот замечательный пакет, так что шансы снова будут не в Вашу пользу. Собственно, Вы должны помнить, что в Linux`е это относится ко всему. Но пока этот метод работает (и глядя на ленивых парней с HCulinux [http://hculinux.cjb.net/] я готов спорить, что он будет работать ещё долго :-)

- через пару дней после написания ELF.compact я, почесав репу, написал довольно простой загрузчик для IDA Pro, так что я лично смогу дизассемблировать обработанные таким образом ELF`ы без каких-либо затруднений. Кстати, он продаётся :-)

Данный вариант может рассматриваться как очень простая защита от полных ламеров, rating 0.1%.


Компрессия/шифрование кода программы


Самый распространённый метод защиты под Win32. Под Linux`ом этот метод имеет некоторые особенности. Самое большое отличие в том, как разрешаются ссылки на внешние модули.


Статическая линковка


Не имеющий аналогов под Win32 метод. При сборке программы все используемые ею библиотеки просто статически линкуются в один большой толстый модуль. Т.е. для запуска такой программы ничего дополнительно делать не нужно - такая программа самодостаточна. Преимущества:

- Большую программу ломать труднее, чем маленькую. Впрочем, это несерьёзно :-)

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

- Устранение (хотя и не 100%) возможности перехвата и эмуляции библиотечных вызовов (см. также далее по тексту). В такой программе Вы будете несколько более уверены, что при вызове, скажем, strcmp будет вызвана Ваша статически слинкованная функция strcmp, а не неизвестно что. Хотя в Linux`е никогда и ни в чём нельзя быть уверенным до конца :-)

Недостатки:

- Увеличение размера программ. Впрочем, я уже рассуждал об это выше.

- Если Вы думаете, что таким образом сможете затруднить жизнь крякеру, Вы глубоко ошибаетесь. С помощью технологии FLAIR, используемой в IDA Pro, а также применив мой инструмент RPat для создания сигнатур исходных библиотек (использованных Вами при статической линковке), все Ваши библиотечные функции могут быть легко опознаны. Более того, обычно не составляет большого труда выяснить, какие именно библиотеки используются, собрать их, и сделать файлы сигнатур.

Rating: 0.1%.
Также возможно, что кто-нить станет бросать в меня кирпичи, утверждая, что статическая линковка де увеличивает необходимые ресурсы, и что якобы разделяемые библиотеки разделяют сегмент кода между всеми процессами, использующими их. Я тоже так думал, более того, то же самое утверждают большинство виденных мною учебников по Unix, но это не так. Самое простое доказательство - посмотрите атрибуты сегментов памяти, занимаемых разделяемыми библиотеками (файл maps в файловой системе /proc). Вы почти никогда не увидите атрибута s(hared). Почему ? Короткий ответ звучит так - из-за ELF. Дело в том, что при загрузке ELF файла происходит настройка его перемещаемых адресов - relocations. При этом сегменту памяти (даже если это сегмент кода) присваиваются атрибуты Read/Write, и если он при этом разделялся несколькими процессами, происходит копирование памяти при записи. Таким образом, разделение сегментов кода между процессами возможно только между родителем и его потомками (как результат функции fork). За подробностями обращайтесь к исходникам kernal`а. Кстати, эти же аргументы применимы и к утверждению, что якобы "упаковка кода программы приводит к увеличению ресурсов, необходимых для запуска такой программы". Как видите, господа-слюниксоиды, как минимум в управлении виртуальной памятью Linux ничем не лучше поделок от M$.
Декомпрессор/декриптор для статически слинкованных файлов ничем не отличаются от своих DOS`овых предков, собственно, тут даже и говорить не о чем. Я в настоящий момент занят написанием такого зверя - просто добавляется код распаковки и изменяется точка входа на него.


Динамическая линковка


Под Win32 все программы являются динамически слинкованными как минимум с системными .DLL, реализующими API. Более того, такая линковка осуществляется опять же самой системой с помощью всё тех же функций API. Под Linux`ом всё по-другому. Во-первых, программе совершенно необязательно быть динамически слинкованной. Во-вторых, программа сама должна заботиться о загрузке всех необходимых модулей и динамическом разрешении ссылок. Это, правда, вовсе не означает, что Вам каждый раз придётся писать код загрузки модуля в память. Среда исполнения (а не kernel - как в Win32) предоставляет реализацию динамического загрузчика по умолчанию - в терминах Linux его называют ELF interpretor, или просто interpretor (я не знаю точного перевода и вообще сомневаюсь в его наличии, так что буду просто использовать оригинальный термин). При линковке в программу помещается информация, что для её запуска необходимо после загрузки самой программы также загрузить interpretor, и передать ему управление. На этом загрузка файла на исполнение с точки зрения кернела заканчивается. Но Ваши головные боли только начинаются ! Итак, чем плох стандартный ELF interpretor ?

1) Тем же, чем и весь Linux - его исходники доступны, соответственно, он может быть легко изменён для достижения неизвестных Вам целей

2) Он поддерживает уникальный для Unix`ов механизм предварительной загрузки (я лично не знаю аналогов под Win32). Рассмотрим его подробнее. Итак, предположим, что Ваша программа импортирует функцию strcmp. Злобный крякер может написать собственную реализацию этой функции, создать объектный модуль и использовать её вместо той, что Вы ожидали ! Для этого всего лишь нужно определить переменную среды LD_PRELOAD, чтобы она содержала список модулей, подлежащих загрузке ПЕРЕД импортируемыми Вашей программой. Логика работы interpretor`а такова, что если некая импортируемая функция уже разрешена, то она больше не разрешается (в Linux импорт происходит по имени, а не по имени и имени библиотеки, как в Win32). Таким образом, можно штатными средствами внедрить в адресное пространство Вашей программы всё что угодно, заменив при этом любую импортируемую функцию. Похоже на ночной кошмар, не так ли ? Вы всё ещё думаете, что Linux написали не крякеры :-) ?

3) С стандартным interpretor`ом есть и ещё одна проблема. Дело в том, что его легко можно переписать для универсального инструмента, отслеживающего все вызовы импортируемых функций. У меня была идея встроить script engine в ELF interpretor, так что больше не нужно будет переписывать его под каждую конкретную программу, а всего лишь заменить script, который и сделает всё что нужно. Ведь ELF interpretor работает в адресном пространстве Вашей программы, и он отвечает за начальную загрузку импортируемых функций, т.е. фактически такой script будет иметь над Вашей программой полный контроль (под Win32 мне вообще неизвестны подобные инструменты. BoundsChecker конечно может отслеживать все вызовы импортируемых функций, но пока никому не пришла мысль дописать к нему script engine и использовать, например, для memory patching). Пока Вы можете вздохнуть свободно - из-за недостатка времени эта идея уже третий месяц лежит в долгом ящике. Но ведь если она пришла в мой извращённый мозг - она может посетить и кого-нить менее занятого :-)

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

1) Собственный загрузчик в кернеле Можно переписать стандартный загрузчик ELF файлов (файл binfmt_elf.c из директории fs исходников ядра Linux), чтобы сделать жизнь крякера несколько тяжелее. Например, сбрасывать флаг трассировки процесса, иметь собственный формат исполнимых файлов (естественно вместе с перекодировщиком обычных ELF`ов в этот формат), декриптовать/декомпрессировать куски файла перед загрузкой их в память - у меня довольно богатая фантазия. Недостатки:

- как ни странно, самым большим недостатком является необходимость иметь собственный код в kernel`е. Поскольку у конечного пользователя время от времени возникает необходимость в пересборке кернела, Вы должны будете предоставить либо объектный модуль (для насмерть прибитого гвоздями в кернел кода) или опять объектный модуль (для LKM - Linux Kernal Module). И то и другое легко можно дизассемблировать/пропатчить и история повторяется...

- Как насчёт смены версии кернела ? Например, грядёт смена ядра 2.2 на 2.4 - нужно будет иметь (и поддерживать !) как минимум код для обоих версий ядра...

- А если Вы допустите ошибку ? Если для userlevel программ Ваши ошибки скорее всего не смертельны, то ошибки в коде кернела могут иметь весьма плачевные последствия. Кроме того, отладка такого кода является сущим кошмаром, поверьте мне...

- Субъективная причина - сложность установки. Если Вам скажут, что для использования, скажем, Photoshop`ом Вам придётся загрузить модуль ядра, а при сборке ядра Вам необходимо сделать такие-то действия - я просто хочу знать Вашу реакцию :-)...

При всех недостатках это вполне приемлемый вариант для серверов, работающих в режиме 7x24x365, где кернел модернизируется раз в год (при обязательном условии, что Ваш встраиваемый в кернел код глючит относительно редко). Так что для серверных приложений (каких-нить баз данных, например), real-time приложений, и приложений, всё равно требующих изменений в кернеле (например драйверов какого-нть заказного железа, см. ниже), этот вариант вполне может использоваться...
Rating: 1-20%, в зависимости от реализации.

2) Собственный ELF interpretor Только подумайте о том, чего можно добиться, используя собственную версию ELF interpretor`а !

- Скажите "прощай" предварительной загрузке, поддержке отладчика (кстати, разве я не говорил, что для нормальной работы всё того же GDB стандартный ELF interpretor должен иметь кое-какие функции ?) и тому подобным прелестям.

- А ведь почти всё, что было описано выше для загрузчика в ядре применимо также и для ELF interpretor`а. Он может перед передачей управления основной программе распаковать/декриптовать её части, проверить наличие/отсутствие лицензии, проверить наличие отладчика в памяти и много ещё чего. Причём, в отличие от LKM, он может использовать стандартную C runtime library, его написание (и самое главное отладка) намного легче, и ошибка в нём (в общем-то все программы содержат ошибки. Любое тестирование может выявить лишь их наличие, но никак не их отсутствие) не приведёт к необходимости перезагрузки системы и порче системных файлов (ну, если Вы не работаете как root :-).

- Он может снять ещё одну Вашу головную боль - проверять подлинность разделяемых библиотек. Допустим, что Вы подписываете все используемые Вами библиотеки (скажем, посредством MD5 или SHA hash). Теперь при загрузке такой библиотеки можно повторно вычислить цифровую подпись - и если фактическая не совпадает с имеющейся - ба, да нас ломают ! Т.е. с некоторой вероятностью Вы будете уверены после этой процедуры, что вызов несчастной функции strcmp будет вызывать Вашу реализацию strcmp из подписанной Вами библиотеки...

Мой извращённый мозг может генерировать довольно много применений собственной версии ELF interpretor`а, но этот способ также имеет недостатки:

- ELF interpretor - всего лишь программа. Поэтому она также может быть дизассемблирована/пропатчена...

- Как насчёт memory dump/memory patch ? Конечно, можно сделать так, чтобы перед передачей управления главной программе ELF interpretor затирал в памяти все данные, использованные для её загрузки (символьную и строковую таблицы, информацию о relocations и т.д.), но тем не менее всё равно Ваша программа в памяти находится в боевой готовности к выполнению, полностью распакованной, расшифрованной, с широко раскинутыми ногами, в общем :-)
Вполне реально написать memory dumper, который будет формировать на диске статически "слинкованный" исполнимый файл прямо из образа Вашей программы в памяти. Более того, этот файл будет работоспособен (ведь в памяти уже однажды всё было готово к исполнению, все библиотеки загружены, relocations выполнены...) - просто размерчик у него будет больше среднего :-). Нда, надо будет как-нть заняться этим...
Также весьма многообещающим выглядит модификация куска кода в кернеле, отвечающая за формирование core dumps.

Rating: 1-20%, сильно зависит от реализации.


Применение виртуальной среды исполнения


Да, что-то вроде старой недоброй Java - свой ассемблер, свой процессор, свой язык. Необязательно писать всю программу на таком чудовище - достаточно написать на нём макросы, и добавить к ним парочку, отвечающую за защиту (если я ещё не выжил из ума окончательно, есть такой неплохой редактор CRiSP, хорошо попивший у меня крови в своё время - в нём использовалась именно такая схема защиты. Ему правда всё равно не помогло :-). Если с достоинствами всё ясно, то недостатки несколько менее очевидны:

- Нельзя использовать готовые script engines, чьи исходники доступны. Мне однажды пришлось написать дизассемблер с байткодов Pythonа (для поискового сервера UltraSeek ) - это оказалось на удивление простой задачей - ведь у меня были исходные коды !

- поэтому Вам нужно написать собственную среду исполнения. Это довольно нетривиальная и дорогостоящая задача...


Применение аппаратных средств защиты


Я лично считаю, что если некая привинченная к порту железка (dongle) не несёт в себе часть функциональности самой программы, то она просто бесполезна, и программа, "защищённая" таким образом, легко может, и более того, просто обязана быть взломана. Такая затычка занимает целый порт, коих и так обычно недостаточно (я видел однажды гирлянду из пяти dongles, нанизанных друг на друга. Как говорил ослик Иа, "байтораздирающее зрелище" :-). Обратитесь к парням из UCL, они намного лучше меня разбираются в данном вопросе.
Но мы имеем совершенно другую картину, если такая железка используется не просто в декоративных целях, а реально необходима для функционирования программы. Примеры таких аппаратно-программных комплексов:

- Аппаратно реализованные модули криптографии, например, для зашифрованной файловой системы. Где-то я уже видел нечто аналогичное, если я не ошибаюсь, был использован IBM 4758 PCI Cryptographic Coprocessor (http://www-4.ibm.com/cgi-bin/software/developer/click.cgi?url=oss.software.ibm.com/developerworks/opensource/4758/index.html)

- Прога для сопряжения с уникальным (в смысле заказным, не массовым) оборудованием, всяческими DSP, измерительными приборами etc. Кстати, я нашёл неплохую ссылку на Linux-драйверы для подобных устройств: http://www.llp.fu-berlin.de/pool/software/. Создание драйвера под Linux не намного отличается от создания драйвера под любую другую операционную систему.

Т.е. без такой железки Ваша программа просто не имеет смысла. Можно вообще не заботиться об её защите (возможно даже её распространение под GPL) - если такие железки производите только Вы, и больше никто. Впрочем, всегда помните о такой страшной штуке, как послойное копирование (особенно этим пробавлялись Япония и не так давно СССР)...


Клиент-сервер


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


Практическая реализация


Суха теория, да древо жизни пышно зеленеет...
Почти всё вышеописанное имеет один недостаток - это всё плоды моего не в меру воспалённого сознания. Так что пару недель назад я таки реализовал некоторые из вышеизложенных идей - я написал настоящий packer/runtine unpacker для Linuxа (первый, насколько я знаю. Дело в том, что UPX и ExePack не являются настоящими unpackerами, какие мы привыкли видеть под DOS/Win32. Они просто распаковывают исполнимый файл во временную директорию, запускают его как обычный файл, а по окончании работы удаляют. Святая наивность в действии...). Я имею версию как для Linux с ядром 2.2, так и под FreeBSD 3.4 (и есть подозрения, что он будет работать также и с версиями FreeBSD 3.X). Распаковка происходит в моём собственном ELF interpretor`е, он также не поддерживает GDB и LD_PRELOAD. Вследствие этого, пока мой packer умеет сжимать только файлы с ELF interpretor`ом. Справедливости ради нужно заметить, что таких в Red Hat 6.1 около 96 %. Кстати, мой packer/unpacker также продаётся :-)
Для демонстрации его возможностей я написал простой crack.me (http://www.revers.forinfo.ru/other/crackme.tgz) под Linux (опять же первый, насколько я знаю), упакованный моим packerом. Он требует Linux с ядром 2.2 и glibc 2.1 (да да, я намеренно использую динамическую линковку с C RunTime library- как наихудший вариант для применения envelop-защиты наподобие моего packerа). Инсталляция очень проста - поместите файл rp-linux.so.0 (собственно это и есть мой ELF interpretor) в директорию /lib и дайте ему права на исполнение. Эти операции необходимо проделать от пользователя root. А дальше запускайте мой crack.me (под каким хотите пользователем. Вообще для параноиков, в любом shell scriptе видящем трояна, я рекомендовал бы использовать отдельно стоящую машинку без сетевой карты с только что сделанным backupом). Смысл заключается в том, чтобы заставить его сказать что-нть кроме "You are wrong". Для этого Вы должны ввести пароль. Пароль имеет длину больше восьми символов, что делает простой перебор несколько неэффективным (я надеюсь :-). Happy cracking !


Жалобы и предложения


(а также если у Вас появится навязчивая идея нанять меня на работу :-) можно отправлять автору по адресу redplait@usa.net.

#include <std_disclaim.h>

Статью добавил dzen <dzen@inbox.ru>

Обсуждение статьи: Обзор защит программного обеспечения под Linux >>>


Комментарии к статье: Обзор защит программного обеспечения под Linux

SLV 28.07.2004 14:09:12
У меня есть на харде подобная статья. А так нормуль, только я наврятли в ближайшее времи буду что-нибудь под Линукс ломать...
---
aL 28.07.2004 15:24:07
Rulezzzz!
---
Jadex2004 29.07.2004 01:22:22
Молодец - отошёл от стереотипов, хорошая статья
---
--- 29.07.2004 18:10:48
а под linux/unix crackme нет ни у кого? простеньких каких -нить
p.s. то что можно было найти по google уже нашел ;)
---
Mafia32/[ROCK] 31.07.2004 15:59:01
Фуу. Я уж думал нормальные статьи совсем перевелись. Хорошая работа!
---

Материалы находятся на сайте https://exelab.ru



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS