Blog. Just Blog

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

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

Программа MIDI Workplace от xTau предназначена для конвертирования MIDI-файлов в формат MP3 или WAV. Ну и по мелочи всякого, типа посмотреть список инструментов или просто прослушать MIDI. На офсайте по какой-то причине ее давно нет, да и сам сайт какой-то полуживой. Купить программу уже не получится, даже если вам сильно захочется это сделать, но в незарегистрированном состоянии она обрабатывает не более 30 секунд каждого файла. Будем лечить, ничего не поделаешь.

Забираем дистрибутив с файлообменника, устанавливаем, смотрим. Главный исполняемый файл имеет совсем небольшой размер, к тому же ничем не упакован. Отправляем его сразу же на разбор в дизассемблер.

Сообщение о неправильной регистрации
Сообщение о неправильной регистрации

После запуска сразу же появляется триальное окно с предложением оплатить, ввести регистрационные данные или продолжить работу. На ввод левых регистрационных данных программа реагирует сообщением "Invalid RegCode". Посмотрим в листинге где и как это сообщение проявляется.
  1. .text:0040848F                 push    1Fh             ; cchMax
  2. ; Получить из полей ввода регистрационное имя и серийник
  3. .text:00408491                 push    offset byte_42A540 ; lpString
  4. .text:00408496                 push    66h             ; nIDDlgItem
  5. .text:00408498                 mov     edx, [ebp+hDlg]
  6. .text:0040849B                 push    edx             ; hDlg
  7. .text:0040849C                 call    ds:GetDlgItemTextA
  8. .text:004084A2                 push    1Fh             ; cchMax
  9. .text:004084A4                 push    offset ReturnedString ; lpString
  10. .text:004084A9                 push    67h             ; nIDDlgItem
  11. .text:004084AB                 mov     eax, [ebp+hDlg]
  12. .text:004084AE                 push    eax             ; hDlg
  13. .text:004084AF                 call    ds:GetDlgItemTextA
  14. .text:004084B5                 push    offset ReturnedString ; Str
  15. .text:004084BA                 push    offset byte_42A540 ; int
  16. ; Вызывать функцию проверки регистрации
  17. .text:004084BF                 call    sub_408840
  18. .text:004084C4                 add     esp, 8
  19. .text:004084C7                 test    eax, eax
  20. ; Если результат EAX=0, то регистрация неправильная
  21. .text:004084C9                 jz      short loc_40850A
  22. .text:004084CB                 push    offset byte_42A540
  23. .text:004084D0                 push    offset aThankYouForReg
  24. ; "Thank you for registration!\nRegistered "...
  25. .text:004084D5                 mov     ecx, lpString
  26. .text:004084DB                 push    ecx             ; Dest
  27. .text:004084DC                 call    _sprintf
  28. .text:004084E1                 add     esp, 0Ch
  29. .text:004084E4                 push    40h             ; uType
  30. .text:004084E6                 push    offset Caption  ; "MIDI Workplace v1.0"
  31. .text:004084EB                 mov     edx, lpString
  32. .text:004084F1                 push    edx             ; lpText
  33. .text:004084F2                 mov     eax, [ebp+hDlg]
  34. .text:004084F5                 push    eax             ; hWnd
  35. .text:004084F6                 call    ds:MessageBoxA
  36. .text:004084FC                 push    1               ; nResult
  37. .text:004084FE                 mov     ecx, [ebp+hDlg]
  38. .text:00408501                 push    ecx             ; hDlg
  39. .text:00408502                 call    ds:EndDialog
  40. .text:00408508                 jmp     short loc_408520
  41. .text:0040850A ; ---------------------------------------
  42. .text:0040850A loc_40850A:
  43. .text:0040850A                 push    30h             ; uType
  44. .text:0040850C                 push    offset aMidiWorkplac_0
  45. ; "MIDI Workplace v1.0"
  46. .text:00408511                 push    offset Text
  47. ; "Invalid RegCode !"
  48. .text:00408516                 mov     edx, [ebp+hDlg]
  49. .text:00408519                 push    edx             ; hWnd
  50. .text:0040851A                 call    ds:MessageBoxA
  51. .text:00408520
Все очень чисто и красиво. Из формы ввода программа получает имя и серийник, затем вызывает функцию проверки, по ее результатам выводится или сообщение о неправильной регистрации, или благодарочка за покупку. Руки тянутся вбить в начало функции проверки заветную парочку команд MOV EAX,1 и RET, но, забегая вперед, скажу, что делать этого пока не надо. Давайте поближе посмотрим на функцию проверки.
  1. .text:00408840 sub_408840      proc near
  2. .text:00408840 var_C           = dword ptr -0Ch
  3. .text:00408840 var_8           = dword ptr -8
  4. .text:00408840 var_4           = dword ptr -4
  5. .text:00408840 Str             = dword ptr  0Ch
  6. .text:00408840
  7. .text:00408840                 push    ebp
  8. .text:00408841                 mov     ebp, esp
  9. .text:00408843                 sub     esp, 0Ch
  10. ; Сразу установить результат проверки = "неправильная регистрация"
  11. .text:00408846                 mov     [ebp+var_4], 0
  12. .text:0040884D                 mov     eax, [ebp+Str]
  13. .text:00408850                 push    eax             ; Str
  14. ; Выяснить длину серийника
  15. .text:00408851                 call    _strlen
  16. .text:00408856                 add     esp, 4
  17. ; Длина равна 1C байт (28 в десятичной системе)?
  18. .text:00408859                 cmp     eax, 1Ch
  19. ; Да, переходим к следующим проверкам
  20. .text:0040885C                 jz      short loc_408866
  21. ; Записать в EAX результат проверки и вернуться
  22. .text:0040885E                 mov     eax, [ebp+var_4]
  23. .text:00408861                 jmp     loc_40891F
  24. .text:00408866 ; ---------------------------------------
  25. .text:00408866 loc_408866:
  26. .text:00408866                 push    20h             ; Size
  27. .text:00408868                 push    0               ; Val
  28. .text:0040886A                 push    offset unk_42A3F0 ; Dst
  29. .text:0040886F                 call    _memset
  30. .text:00408874                 add     esp, 0Ch
  31. .text:00408877                 push    19h             ; Size
  32. .text:00408879                 mov     ecx, [ebp+Str]
  33. .text:0040887C                 push    ecx             ; Src
  34. .text:0040887D                 push    offset unk_42A3F0 ; Dst
  35. .text:00408882                 call    _memcpy
  36. .text:00408887                 add     esp, 0Ch
  37. .text:0040888A                 push    offset unk_42A430
  38. .text:0040888F                 push    20h
  39. .text:00408891                 push    offset unk_42A3F0
  40. .text:00408896                 call    sub_40CC60
  41. .text:0040889B                 push    40h             ; Size
  42. .text:0040889D                 push    offset unk_42A430 ; Src
  43. .text:004088A2                 push    offset dword_42A3B0 ; Dst
  44. .text:004088A7                 call    _memcpy
  45. .text:004088AC                 add     esp, 0Ch
  46. .text:004088AF                 mov     [ebp+var_C], 0
  47. .text:004088B6                 mov     [ebp+var_8], 0
  48. .text:004088BD                 jmp     short loc_4088C8
  49. .text:004088BF ; ---------------------------------------
  50. .text:004088BF loc_4088BF:
  51. .text:004088BF                 mov     edx, [ebp+var_8]
  52. .text:004088C2                 add     edx, 1
  53. .text:004088C5                 mov     [ebp+var_8], edx
  54. .text:004088C8 loc_4088C8:
  55. .text:004088C8                 cmp     [ebp+var_8], 10h
  56. .text:004088CC                 jge     short loc_4088E0
  57. .text:004088CE                 mov     eax, [ebp+var_8]
  58. .text:004088D1                 mov     ecx, [ebp+var_C]
  59. .text:004088D4                 add     ecx, dword_42A3B0[eax*4]
  60. .text:004088DB                 mov     [ebp+var_C], ecx
  61. .text:004088DE                 jmp     short loc_4088BF
  62. .text:004088E0 ; ---------------------------------------
  63. .text:004088E0 loc_4088E0:
  64. .text:004088E0                 mov     [ebp+var_8], 0
  65. .text:004088E7                 jmp     short loc_4088F2
  66. .text:004088E9 ; ---------------------------------------
  67. .text:004088E9 loc_4088E9:
  68. .text:004088E9                 mov     edx, [ebp+var_8]
  69. .text:004088EC                 add     edx, 1
  70. .text:004088EF                 mov     [ebp+var_8], edx
  71. .text:004088F2 loc_4088F2:
  72. .text:004088F2                 cmp     [ebp+var_8], 400h
  73. .text:004088F9                 jge     short loc_408913
  74. .text:004088FB                 mov     eax, [ebp+var_8]
  75. .text:004088FE                 mov     ecx, dword_424088[eax*4]
  76. .text:00408905                 cmp     ecx, [ebp+var_C]
  77. .text:00408908                 jnz     short loc_408911
  78. ; Установить результат проверки = "регистрация правильная"
  79. .text:0040890A                 mov     [ebp+var_4], 1
  80. .text:00408911 loc_408911:
  81. .text:00408911                 jmp     short loc_4088E9
  82. .text:00408913 ; ---------------------------------------
  83. .text:00408913 loc_408913:
  84. ; Записать в EDX результат проверки
  85. .text:00408913                 mov     edx, [ebp+var_4]
  86. ; Записать результат из EDX в переменную-флаг
  87. .text:00408916                 mov     dword_42A474, edx
  88. ; Записать результат проверки в EAX
  89. .text:0040891C                 mov     eax, [ebp+var_4]
  90. .text:0040891F loc_40891F:
  91. .text:0040891F                 mov     esp, ebp
  92. .text:00408921                 pop     ebp
  93. .text:00408922                 retn
  94. .text:00408922 sub_408840      endp
Код я немного прокомментировал, продублирую словами. Обратите внимание, что сперва проверяется длина серийника, если она неправильная, то сразу выполняется возврат и больше никаких проверок не выполняется. А в конце функции проверки результат не только заносится в возвратный регистр EAX, но и записывается в переменную dword_42A474. Если посмотреть, где она используется, то обнаружится несколько мест, отвечающих именно за 30-секундные ограничения и прочие триальные проявления. Таким образом сама функция проверки отвечает только за "косметику", а за функционал отвечает переменная. Значит патчить начало функции надо будет тремя командами: MOV EAX,1; MOV dword_42A474, EAX и RET. Конечно, есть и другие варианты, например, заменить в инициализации по адресу 00408846 нолик на единичку, а потом поменять команду перехода по адресу 00408861 с jmp loc_40891F на jmp loc_408913. Теперь при любом раскладе и функция проверки вернет нужное значение, и переменная будет содержать нужную единичку.

Введенные регистрационные данные, даже неправильные, записываются в файл конфигурации settings.ini, поэтому сперва регистрируем какой-нибудь произвольной информацией, а только потом патчим. Вот что получается.

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

Ограничения по функционалу сняты, триальные окна при старте и кнопки регистрации в интерфейсе исчезли, в окне "О программе" отображается введенное ранее регистрационное имя, цель достигнута.

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

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

Комментарии

Отзывы посетителей сайта о статье
Комментариeв нет

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

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

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