Исследование защиты программы JavaScript Scrambler


Скриншот программы JavaScript Scrambler

Читаю сейчас умную книжку по JavaScript, в одной из глав наткнулся на описание якобы крутой программы для защиты исходных кодов JavaScript от всяких посягательств. И там же было сказано, что программа еще и платная. Речь идет о JavaScript Scrambler. Не знаю что мне захотелось больше: поковыряться внутри самой программы или в результатах ее работы. Так что придется воплощать в жизнь оба желания.

С главной страницы сайта ссылок на программу нет, более того, нет вообще никаких упоминаний о ней, что уже настораживает. Ладно, качаем дистрибутив по прямой ссылке. Устанавливать ничего не надо, все лежит в архиве. Беглый осмотр пациента указывает, что главный файл ничем не упакован. Пока работает дизассемблер, почитаем описание с офсайта: "... заменяет до 100 имен функций на рандомные имена ..." (мне было лениво разбираться с динамическим распределением памяти, поэтому я тупо забил массив из 100 строк фиксированной длины), "... обработка html-файлов размером аж до 60 килобайт ..." (блин, и тут придется делать динамическое выделение памяти, ладно, пусть будет массив 60000 of char), "... возможность пакетной обработки файлов через командную строку ..." (выбор одного файла я уже умею делать, про drag'n'drop, listbox и групповую обработку файлов почитаю в другой раз). В скобках указаны предполагаемые мысли аффтара этой поделки на этапе ее разработки.

Ладно, оставим аффтара в покое, вернемся к его выкидышу. На ввод левых регистрационных данных программа реагирует сообщением "The serial number you entered, was wrong!". Замечательно, вот эта строка в файле:


Нехорошая строка найдена

Посмотрим, что нам скажет дизассемблер. Параллельно пройдем этот блок под отладчиком, чтобы было понятно, откуда что берется. В листинге все ключевые места прокомментированы.
CODE:00433F69                 lea     edx, [ebp+var_8]
CODE:00433F6C                 mov     eax, [ebx+230h]
CODE:00433F72                 call    sub_41A8BC
CODE:00433F77                 mov     eax, [ebp+var_4]
CODE:00433F7A                 call    sub_403A30
; Проверка длины имени, если оно меньше 4 символов, то дальше ничего не проверять
CODE:00433F7F                 cmp     eax, 4
CODE:00433F82                 jle     loc_43406D
CODE:00433F88                 lea     ecx, [ebp+var_C]
CODE:00433F8B                 mov     edx, [ebp+var_4]
CODE:00433F8E                 mov     eax, ebx
; Тут из имени вычисляется правильный серийный номер
CODE:00433F90                 call    sub_4339B0
CODE:00433F95                 mov     eax, [ebp+var_C]
CODE:00433F98                 mov     edx, [ebp+var_8]
CODE:00433F9B                 call    sub_403B40
; Если функция не установила флаг ZF, то серийный номер неправильный
; Так работает функция сравнения двух строк, адреса которых переданы в
; регистрах EAX и EDX
CODE:00433FA0                 jnz     loc_43406D
; Сохранить правильные регистрационные данные
CODE:00433FA6                 mov     ds:byte_435948, 1
CODE:00433FAD                 mov     ecx, offset aJsscrambler__0
; "JSScrambler.ini" - теперь мы знаем, куда это все будет записываться
CODE:00433FB2                 mov     dl, 1
CODE:00433FB4                 mov     eax, off_42F3D4
CODE:00433FB9                 call    sub_42F430
CODE:00433FBE                 mov     esi, eax
CODE:00433FC0                 mov     eax, [ebp+var_4]
CODE:00433FC3                 push    eax
CODE:00433FC4                 mov     ecx, offset aName_0 ; "Name"
CODE:00433FC9                 mov     edx, offset aJavascriptSc_2
; "JavaScript Scrambler"
CODE:00433FCE                 mov     eax, esi
CODE:00433FD0                 call    sub_42F4C4
CODE:00433FD5                 mov     eax, [ebp+var_8]
CODE:00433FD8                 push    eax
CODE:00433FD9                 mov     ecx, offset dword_43411C
CODE:00433FDE                 mov     edx, offset aJavascriptSc_2
; "JavaScript Scrambler"
CODE:00433FE3                 mov     eax, esi
CODE:00433FE5                 call    sub_42F4C4
CODE:00433FEA                 mov     eax, esi
CODE:00433FEC                 call    sub_402D50
CODE:00433FF1                 mov     eax, offset aThankYouForR_0
; "Thank you for registering!"
CODE:00433FF6                 call    sub_42F1E4
CODE:00433FFB                 mov     edx, offset aJavascriptSc_3
; "JavaScript Scrambler V1.11"
CODE:00434000                 mov     eax, ds:dword_43673C
CODE:00434005                 call    sub_41A8EC
CODE:0043400A                 push    offset dword_43417C
CODE:0043400F                 push    [ebp+var_4]
CODE:00434012                 push    offset dword_434194
CODE:00434017                 lea     eax, [ebp+var_C]
CODE:0043401A                 mov     edx, 3
CODE:0043401F                 call    sub_403AF0
CODE:00434024                 mov     edx, [ebp+var_C]
CODE:00434027                 mov     eax, [ebx+21Ch]
CODE:0043402D                 call    sub_41A8EC
CODE:00434032                 mov     edx, offset aThankYouForR_0
; Вывести сообщение "Thank you for registering!"
CODE:00434037                 mov     eax, [ebx+220h]
CODE:0043403D                 call    sub_41A8EC
CODE:00434042                 xor     edx, edx
CODE:00434044                 mov     eax, [ebx+1F8h]
CODE:0043404A                 call    sub_430E88
CODE:0043404F                 mov     eax, [ebx+1F8h]
CODE:00434055                 mov     edx, [eax]
CODE:00434057                 call    dword ptr [edx+50h]
CODE:0043405A                 mov     edx, [ebx+1ECh]
CODE:00434060                 mov     eax, [ebx+1E8h]
CODE:00434066                 call    sub_4312B0
CODE:0043406B                 jmp     short loc_4340A2
CODE:0043406D ; ------------------------------------------------
CODE:0043406D loc_43406D:
CODE:0043406D                 mov     eax, offset aTheSerialNumbe
; Вывести сообщение "The serial number you entered, was wrong"...
CODE:00434072                 call    sub_42F1E4
CODE:00434077                 xor     edx, edx
CODE:00434079                 mov     eax, [ebx+22Ch]
CODE:0043407F                 call    sub_41A8EC

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


Серийный номер на стеке

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


Программа успешно зарегистрирована

Файл с регистрационными данными JSScrambler.ini создается в папке Windows. Ну правильно, блин, больше ж негде... Тратить время на кейгенинг этого убожества даже не хочется, хоть алгоритм там очень простой. Ладно, ограничение по размеру обрабатываемых файлов теперь снято, можно посмотреть как это чудо программерской мысли зарекомендует себя в работе. Включаем все опции защиты, но даже в этом режиме программа категорически отказывается обрабатывать чистые скрипты .js, они обязательно должны быть внутри тегов script в html-странице. Хорошо, сделаем как просят. Вот что получилось у меня после обработки (фрагмент кода):
function x065309(lay){if(loaded==0)return false;if(is.ie4up)document.all(lay).style.visibility='visible';else if(is.gecko)document.getElementById(lay).style.visibility='visible';}
function x058446(lay){if(loaded==0)return false;if(is.ie4up)document.all(lay).style.visibility='hidden';else if(is.gecko)document.getElementById(lay).style.visibility='hidden';}

Что мы видим? Переносы строк, пробелы и комментарии убраны, имена функций заменены на псевдослучайные, имена переменных не тронуты, текстовые строки не искажены. Стойкость такой защиты уверенно стремится к нулю. Из-за отсутствия полноценной пакетной обработки при нескольких взаимосвязанных скриптах корректность результата работы JavaScript Scrambler в точности равна такому же нулевому значению. Этакий сферический говнософт в вакууме: ни украсть, ни покараулить. Видимо аффтар не зря решил не выкладывать этот позор на всеобщее обозрение, вот только мне непонятно, как ЭТО может стоить аж целых 15 баксов?
Теги:
защита, взлом, javascript
Добавлено: 20 Сентября 2013 10:53:42 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...