index5 - Reverse engineering: правда и ложь

Если вы мне сообщите, что за всю жизнь вы ни разу не пользовались «ломалкой» для какой-нибудь утилиты или пиратской копией какой-либо программы, то я вам все равно не поверю.

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

Может это и можно назвать воровством, но вы ведь не станете спорить с тем, что обход защиты программы это своего рода искусство. Да и где здесь граница проходит? Могу же я отлаживать на предмет поиска ошибок свои программы, так как почему же я не могу отлаживать программы других людей? А чем же является сообщение о неправильно введенном серийном номере или пароле, кроме как сообщением об ошибке?

Заметьте при этом, что я ни в коем случае не ставлю перед собой цель наживы. Мой интерес сугубо теоретический. И, конечно, могу «выложить» на интернет сломанную мною программу. Но ведь и здесь никакой выгоды для меня нет. Ведь не перепродаю же я ее в самом деле. Просто хочу похвастаться достижениями. А если кто-то сломанной мною программой будет незаконно пользоваться, так ведь это же он закон нарушает, а не я. С него и спрашивайте.

В общем, мне стало чертовски интересно, что же из себя этот самый reverse engineering (искусство заключения выводов о внутреннем устройстве программы только на основании ее внешнего поведения) представляет. И где же проходит грань между обучением чему-либо и нарушением закона. Я еще не решил, какой будет моя статья (или цикл статей) – практической или сугубо теоретической. Будем ли мы обсуждать тонкости дизассемблирования или говорить о правовых нормах, изучать мнемонику ассемблерных команд или придумывать новые интересные способы защиты.

index22 - Reverse engineering: правда и ложь

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

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

Я помню программу GameHack. Работала она чересчур просто. До начала игры вы делали дамп памяти - что-то вроде сохраненной про запас копии всех тех ноликов и единичек, хранящихся внутри компьютерной оперативки. Когда ситуация в игре менялась (например, у вас стало на одну жизнь меньше), вы повторяли процедуру. GameHack пытался анализировать эти два дампа и найти место в памяти, ответственное за число ваших жизней. Разумеется, чем больше дампов вы делали, тем аккуратнее был результат. Пользуясь этой же программой, вы могли сравняться с кошкой по количеству жизней. Также можно было редактировать «сэйвы». Как правило, из-за работы компаратора у вас «летела» вся система, но иногда все проходило неплохо, и вы заканчивали игру в предельно короткие сроки.

Потом появились «тренеры» - небольшие программки, рассчитанные на специфическую игрушку. С их помощью вы могли получить любое оружие, любые деньги и перескочить на любой уровень. Наверное, именно с тренеров и началось разделение между крэкерами и пользователями. До этого времени это были одни и те же люди. Теперь же появились программисты, которым интересней было ломать игрушку, чем проходить ее. А что? По крайней мере, это тренировка мозгов. Потом они, конечно, с игрушек к серьезным вещам перешли.

index32 - Reverse engineering: правда и ложьТут-то разработчики и засуетились и начали всякие хитрые способы защиты придумывать. Посмотрите чего только они не напридумывали.

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

Expiration. Чудо. Просто чудо. Программа функционирует определенный срок после чего отказывается работать вовсе. И ничего вам после этого не поможет. Ни новая ее инсталляция, ни формат диска. Такие программы называют еще trial version. Ее создатель наивно полагает, что за трехдневный срок мы все про эту программу поймем и, если нам действительно надо, то и купим. А если нет, так другие клиенты найдутся. Для тех из вас, кто хоть немного знаком с программированием, добавлю, что для подобной проверки используется как выставление флагов в системном реестре, так и проверка checksum или header-файлов.

User registration. Этот метод защиты требует от вас предварительной оплаты. На основании вашего имени, email-а или подобной информации вам высылается аутентичный код, при помощи которого вы и разблокируете программу. Очевидно, что внутри программы при этом генерируется код на основании введенных вами данных и какого-то хитрого алгоритма. Он-то и сравнивается потом с кодом, который ввели вы. Подобный метод используется в программах WinZip или CuteFTP, а также во многих других.

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

Генерация кода.

If (введенный код=генерированный код) then (программа зарегистрирована) else (Сообщение: «Введите правильный код!»)

Крэкеру достаточно поменять равенство на неравенство, и программа будет вскрыта любым кодом, кроме правильного. Недостаток такого метода очевиден. При выходе новой версии этой программы необходимо снова влезать в код. Тогда как шансы того, что изменится сам алгоритм генерации, много меньше.

Дело в том, что если бы для каждой новой версии программы алгоритм подсчета unlock code изменялся бы, автору приходилось бы спешно рассылать новый код всем предыдущим клиентам. Если, конечно, в условия покупки программы входила возможность бесплатных апгрейдов.

Поехали дальше. Commercial strength wrappers. Это чудовище появилось на свет тогда, когда появились первые безумцы, готовые отослать через интернет номер своей кредитной карточки и таким образом получить желаемый продукт и массу проблем на свою голову. Выглядит это следующим образом. Готовый продукт запакован в своего рода оболочку (wrapper) и недоступен, пока вы это оболочку не вскроете при помощи номера вашей кредитки или каким-то менее законным способом. Преимущества для крэкера очевидно. Вам достаточно лишь вскрыть dll файл, ответственный за проверку номера и его отсылку на сервер, и вы сможете использовать любую программу, запакованную в этот wrapper. На сегодняшний день число коммерческих wrapper-ов огромно. Самыми распространенными стали Release Software Agent, Vbox, unBoxed, Techwave и многие другие.

Неплохим способом защиты является также и постоянная проверка легальности копии, проводимая самой программой через интернет. Так, например, программа audiograbber просто сверяется с большой базой данных, находящейся на сервере разработчиков, и проверяет действителен ли ваш серийный номер. Если нет, то результат может быть плачевным. Нет, конечно, форматировать диск программа не будет - слишком уж риск велик. Может какой-нибудь компьютерный клерк ваш на 100% законный номер просто забыл в список внести. Но в системный реестр эта программа такого понапишет, что сто лет потом выискивать и стирать придется.

Самым на сегодняшний день действенным средством защиты стала hardware (dongle) protection. Это небольшая железка, подключаемая к одному из свободных портов вашего компьютера. Внутри нее может быть что угодно - от записанной на чип программы, проверяющей серийный номер, до вшитых внутрь API функций. Чтобы «сломать» программу с такой защитой, как правило, необходимо иметь эту самую железку. А это значит, что кто-то должен все-таки программу купить. Ходят слухи, что dongle может и сгореть, если залезть в него внутрь, а для крэкера, купившего многотысячедолларовую, программу это не самое приятное. Не каждая из групп крэкеров может позволить себе такое удовольствие. Как правило, для этого приходится завязывать знакомства в компьютерных магазинах и  платить работающим там продавцам.

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

Очевидно, что единого способа и метода для взлома программ не существует, однако программы, помогающие это сделать, в общем-то, одни и те же. К тому же они широко распространены и абсолютно легальны. Я расскажу вам об этих утилитах.

index41 - Reverse engineering: правда и ложь

Начнем с программы SoftIce (Numega Corporation – www.numega.com). Извините за то, что я не привожу screenshots этой программы. SoftIce работает в нулевом кольце защиты и получить изображение ее интерфейса практически невозможно. Не пугайтесь нового термина. Выражение «кольцо защиты» служит для обозначения факта разграничения взаимодействия выполняющихся программ. Речь идет о взаимодействии программ как между собой, так и с операционной системой. В данном случае с Windows. Как правило, в нулевом кольце защиты работает сама операционная система. Это значит, что она способна запускать другие приложения и контролировать ресурсы вашего компьютера. Все системные задачи выполняются в 1-м и 2-м кольцах, а программы, запускаемые пользователем, выполняются в 3-м кольце.

Отличие SoftIce от других отладчиков в том, что он загружается перед операционной системой и в состоянии контролировать не только запускаемые приложения, но и саму Windows. Как же этот SoftIce использовать? Более подробную информацию я предоставлю в следующей статье, а пока лишь нарисую общую схему.

Сейчас нам понадобится немного теории. Я собираюсь рассказать вам о прерываниях (breakpoint). Прерывания в системе являются требованием к процессору прекратить выполнение той или иной задачи. Обращаться могут как периферийные устройства (модем, мышка и другие), так и сама операционная система или запущенная программа. Это очень эффективная штука. Не будь ее, процессору нужно было бы время от времени прерываться самому, для того чтобы узнать, не нужно ли предоставить компьютерные ресурсы для решения какой-нибудь особенно важной задачи.

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

Похоже, что я не очень внятно (если вообще хоть как-то) объяснил, что представляет собой API и с чем его едят. Вы наверняка обращали внимание на то, что в вашей виндоузовской директории полным-полно файлов с расширением dll. Именно в них-то и находятся эти самые Application Programming Interfaces – API. Для простоты ситуации советую воспринимать эти файлы как процедуры или функции, вынесенные за пределы программы. Просто так сложилось, что одни функции используются настолько часто, что их пришлось внести в специальные файлы и записать в системную директорию.

На языке ассемблера это выглядит приблизительно так:

push characterA

push characterB

call CombineCharacters

Именно этот самый call и есть вызов API функции. При этом API вернет нам указатель на строку-результат.

Очевидно, что для того, чтобы добиться хоть каких-то успехов в reverse engineering, вам понадобится неплохое знание ассемблера. Нет, конечно, самые азы вы изучите и без него, но это действительно будут самые базисные вещи. ОК, предположим, что вы нашли ту самую строку, в которой проверяется правильность введенного серийного номера. Используя SoftIce, вы можете ее изменить для того, чтобы проверить действительно ли программа принимает любой набор символов и регистрируется после этого. Проблема лишь в том, что SoftIce не изменяет сам программный файл, и потому такое изменение временно.

Теперь вам нужен hex editor. Программа, которая может дизассемблировать любой код и предоставить пользователю возможность его изменения. Для этого вы можете использовать Norton DiskEdit, Hackers View или Hex Workshop.

Не менее мощным оружием является программа W32Dasm. Предположим, что апгрейд к какой-то игрушке требует наличия оригинального CD с инсталляцией. Если его нет, то на экране появляется сообщение об ошибке. Ага, - говорите вы и открываете программу в W32Dasm. Теперь вы просто ищите текст сообщения и, просматривая код, находите строку, в которой проверяется наличие CD. Как правило, подобным апгрейдам не нужна информация, хранящаяся на диске. Создатели игрушки хотят убедиться в том, что эту копию вы действительно приобрели. Разумеется, подобный способ защиты обходится и с использованием SoftIce. Вам лишь нужно выставить правильное прерывание. Однако в ряде случаев W32Dasm оказывается удобнее.

Случается, что одного W32Dasm оказывается вполне достаточно, так как некоторые программисты просто «впаивают» серийные номера внутрь программы. Наверное, таким образом они экономят время написания кода и размер программы. Действительно, какой смысл вставлять в 2-3 килобайтную программку здоровый 10-15 килобайтный код, рассчитывающий серийный номер.

Одним из самых простых и ненапряжных способов является внимательное прочтение string references (то есть всех строк, заданных в программе). Найдите что-то похожее на «Спасибо за покупку. Приходите еще…» и посмотрите на код, который находится перед этой строкой. Если вам повезет, то вы увидите что-то вроде Referenced by a conditional jump at 55efcd.

Переводя это на русский язык, мы догадываемся, что по адресу 55efcd произошла какая-то проверка. Теперь-то мы знаем, что именно нам надо изменить для того, чтобы увидеть желаемое сообщение. Вам нужно сделать всего пару операций: найти смещение (offset) и изменить команду по этому адресу.

Слышу недоуменные возгласы: «Что такое смещение и с чем его едят?». Не знаю, насколько имеет смысл в первой же обзорной статье уходить в такие частности, но раз уж начал…

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

Когда вы ищете нужный дом или квартиру, вы действуете похожим способом. Сначала находите номер дома (сегмент), а потом номер квартиры (смещение).

Итак, для того чтобы найти смещение вам нужно сделать следующую вещь. Подведите курсор на строку с проверкой и посмотрите на текст, который появился в самом низу окна W32Dasm. Там-то и должна располагаться интересующая вас информация. Теперь вы знаете, по какому адресу менять команду. А вот на что ее менять, это уже второй вопрос.

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

Давайте-ка рассмотрим напоследок общую схему обхода защиты программы, использующую keyfile в качестве проверки регистрации.

Идея здесь такова. Вы можете пользоваться программой, но она останется незарегистрированной до тех пор, пока автор программы не вышлет вам еще один файл. В нем могут быть как дополнительные API функции, расширяющие функциональность программы, так и регистрационный номер в каком-нибудь хитром формате (не обязательно текстовом). За примером такой программы далеко ходить не надо. Возьмите Antivirus Toolkit Pro (www.avp.com).

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

Вам снова поможет W32Dasm. Загрузите программу в этот отладчик и поищите строку похожую на «program.key…» или «program.lic…».

Если вы не нашли ничего похожего, но уверены, что имеете дело именно с этим типом защиты, то вам придется воспользоваться немного другим типом утилит.

Ряд программ позволяют вам понаблюдать, к каким файлам или строкам системного реестра программа обращается при запуске или работе. Не надо проявлять чудеса наблюдательности для того, чтобы увидеть, что программа пытается обратиться к какому-то файлу, которого просто не существует. Шанс того, что этот файл тот самый keyfile очень велик.

Теперь вам понадобится открыть какую-нибудь книжку и выяснить, какой именно API используется для чтения из файла. Ладно, книгу можно не открывать. Вам нужно рассмотреть повнимательнее Read File API.

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

Свои собственные заморочки есть у программ, написанных на visual basic-е. Дело в том, что эти программы не используют стандартного виндоузовского API. У них свой собственный API. Видели, наверное, файлы Vbrun300.dll, Vbrun400.dll, Msvbm50.dll и другие, похожие на них? Вот, это он самый API и есть.

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

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

Крэкер – это особенное состояние души. Это ночи заполненные чтением книг и руководств пользователя. Это постоянно «летящий» компьютер и огромные телефонные счета. Ведь вначале вы не сумеете работать в одиночку, вам нужны будут опытные наставники, да и утилиты для практики надо будет «скачивать» ежедневно.

Зато мозги у вас будут работать на все катушку. Думать придется много, еще больше запоминать. Академического подхода здесь просто не существует. Придется учиться на ошибках, причем, как правило, на своих. Надеюсь, что заинтересовал и заинтриговал вас.

Тэги записи: hard and soft