Blog. Just Blog

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

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Темная сторона Силы | Автор: ManHunter
Скриншот программы 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!". Замечательно, вот эта строка в файле:

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

Посмотрим, что нам скажет дизассемблер. Параллельно пройдем этот блок под отладчиком, чтобы было понятно, откуда что берется. В листинге все ключевые места прокомментированы.
  1. CODE:00433F69                 lea     edx, [ebp+var_8]
  2. CODE:00433F6C                 mov     eax, [ebx+230h]
  3. CODE:00433F72                 call    sub_41A8BC
  4. CODE:00433F77                 mov     eax, [ebp+var_4]
  5. CODE:00433F7A                 call    sub_403A30
  6. ; Проверка длины имени, если оно меньше 4 символов, то дальше ничего не проверять
  7. CODE:00433F7F                 cmp     eax, 4
  8. CODE:00433F82                 jle     loc_43406D
  9. CODE:00433F88                 lea     ecx, [ebp+var_C]
  10. CODE:00433F8B                 mov     edx, [ebp+var_4]
  11. CODE:00433F8E                 mov     eax, ebx
  12. ; Тут из имени вычисляется правильный серийный номер
  13. CODE:00433F90                 call    sub_4339B0
  14. CODE:00433F95                 mov     eax, [ebp+var_C]
  15. CODE:00433F98                 mov     edx, [ebp+var_8]
  16. CODE:00433F9B                 call    sub_403B40
  17. ; Если функция не установила флаг ZF, то серийный номер неправильный
  18. ; Так работает функция сравнения двух строк, адреса которых переданы в
  19. ; регистрах EAX и EDX
  20. CODE:00433FA0                 jnz     loc_43406D
  21. ; Сохранить правильные регистрационные данные
  22. CODE:00433FA6                 mov     ds:byte_435948, 1
  23. CODE:00433FAD                 mov     ecx, offset aJsscrambler__0
  24. ; "JSScrambler.ini" - теперь мы знаем, куда это все будет записываться
  25. CODE:00433FB2                 mov     dl, 1
  26. CODE:00433FB4                 mov     eax, off_42F3D4
  27. CODE:00433FB9                 call    sub_42F430
  28. CODE:00433FBE                 mov     esi, eax
  29. CODE:00433FC0                 mov     eax, [ebp+var_4]
  30. CODE:00433FC3                 push    eax
  31. CODE:00433FC4                 mov     ecx, offset aName_0 ; "Name"
  32. CODE:00433FC9                 mov     edx, offset aJavascriptSc_2
  33. ; "JavaScript Scrambler"
  34. CODE:00433FCE                 mov     eax, esi
  35. CODE:00433FD0                 call    sub_42F4C4
  36. CODE:00433FD5                 mov     eax, [ebp+var_8]
  37. CODE:00433FD8                 push    eax
  38. CODE:00433FD9                 mov     ecx, offset dword_43411C
  39. CODE:00433FDE                 mov     edx, offset aJavascriptSc_2
  40. ; "JavaScript Scrambler"
  41. CODE:00433FE3                 mov     eax, esi
  42. CODE:00433FE5                 call    sub_42F4C4
  43. CODE:00433FEA                 mov     eax, esi
  44. CODE:00433FEC                 call    sub_402D50
  45. CODE:00433FF1                 mov     eax, offset aThankYouForR_0
  46. ; "Thank you for registering!"
  47. CODE:00433FF6                 call    sub_42F1E4
  48. CODE:00433FFB                 mov     edx, offset aJavascriptSc_3
  49. ; "JavaScript Scrambler V1.11"
  50. CODE:00434000                 mov     eax, ds:dword_43673C
  51. CODE:00434005                 call    sub_41A8EC
  52. CODE:0043400A                 push    offset dword_43417C
  53. CODE:0043400F                 push    [ebp+var_4]
  54. CODE:00434012                 push    offset dword_434194
  55. CODE:00434017                 lea     eax, [ebp+var_C]
  56. CODE:0043401A                 mov     edx, 3
  57. CODE:0043401F                 call    sub_403AF0
  58. CODE:00434024                 mov     edx, [ebp+var_C]
  59. CODE:00434027                 mov     eax, [ebx+21Ch]
  60. CODE:0043402D                 call    sub_41A8EC
  61. CODE:00434032                 mov     edx, offset aThankYouForR_0
  62. ; Вывести сообщение "Thank you for registering!"
  63. CODE:00434037                 mov     eax, [ebx+220h]
  64. CODE:0043403D                 call    sub_41A8EC
  65. CODE:00434042                 xor     edx, edx
  66. CODE:00434044                 mov     eax, [ebx+1F8h]
  67. CODE:0043404A                 call    sub_430E88
  68. CODE:0043404F                 mov     eax, [ebx+1F8h]
  69. CODE:00434055                 mov     edx, [eax]
  70. CODE:00434057                 call    dword ptr [edx+50h]
  71. CODE:0043405A                 mov     edx, [ebx+1ECh]
  72. CODE:00434060                 mov     eax, [ebx+1E8h]
  73. CODE:00434066                 call    sub_4312B0
  74. CODE:0043406B                 jmp     short loc_4340A2
  75. CODE:0043406D ; ------------------------------------------------
  76. CODE:0043406D loc_43406D:
  77. CODE:0043406D                 mov     eax, offset aTheSerialNumbe
  78. ; Вывести сообщение "The serial number you entered, was wrong"...
  79. CODE:00434072                 call    sub_42F1E4
  80. CODE:00434077                 xor     edx, edx
  81. CODE:00434079                 mov     eax, [ebx+22Ch]
  82. 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 баксов?

Поделиться ссылкой ВКонтакте Поделиться ссылкой на Facebook Поделиться ссылкой на LiveJournal Поделиться ссылкой в Мой Круг Добавить в Мой мир Добавить на ЛиРу (Liveinternet) Добавить в закладки Memori Добавить в закладки Google
Просмотров: 3993 | Комментариев: 8

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
ANIEL (20.01.2011 в 13:34):
Мне это напоминает американских кинокритиков, критикуют все но никто из них не создал шедевр.
ManHunter (20.08.2010 в 08:41):
А еще в фильме "Ширли-мырли" была хорошая фраза: "Вы слишком много кушать, в смысле зажрались".
Isaev (20.08.2010 в 02:40):
В общем никто не обижался, просто был дан в полне адекватный совет. :)
mrX (20.08.2010 в 00:15):
Зачем сразу обижаться, если действительно автору неинтересно, что думаю о его статьях, то пожалуй найду другой блог. Видать, как читатель я перерос автора. Один известный человек написал: "Или автор застрял в развитии или читатель вырос." :)
ManHunter (19.08.2010 в 23:47):
Значит надо искать другой блог, я уверен, в интернете их более чем много. А еще лучше открыть свой сайт и писать там правильные и интересные статьи. Ну а потом их можно будет приводить мне в пример, чтобы я знал к чему мне стремиться и на что равняться. Это ведь очень просто сделать, не так ли?
mrX (19.08.2010 в 22:29):
К сожалению, с каждой новой статьёй всё меньше интересных и стоящих идей и исследований. Статья ни о чём. Возможно для блога самое то, но зная уровень предыдущих статей, очень печально, что нет хорошего материала.
semenov (18.08.2010 в 18:44):
В любой сфере были, есть и будут подобные гении и их креативы
SAY (18.08.2010 в 11:44):
На каждый товар найдется свой покупатель! :)

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2017
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.09 сек. / MySQL: 2 (0.0057 сек.) / Память: 4.5 Mb
Наверх