Blog. Just Blog

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

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Темная сторона Силы | Автор: ManHunter
Скриншот программы WinSnap
Скриншот программы WinSnap

WinSnap от NTWind Software - удобная программа для создания скриншотов. От множества аналогов отличается тем, что корректно захватывает окна непрямоугольной формы, позволяет сразу же добавлять эффект тени, наносить водяные знаки на изображение, захватывать несколько последовательных окон, а также имеет другие полезные функции, которых нет у конкурентов. Но в пробной версии показывает всякие наг-скрины и маркирует все создаваемые скриншоты своим логотипом. Для исследования защиты нам потребуется дизассемблер и дистрибутив, на момент публикации последняя версия WinSnap 3.0.8 от мая 2009 года.

Устанавливаем и запускаем программу. Нас тут же встречает наг-скрин с предложением потратить наше бабло на покупку или ввести регистрационные данные. Нажимаем кнопку "Зарегистрировать", вводим имя и любой левый серийник, получаем отлуп "Лицензионный ключ неверен!". Отлично, образец "нехорошей" строки у нас есть. Загоняем exe-файл в дизассемблер, и пока он работает, посмотрим где эта строчка имеется. В папке "lang" лежат файлы локализации программы на разных языках, нас интересует русский. В нем и находится наша строчка:

32052="Лицензионный ключ неверен!"
Число 32052 - это уникальный идентификатор строки, по которому она запрашивается из основной программы. Дизассемблер уже закончил свою работу, попробуем поискать число 32052 в коде, только предварительно его надо перевести в шестнадцатеричное представление (получится 7D34h). Найдется только одно вхождение:
  1. ; Тут и выше всякие манипуляции с текстовыми строчками
  2. .text:0040188D                 push    edx
  3. .text:0040188E                 lea     eax, [ebp+var_1590]
  4. .text:00401894                 push    eax             ; int
  5. .text:00401895                 lea     edi, [ebp+var_55C]
  6. .text:0040189B                 lea     ecx, [ebp+String] ; lpWideCharStr
  7. .text:004018A1                 mov     [ebp+var_1590], ebx
  8. .text:004018A7                 mov     [ebp+var_1594], ebx
  9. ; Вызов функции проверки, результат которой влияет на дальнейшую работу
  10. .text:004018AD                 call    sub_40A6F0
  11. .text:004018B2                 add     esp, 8
  12. .text:004018B5                 test    al, al
  13. .text:004018B7                 jnz     short loc_4018C8
  14. ; Вот тут загружается "нехорошая" строка из языкового файла и выводится
  15. ; диалогово окно с сообщением об ошибке
  16. .text:004018B9                 mov     ecx, 7D34h  ; <-- код строки 32052
  17. .text:004018BE                 call    sub_408930
  18. .text:004018C3                 jmp     loc_401A83
  19. .text:004018C8
  20. ; Сюда мы попадаем, если функция проверки вернула AL=1, то есть все нормально
  21. .text:004018C8 loc_4018C8:
  22. .text:004018C8                 lea     ecx, [ebp+String]
  23. .text:004018CE                 push    ecx
  24. ; Дальше по тексту вывод сообщения с благодарностью за регистрацию, запись
  25. ; введенных данных в ключевой файл и прочие ништяки для зарегистрированного
  26. ; пользователя программы
Теперь посмотрим саму функцию проверки:
  1. .text:0040A6F0                 sub     esp, 114h
  2. .text:0040A6F6                 mov     eax, dword_450050
  3. .text:0040A6FB                 xor     eax, esp
  4. .text:0040A6FD                 mov     [esp+114h+var_8], eax
  5. .text:0040A704                 mov     eax, [esp+114h+arg_4]
  6. .text:0040A70B                 push    ebp
  7. .text:0040A70C                 mov     ebp, [esp+118h+arg_0]
  8. .text:0040A713                 push    esi
  9. .text:0040A714                 push    7Fh             ; Size
  10. .text:0040A716                 mov     esi, ecx
  11. .text:0040A718                 lea     ecx, [esp+120h+Dst]
  12. .text:0040A71F                 push    0               ; Val
  13. .text:0040A721                 push    ecx             ; Dst
  14. .text:0040A722                 mov     [esp+128h+var_110], eax
  15. .text:0040A726                 mov     [esp+128h+MultiByteStr], 0
  16. .text:0040A72E                 call    _memset
  17. .text:0040A733                 push    7Fh             ; Size
  18. .text:0040A735                 lea     edx, [esp+12Ch+var_10B]
  19. .text:0040A739                 push    0               ; Val
  20. .text:0040A73B                 push    edx             ; Dst
  21. .text:0040A73C                 mov     [esp+134h+var_10C], 0
  22. .text:0040A741                 call    _memset
  23. .text:0040A746                 add     esp, 18h
  24. .text:0040A749                 push    0               ; lpUsedDefaultChar
  25. .text:0040A74B                 push    0               ; lpDefaultChar
  26. .text:0040A74D                 push    80h             ; cchMultiByte
  27. .text:0040A752                 lea     eax, [esp+128h+MultiByteStr]
  28. .text:0040A759                 push    eax             ; lpMultiByteStr
  29. .text:0040A75A                 push    0FFFFFFFFh      ; cchWideChar
  30. .text:0040A75C                 push    esi             ; lpWideCharStr
  31. .text:0040A75D                 mov     esi, ds:WideCharToMultiByte
  32. .text:0040A763                 push    0               ; dwFlags
  33. .text:0040A765                 push    0FDE9h          ; CodePage
  34. .text:0040A76A                 call    esi ; WideCharToMultiByte
  35. .text:0040A76C                 test    eax, eax
  36. ; Какое-то имя введено, продолжить проверку
  37. .text:0040A76E                 jnz     short loc_40A789
  38. ; Если строка имени пустая, то вернуть AL=0, то есть все плохо
  39. .text:0040A770 loc_40A770:
  40. ; Вернуть AL=0 если не введено имя или серийный номер
  41. .text:0040A770                 xor     al, al
  42. .text:0040A772                 pop     esi
  43. .text:0040A773                 pop     ebp
  44. .text:0040A774                 mov     ecx, [esp+114h+var_8]
  45. .text:0040A77B                 xor     ecx, esp
  46. .text:0040A77D                 call    sub_432AD6
  47. .text:0040A782                 add     esp, 114h
  48. .text:0040A788                 retn
  49. .text:0040A789 loc_40A789:
  50. ; Проверить введен или нет какой-нибудь серийный номер
  51. .text:0040A789                 push    0               ; lpUsedDefaultChar
  52. .text:0040A78B                 push    0               ; lpDefaultChar
  53. .text:0040A78D                 push    80h             ; cchMultiByte
  54. .text:0040A792                 lea     ecx, [esp+128h+var_10C]
  55. .text:0040A796                 push    ecx             ; lpMultiByteStr
  56. .text:0040A797                 push    0FFFFFFFFh      ; cchWideChar
  57. .text:0040A799                 push    edi             ; lpWideCharStr
  58. .text:0040A79A                 push    0               ; dwFlags
  59. .text:0040A79C                 push    0FDE9h          ; CodePage
  60. .text:0040A7A1                 call    esi ; WideCharToMultiByte
  61. .text:0040A7A3                 test    eax, eax
  62. ; Если строка серийника пустая, то вернуть AL=0, то есть все плохо
  63. .text:0040A7A5                 jz      short loc_40A770
  64. ; Записать в стек указатели на имя и серийный номер
  65. .text:0040A7A7                 mov     edx, [esp+11Ch+var_110]
  66. .text:0040A7AB                 push    edx
  67. .text:0040A7AC                 lea     eax, [esp+120h+var_10C]
  68. .text:0040A7B0                 push    eax
  69. .text:0040A7B1                 mov     edx, ebp
  70. .text:0040A7B3                 lea     ecx, [esp+124h+MultiByteStr]
  71. ; Вот тут вызывается вторая функция проверки, которая и выставляет
  72. ; окончательный диагноз правильности регистрационных данных
  73. .text:0040A7BA                 call    sub_409EC0
  74. ; После вызова функции AL=0 - регистрационные данные неправильные
  75. ; или AL=1 - введенные ключ и имя правильные
  76. .text:0040A7BF                 mov     ecx, [esp+124h+var_8]
  77. .text:0040A7C6                 add     esp, 8
  78. .text:0040A7C9                 pop     esi
  79. .text:0040A7CA                 pop     ebp
  80. .text:0040A7CB                 xor     ecx, esp
  81. .text:0040A7CD                 call    sub_432AD6
  82. .text:0040A7D2                 add     esp, 114h
  83. .text:0040A7D8                 retn
  84. .text:0040A7D8 sub_40A6F0      endp
Если посмотреть вторую функцию проверки по адресу 409EC0, то можно обнаружить в ней множество всяких арифметических действий, проверок и вычислений. При большом желании и наличии кучи свободного времени можно попытаться отреверсить алгоритм проверки ключа, но похоже, что он завязян на нехилой криптографии, поэтому проще пропатчить исполняемый файл, чтобы любые регистрационные данные считались правильными. Это лучше сделать или в первой функции проверки по адресу 0040A6F0 или во второй по адресу 00409EC0, заменив первые команды на MOV AL,1; RET. После этих манипуляций WinSnap будет принимать в качестве регистрационных данных любое имя и серийный номер. Можно даже выделить сигнатуру и нарисовать универсальный патч для обычной и портативной версии WinSnap, но это уже сделайте самостоятельно.

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

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

Комментарии

Отзывы посетителей сайта о статье
brute (15.07.2013 в 06:59):
у меня подопытным кроликом была версия 3.5.4 - не запакована. По адресам аналогичным 0040A6F0 и 00409EC0 (адреса другие, байт код тот же) пропатчить не удается.. Ну и фиг с ней - не очнь-то и хотелось, проги Clip2Net и Lightshot лучше. А для веба плагин для firefox есть fireshot.
ManHunter (26.06.2013 в 21:19):
Купить, например.
Dragons (26.06.2013 в 20:52):
Подскажите как получить лицензионный ключ?
Zhelezyaka (04.08.2011 в 10:42):
как в кино: ..прошло несколько лет
поменялась версия - Version 3.5.5 (March 1, 2011)
поменялись адреса - 0040A6F0>0040AE40
остальное - всё тоже самое)
спасибо, маэстро!
artden6 (23.01.2011 в 13:48):
Спасибо
ManHunter (18.01.2011 в 23:38):
Дизасм в IDA Pro, патч в hiew, отладка в Olly.
artden6 (18.01.2011 в 23:13):
Пож подскажите каким дисассемблером вы пользуетесь, вот я качнул ИДУ Про но ничего не могу понять там совсем все по другому не как у Вас на скринах. Вроде и строки нахожу эти но они по другому и изменить ничего не могу, Да команды там не как не поменять Мыло artden6@yandex.ru
ManHunter (19.08.2009 в 23:17):
Ты правда думаешь, что "кого нибут" тут волнует твое "позарес"?
zver` (19.08.2009 в 15:52):
кто нибут мне скажет ключ и имя,мне позарес надо!!!
Vadim (13.08.2009 в 20:28):
Я новенький в этом деле и пропатчить у меня не получилось. Я сделал по другому что бы программа работала как зарегистрированная:
1) Я залез в ресурсы программы и с помощью PE Exlorer-a удалил диалоги:
108, 181, 182
2) Заменил PNG их вотермарк на прозрачный фон с такими же размерами
Ну вот и все )
Наг скринов нет и все работает )
ManHunter (17.06.2009 в 23:50):
azerty, лучше дизассемблера чем IDA Pro пока не придумали. Варезная версия 5.2 находится любым гуглояндексом.
azerty (17.06.2009 в 23:30):
Замечательно расписал. Посоветуй хороший дисассемблер ;)

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

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

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