Blog. Just Blog

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

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

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

Забираем с сайта дистрибутив последней версии, устанавливаем. В процессе установки загружаются дополнительные компоненты, без них ничего работать не будет. После установки смотрим, что и как. Сразу бросается в глаза надпись "Незарегистрировано" в заголовке главного окна. С этого и начнем. Хотя начать надо, конечно, с дизассемблера, но вы это и так хорошо знаете.

Строка в языковом файле
Строка в языковом файле

Программа мультиязычная, соответствующий языковой файл находится в папке Languages. Код строки 10776 или 2A18h, если смотреть в шестнадцатеричной системе счисления. Код, в котором используется это значение, выглядит следующим образом:
  1. ; Загрузить в AL флаг регистрации
  2. .text:004E6444                 mov     al, byte_6BEEEC
  3. .text:004E6449 loc_4E6449:
  4. .text:004E6449                 test    al, al
  5. ; Если он не нулевой, то перепрыгнуть загрузку строки
  6. .text:004E644B                 jnz     loc_4E657E
  7. ; Загрузить строку "Незарегистрированная"
  8. .text:004E6451                 mov     ecx, 2A18h
  9. .text:004E6456                 call    sub_581980
  10. .text:004E645B                 mov     edx, eax
Тут проверяется флаг регистрации, по результатам проверки выполняется условный переход или же загружается строка в заголовок окна. Давайте посмотрим, где инициализируется этот флаг. Для этого откроем список перекрестных ссылок.

Перекрестные ссылки на флаг
Перекрестные ссылки на флаг

Фигвам. Только проверки или же загрузка значения флага. Никаких прямых инициализиаций. Ничего страшного, там, где не помогает дизассемблер, поможет отладчик. Загружаем программу в отладчик и ставим хардварную точку останова на запись в байт памяти по адресу 006BEEEC.

Ставим точку останова
Ставим точку останова

Запускаем программу на выполнение. Запись в память сработает только в двух местах.
  1. ; Первая инициализация флага регистрации
  2. .text:0058E9D9                 mov     byte ptr [ecx+4], 0
  3. .text:0058E9DD                 mov     dword ptr [ecx+8], 0
  4. .text:0058E9E4                 mov     dword ptr [eax+10h], 0
  5. .text:0058E9EB                 cmp     dword ptr [eax+14h], 8
  1. .text:0058EF7D                 mov     eax, dword_6BEDD0
  2. ; Вторая инициализация флага регистрации
  3. .text:0058EF82                 mov     [edi+4], bl
  4. .text:0058EF85                 test    eax, eax
  5. .text:0058EF87                 jz      short loc_58EF9C
  6. .text:0058EF89                 push    eax
  7. .text:0058EF8A                 push    59E68620h
  8. .text:0058EF8F                 call    sub_58E5F0
  9. .text:0058EF94                 add     esp, 4
Приступаем к патчам. В первом случае команду mov byte ptr [ecx+4], 0 надо заменить на mov byte ptr [ecx+4], 1, тогда флаг регистрации будет изначально установлен в правильное значение. Во втором фрагменте надо забить NOP'ами команду mov [edi+4], bl, чтобы не допустить сброс флага регистрации. Сохраняем изменения, запускаем. Триальных надписей нет, в окне "О программе" тоже информация о зарегистрированности.

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

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

Строка в файле
Строка в файле

Давайте посмотрим, где и как они вызываются.
  1. .text:004611E7                 cmp     byte ptr [esi+50h], 1
  2. .text:004611EB                 jnz     short loc_461207
  3. .text:004611ED                 cmp     byte ptr [ebx+24h], 1
  4. .text:004611F1                 jnz     short loc_461207
  5. .text:004611F3                 push    5
  6. .text:004611F5                 push    offset aPro_0   ; "#PRO#"
  7. .text:004611FA                 lea     ecx, [ebp+lpNewItem]
  8. .text:004611FD                 mov     edi, 401h
  9. .text:00461202                 call    loc_407820
Проверяются два флага, если хоть один из них подходит под условие, то выполняется условный переход и "PRO" куда-то к пунктам меню не добавляется.
  1. .text:00460C67                 jz      loc_461D2B
  2. ; Вызвать функцию проверки
  3. .text:00460C6D                 call    sub_5603F0
  4. ; EAX=0 - не зарегистрирована
  5. .text:00460C72                 test    eax, eax
  6. .text:00460C74                 jz      short loc_460C7F
  7. ; EAX=2 - не зарегистрирована
  8. .text:00460C76                 cmp     eax, 2
  9. .text:00460C79                 jz      short loc_460C7F
  10. .text:00460C7B                 xor     al, al
  11. .text:00460C7D                 jmp     short loc_460C81
  12. .text:00460C7F ; ---------------------------------------
  13. .text:00460C7F loc_460C7F:
  14. ; Флаг "не зарегистрирована"
  15. .text:00460C7F                 mov     al, 1
  16. .text:00460C81 loc_460C81:
  17. ; Сохранить значение флага
  18. .text:00460C81                 mov     [ebx+24h], al
  19. ; Вызвать функцию проверки
  20. .text:00460C84                 call    sub_5603F0
  21. ; EAX=3 - не зарегистрирована
  22. .text:00460C89                 cmp     eax, 3
  23. .text:00460C8C                 setz    al
  24. ; Какой-то дополнительный флаг
  25. .text:00460C8F                 mov     [ebx+25h], al
  26. .text:00460C92                 jnz     short loc_460CA4
  27. .text:00460C94                 call    sub_5603F0
  28. ; EAX=5 - не зарегистрирована
  29. .text:00460C99                 cmp     eax, 5
  30. .text:00460C9C                 jnz     short loc_460CA4
  31. .text:00460C9E                 mov     word ptr [ebx+24h], 1
Тут несколько раз вызывается функция проверки по адресу 005603F0 и по ее результатам выставляются значения двух флагов. По всей видимости они по отдельности отвечают за активацию каких-то дополнительных опций программы. Как видно по логике программы, допустимым значением возврата из функции проверки является EAX=1. Посмотрим эту функцию.
  1. .text:005603F0 sub_5603F0      proc near
  2. .text:005603F0                 push    esi
  3. .text:005603F1                 push    edi
  4. .text:005603F2                 mov     edi, ds:OpenMutexW
  5. .text:005603F8                 push    offset aLocalB7df3bc_0
  6. ; "Local\\{B7DF3BCE-B146-4b00-8783-12BD0DFD"...
  7. .text:005603FD                 push    0               ; bInheritHandle
  8. .text:005603FF                 push    100000h         ; dwDesiredAccess
  9. .text:00560404                 call    edi ; OpenMutexW
  10. .text:00560406                 mov     esi, eax
  11. .text:00560408                 test    esi, esi
  12. .text:0056040A                 jz      short loc_560422
  13. .text:0056040C                 push    esi             ; hMutex
  14. .text:0056040D                 call    ds:ReleaseMutex
  15. .text:00560413                 push    esi             ; hObject
  16. .text:00560414                 call    ds:CloseHandle
  17. .text:0056041A                 pop     edi
  18. .text:0056041B                 mov     eax, 2
  19. .text:00560420                 pop     esi
  20. .text:00560421                 retn
  21. .text:00560422 loc_560422:
  22. .text:00560422                 push    offset aLocalB7df3bc_1
  23. ; "Local\\{B7DF3BCE-B146-4b00-8783-12BD0DFD"...
  24. .text:00560427                 push    0               ; bInheritHandle
  25. .text:00560429                 push    100000h         ; dwDesiredAccess
  26. .text:0056042E                 call    edi ; OpenMutexW
  27. .text:00560430                 mov     esi, eax
  28. .text:00560432                 test    esi, esi
  29. .text:00560434                 jz      short loc_56044C
  30. .text:00560436                 push    esi             ; hMutex
  31. .text:00560437                 call    ds:ReleaseMutex
  32. .text:0056043D                 push    esi             ; hObject
  33. .text:0056043E                 call    ds:CloseHandle
  34. .text:00560444                 pop     edi
  35. .text:00560445                 mov     eax, 1
  36. .text:0056044A                 pop     esi
  37. .text:0056044B                 retn
  38. .text:0056044C loc_56044C:
  39. .text:0056044C                 push    offset aLocalB7df3bc_2
  40. ; "Local\\{B7DF3BCE-B146-4b00-8783-12BD0DFD"...
  41. .text:00560451                 push    0               ; bInheritHandle
  42. .text:00560453                 push    100000h         ; dwDesiredAccess
  43. .text:00560458                 call    edi ; OpenMutexW
  44. .text:0056045A                 mov     esi, eax
  45. .text:0056045C                 test    esi, esi
  46. .text:0056045E                 jz      short loc_560476
  47. .text:00560460                 push    esi             ; hMutex
  48. .text:00560461                 call    ds:ReleaseMutex
  49. .text:00560467                 push    esi             ; hObject
  50. .text:00560468                 call    ds:CloseHandle
  51. .text:0056046E                 pop     edi
  52. .text:0056046F                 mov     eax, 3
  53. .text:00560474                 pop     esi
  54. .text:00560475                 retn
  55. .text:00560476 loc_560476:
  56. .text:00560476                 pop     edi
  57. .text:00560477                 xor     eax, eax
  58. .text:00560479                 pop     esi
  59. .text:0056047A                 retn
  60. .text:0056047A sub_5603F0      endp
Последовательно проверяется наличие одного из трех мьютексов, по результатам возвращается то или оное значение. Впечатываем в начало функции по адресу 005603F0 пару команд MOV EAX,1 и RET, сохраняем изменения, проверяем. Вот теперь все пункты меню активны, все опции программы доступны.

Поделиться ссылкой ВКонтакте
Просмотров: 362 | Комментариев: 1

Комментарии

Отзывы посетителей сайта о статье
Fury (21.04.2024 в 12:18):
Hello Master, there must be something wrong here. I tried both methods but I did not get any results.

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

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

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