Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #74, ФЕВРАЛЬ 2005 г.

Пишем профессиональную защиту

GPcH (www.dotfix.net)

Хакер, номер #074, стр. 074-112-3


user name

XOR

savesaves

Если имя пользователя больше 4 символов, мы просто нарастим второй параметр криптовки (слово «save») до нужного нам размера (минимальное имя пользователя - 4 символа). Результат XOR'а - это и есть пароль, который мы дадим пользователю, когда он купит нашу программу. Как известно, операция XOR обратима, то есть мы легко можем из имени и пароля получить обратно строку «savesaves», проксорив имя с паролем. Саму же строчку «save» мы легко получим, считав первые 4 символа. Надеюсь, ты помнишь, что введенные пользователем данные нужно хранить в глобальных переменных? Так вот, в обработчик кнопки «Сохранить» мы напишем следующее:

callbyname frmMain, GetFunction(strName, strPass), vbMethod

callbyname здесь – это весьма позитивная штука, поскольку данный оператор присутствует только в Visual Basic'е и не имеет аналогов ни в Delphi, ни в C++. Служит он для вызова функции по ее имени, которое может храниться где угодно, включая переменные. Первым параметром данной функции служит объект, который содержит вызываемую нами функцию, вторым - имя функции и третьим - тип функции (vbGet, vbLet, vbMethod, vbSet).

Имя функции мы будем получать из имени пользователя и его пароля функцией GetFunction. Соответственно, если мы проксорим верное имя с паролем, то первые четыре символа будут именем функции - их и возвратит GetFunction (посмотреть ее код можно на врезке 1). В противном случае GetFunction может возвратить что угодно, но не «save», при этом программа сглючит. Чтобы этого не произошло, напиши код так:

On Error GoTo lamo

Callbyname frmMain,vbMethod, GetFunction(strName, strPass)

Exit Sub

lamo: msgbox «Пасс неверный»

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

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

А теперь поговорим про действительно хардкорный метод защиты программ паролем - использование ассемблерной функции.

Пароль - функция на ассемблере

Вот мы и дошли до самого интересного. А что если в качестве пароля использовать ассемблерную функцию, возвращающую одну из составляющих имени пользователя, например ASCII-код второго символа имени? Неплохо, но что это нам даст? Это нам позволит сравнить пароль пользователя с результатом работы ассемблерной функции, имя же пользователя мы сможем использовать в качестве ключа для шифровки ассемблерной функции от чужих глаз. Я для этих целей использую алгоритм blowfish. У этого алгоритма есть одна особенность - в качестве ключа для шифровки он принимает только цифры, поэтому проще шифровать не всем именем пользователя, а, например, его контрольной суммой. Это, я думаю, ты реализуешь сам, здесь же для простоты мы будем шифровать ASCII-кодом третьего символа имени пользователя. То есть пользователь вводит имя и пароль, мы декриптуем пароль третьим символом имени и запускаем полученную в результате декриптовки ассемблерную функцию с помощью API-функции CallWindowProc. Функция должна нам возвратить ASCII-код второго символа имени. Если это так - пользователь ввел верный пароль, иначе, если в качестве пароля был введен просто мусор, произойдет ошибка либо при декриптовке, либо при вызове этого мусора и прога вызовет недопустимую операцию. От этого нас спасет уже известный нам On Error GoTo lamo :). Хотя передача мусора непосредственно в CallWindowsProc крайне нежелательна: представь, что будет, если процессору на исполнение пойдет мусор, - так можно и винт форматнуть по глупости. Но я тебя обрадую - если пользователь введет мусор вместо пароля, то ошибка в 99% случаев произойдет в функции декриптовки, и до процессора дело не дойдет. Сама же функция проверки в общем виде представлена в листинге 3.

Назад на стр. 074-112-2  Содержание  Вперед на стр. 074-112-4