Blog. Just Blog

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

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

Программа ControlMyNikon предназначена для дистанционного управления зеркальными камерами Nikon через USB-кабель, а также по беспроводному подключению. Доступны все настройки параметров съемки, режим LiveView, коррекция изображений и автоматическая загрузка готовых снимков на компьютер. Очень неплохая замена штатному софту от Nikon, хоть и со своими заморочками. Некоторые косяки в функционале можно потерпеть, но необходимость выкладывать за программу деньги я терпеть не могу.

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

Окно регистрации программы
Окно регистрации программы

На ввод левых регистрационных данных программа ожидаемо реагирует сообщением "Invalid Product Key". Попробуем найти эту строку в файле. Она находится в виде юникодной строки.

Строка сообщения найдена
Строка сообщения найдена

Но рядом еще есть строка сообщения об успешной регистрации, лучше посмотрим в дизассемблере место, где она используется.
  1. .text:00B44605                 test    bl, bl
  2. ; Условный переход, который обходит ветку успешной регистрации
  3. .text:00B44607                 jz      loc_B446F2
  4. .text:00B4460D                 lea     edx, [ebp+var_30]
  5. .text:00B44610                 mov     eax, [esi+3B4h] ; this
  6. .text:00B44616                 call    sub_520EBC
  7. .text:00B4461B                 mov     eax, [ebp+var_30]
  8. .text:00B4461E                 lea     edx, [ebp+var_2C]
  9. .text:00B44621                 call    sub_4213C8
  10. .text:00B44626                 mov     edx, [ebp+var_2C]
  11. .text:00B44629                 mov     eax, off_B96710
  12. .text:00B4462E                 mov     eax, [eax]
  13. .text:00B44630                 add     eax, 22h
  14. .text:00B44633                 call    sub_407D80
  15. .text:00B44638                 mov     eax, off_B96710
  16. .text:00B4463D                 mov     eax, [eax]
  17. .text:00B4463F                 call    sub_B42020
  18. .text:00B44644                 push    3
  19. .text:00B44646                 lea     eax, [ebp+var_4]
  20. .text:00B44649                 mov     ecx, 1
  21. .text:00B4464E                 mov     edx, ds:off_40C41C
  22. .text:00B44654                 call    @System@@DynArraySetLength$qqrv
  23. .text:00B44659                 add     esp, 4
  24. .text:00B4465C                 lea     ecx, [ebp+var_34]
  25. .text:00B4465F                 mov     eax, off_B972B0
  26. .text:00B44664                 mov     eax, [eax]
  27. .text:00B44666                 mov     edx, offset off_B44848
  28. .text:00B4466B                 call    sub_A89A70
  29. .text:00B44670                 mov     edx, [ebp+var_34]
  30. .text:00B44673                 mov     eax, [ebp+var_4]
  31. .text:00B44676                 call    sub_407D80
  32. .text:00B4467B                 lea     ecx, [ebp+var_38]
  33. .text:00B4467E                 mov     eax, off_B972B0
  34. .text:00B44683                 mov     eax, [eax]
  35. .text:00B44685                 mov     edx, offset aRoductKeyIsVa
  36. ; "Product Key is Valid"
  37. .text:00B4468A                 call    sub_A89A70
  38. .text:00B4468F                 mov     edx, [ebp+var_38]
  39. .text:00B44692                 mov     eax, [ebp+var_4]
  40. .text:00B44695                 add     eax, 4
  41. .text:00B44698                 call    sub_407D80
  42. .text:00B4469D                 lea     ecx, [ebp+var_3C]
  43. .text:00B446A0                 mov     eax, off_B972B0
  44. .text:00B446A5                 mov     eax, [eax]
  45. .text:00B446A7                 mov     edx, offset off_B448A4
  46. .text:00B446AC                 call    sub_A89A70
  47. .text:00B446B1                 mov     edx, [ebp+var_3C]
  48. .text:00B446B4                 mov     eax, [ebp+var_4]
  49. .text:00B446B7                 add     eax, 8
  50. .text:00B446BA                 call    sub_407D80
  51. .text:00B446BF                 mov     eax, [esi+48h]
  52. .text:00B446C2                 push    eax
  53. .text:00B446C3                 mov     eax, [esi+4Ch]
  54. .text:00B446C6                 push    eax
  55. .text:00B446C7                 push    0
  56. .text:00B446C9                 mov     eax, esi
  57. .text:00B446CB                 call    sub_4F9E3C
  58. .text:00B446D0                 push    eax
  59. .text:00B446D1                 mov     eax, esi
  60. .text:00B446D3                 call    sub_4F9E1C
  61. .text:00B446D8                 mov     edx, eax
  62. .text:00B446DA                 mov     eax, [ebp+var_4]
  63. .text:00B446DD                 pop     ecx
  64. .text:00B446DE                 call    sub_A0E4A0
  65. ; По всей видимости здесь заносится в переменную флаг зарегистрированности
  66. .text:00B446E3                 mov     dword ptr [esi+2B8h], 1
  67. .text:00B446ED                 jmp     loc_B447B3
Если заNOPить условный переход по адресу 00B44607, то алгоритм всегда будет переходить на ветку успешной регистрации. Кроме того, в самом конце этой ветки находится команда mov dword ptr [esi+2B8h], 1. Скорее всего это установка флага зарегистрированности. Сохраним изменения, перезапустим программу и снова попробуем зарегистрировать ее произвольным серийником.

Серийный номер принят
Серийный номер принят

Программа приняла серийник, поблагодарила за регистрацию и полноценно работает. Но это только до перезапуска. В следующий раз ее снова придется регистрировать. Кстати, такой вариант тоже имеет место быть, например, если ControlMyNikon используется в фотостудии. Любому проверяющему показывается триальная версия программы с окном регистрации и истекшим пробным периодом, а для личного использования ее можно в любой момент превратить в полноценную.

Но для домашнего использования лучше сделать так, чтобы окно ввода серийника больше не появлялось. Для этого надо найти место, где при запуске выполняются аналогичные проверки корректности регистрационных данных. Обычно я делаю это следующим способом: по очереди перебираю все команды call, которые встречаются в функции валидации и которые не относятся к вызовам системных API. Если функция вызывается еще из одного-двух мест, значит с большой вероятностью это вызовы из таких же проверок корректности регистрации.

Перекрестные ссылки на функцию
Перекрестные ссылки на функцию

Первая же команда call дает нам нужный результат. Она вызывается из функции с говорящим названием "ValidateClick", а кроме того, из другой функции с не менее говорящим названием "StartupTimer". И действительно, окно регистрации появляется уже после открытия главного окна, то есть как раз по таймеру. Переходим туда. Последовательность операций если не такая же, то очень похожая, но заканчивается она следующим кодом:
  1. .text:00B18EA7                 test    bl, bl
  2. .text:00B18EA9                 jnz     short loc_B18EBD
  3. .text:00B18EAB                 call    sub_B43E7C
  4. .text:00B18EB0                 test    al, al
Здесь такая же проверка регистра bl, но условие перехода обратное. Значит менять его надо не на NOP, а на безусловный переход. Патчим, сохраняем изменения, запускаем. Если вы ранее вводили левый серийник, то программа просто запустится и будет работать в полном режиме, без всяких ограничений. Если не регистрировали, то потребуется разовый ввод произвольного серийника, после чего также никаких напоминаний о регистрации не появится. Цель достигнута!

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

Иногда в заголовке программы и в окне "О программе" вместо Nikon внезапно появляется название компании-конкурента. Почему? Ответа на этот вопрос у меня нет, какая-то неведомая хрень. При старте - Nikon, через пару секунд - название другой компании. Но главное, что все работает как надо с зеркалками Nikon, я лично проверил работоспособность программы со своим Nikon D800. Наверняка программа от этой конторы для камер других производителей нейтрализуется таким же образом, но меня это уже не интересует.

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

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

Комментарии

Отзывы посетителей сайта о статье
Grey (28.07.2016 в 19:59):
Оба-на, пропустил статейку. Пультом неудобно мультики делать. Спасибо, время появится, попробую поскрипеть мозгами, повторить это.
ManHunter (17.03.2016 в 09:04):
Это как раз и есть скопипастенная проверка, поэтому два места для патча.
Саша (17.03.2016 в 00:27):
ЦитатаИногда в заголовке программы и в окне "О программе" вместо Nikon внезапно появляется название компании-конкурента

Возможно они писали ещё софт для других кампаний и забыли поправить их название во всех исходниках.

ЦитатаЗначит менять его надо не на NOP, а на безусловный переход.

Стесняюсь спросить, а не логичнее ли пропатчить саму функцию проверки, чтобы она всегда выдавала "зарегистрировано"? И возни меньше, и программа работать быстрее будет. Сам я админ, совсем не программер.

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

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

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