Blog. Just Blog

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

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

WinTools.net - одна из немногих программ для автоматической очистки и оптимизации системы, которым я доверяю. За долгие годы она зарекомендовала себя как надежный инструмент, ни разу не подвела, не удалила лишнего, или еще каким-то образом подвела. Можно долго рассуждать о целесообразности использования таких программ, но речь сейчас не об этом. Как и остальные программы от Godlike Developers, WinTools.net является шароварой, по истечению триального срока некоторые функции перестают работать.

Ранее я уже публиковал исследование защиты программы RAM Saver, но сейчас я решил отойти от своего принципа не потрошить более одной программы одного разработчика. Главная цель статьи - inline-патч исполняемого файла, накрытого ASProtect. Но статью о RAM Saver все-таки прочитайте, некоторые моменты очень похожи.

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

Наг-окно
Наг-окно

Как и на остальных продуктах Godlike Developers, основной исполняемый файл тут тоже накрыт навесным протектором. Перед тем, как его инлайнить, надо разобраться в самой защите. Для этого снимаем протектор или в OllyDbg с помощью скриптов, или каким-нибудь подходящим автоматическим инструментом. Убеждаемся в работоспособности распакованного файла, отправляем его в дизассемблер.

Диалоговое окно в ресурсах
Диалоговое окно в ресурсах

Теперь надо выяснить, как называется окно регистрации. Открываем распакованный файл в редакторе ресурсов. Искомое диалоговое окно имеет название NAGSCREEN. По перекрестным ссылкам в дизассемблере выходим на какой-нибудь код, где это диалоговое окно используется. Например, вот такой:
  1. ; Проверить DWORD
  2. seg000:00409CC5                 mov     eax, ds:dword_4B2A30
  3. seg000:00409CCA                 cmp     eax, 1
  4. ; Не открывать наг-окно
  5. seg000:00409CCD                 jnz     short loc_409CF2
  6. seg000:00409CCF loc_409CCF:
  7. ; Открыть наг-окно
  8. seg000:00409CCF                 push    0               ; dwInitParam
  9. seg000:00409CD1                 push    offset sub_46253D ; lpDialogFunc
  10. seg000:00409CD6                 push    ds:hWndParent   ; hWndParent
  11. seg000:00409CDC                 push    offset aNagscreen ; lpTemplateName
Надо найти место, где инициализируется DWORD, расположенный по адресу 4B2A30. Таких мест несколько, но в одних случаях значение ячейки памяти обнуляется, а в других инициализируется ненулевым значением. А именно вот этот участок кода:
  1. seg000:00462397                 lea     edx, [ecx+6Fh]
  2. seg000:0046239A                 cmp     esi, eax
  3. seg000:0046239C                 jnz     short loc_4623CE
  4. seg000:0046239E                 mov     ds:dword_4B2A34, ecx
  5. seg000:004623A4                 mov     ds:dword_4B2A38, edx
  6. seg000:004623AA                 mov     ds:dword_4B2A3C, edi
  7. seg000:004623B0                 mov     ds:dword_4B2A40, 0EAh
  8. seg000:004623BA                 mov     ds:dword_4B2A44, 34Fh
  9. seg000:004623C4                 mov     ds:dword_4B2A30, 3B3h
  10. seg000:004623CE loc_4623CE:
  11. seg000:004623CE                 xor     eax, eax
  12. seg000:004623D0                 cmp     ebx, [ebp+var_2AC]
  13. seg000:004623D6                 jnz     loc_462291
  14. seg000:004623DC                 mov     ds:dword_4B2A34, ecx
  15. seg000:004623E2                 inc     eax
  16. seg000:004623E3                 mov     ds:dword_4B2A38, edx
  17. seg000:004623E9                 mov     ds:dword_4B2A3C, edi
  18. seg000:004623EF                 mov     ds:dword_4B2A40, 0EAh
  19. seg000:004623F9                 mov     ds:dword_4B2A44, 34Fh
  20. seg000:00462403                 mov     ds:dword_4B2A30, 3B3h
  21. seg000:0046240D                 jmp     loc_462291
Подобный код мы уже встречали в программе RAM Saver, это и есть инициализация правильными значениями целой пачки контрольных переменных. На них основывается вся остальная защита. Для того, чтобы программа почувствовала себя зарегистрированной, надо модифицировать функцию проверки таким образом, чтобы управление получил код правильной инициализации. Алгоритм проверки практически линейный, надо лишь направить его в нужную сторону. Делается это путем замены нескольких условных переходов. Часть кода я пропущу, иначе получится очень длинный листинг.
  1. seg000:00462206                 push    ebp
  2. seg000:00462207                 mov     ebp, esp
  3. seg000:00462209                 sub     esp, 2ACh
  4. seg000:0046220F                 mov     eax, ds:dword_4B2004
  5. seg000:00462214                 xor     eax, ebp
  6. seg000:00462216                 mov     [ebp+var_4], eax
  7. seg000:00462219                 push    ebx             ; psz1
  8. seg000:0046221A                 push    esi
  9. seg000:0046221B                 mov     esi, ds:StrCpyW
  10. seg000:00462221                 push    edi
  11. seg000:00462222                 push    offset off_4A9CBC ; psz2
  12. seg000:00462227                 mov     edi, offset word_628878
  13. seg000:0046222C                 push    edi             ; psz1
  14. seg000:0046222D                 call    esi ; StrCpyW
  15. seg000:0046222F                 push    offset off_4A9CC8 ; psz2
  16. seg000:00462234                 mov     ebx, offset word_628830
  17. seg000:00462239                 push    ebx             ; psz1
  18. ...
  19. ...
  20. ...
  21. seg000:0046226C                 call    sub_462418
  22. seg000:00462271                 test    eax, eax
  23. ; Условный переход заменяется на безусловный
  24. seg000:00462273                 jz      short loc_4622A2
  25. seg000:00462275                 push    offset FileName ; lpFileName
  26. seg000:0046227A                 push    offset a37474384 ; "37474384"
  27. seg000:0046227F                 push    offset off_4A9D5C ; lpKeyName
  28. seg000:00462284                 push    offset off_49E440 ; lpAppName
  29. seg000:00462289                 call    ds:WritePrivateProfileStringW
  30. seg000:0046228F loc_46228F:
  31. seg000:0046228F                 xor     eax, eax
  32. seg000:00462291 loc_462291:
  33. seg000:00462291                 mov     ecx, [ebp+var_4]
  34. seg000:00462294                 pop     edi
  35. seg000:00462295                 pop     esi
  36. seg000:00462296                 xor     ecx, ebp
  37. seg000:00462298                 pop     ebx
  38. seg000:00462299                 call    sub_47BB8C
  39. seg000:0046229E                 mov     esp, ebp
  40. seg000:004622A0                 pop     ebp
  41. seg000:004622A1                 retn
  42. seg000:004622A2 ; --------------------------------
  43. seg000:004622A2 loc_4622A2:
  44. seg000:004622A2                 push    9Ah
  45. seg000:004622A7                 lea     eax, [ebp+ReturnedString]
  46. seg000:004622AD                 push    0
  47. seg000:004622AF                 push    eax
  48. seg000:004622B0                 call    sub_47CB20
  49. seg000:004622B5                 add     esp, 0Ch
  50. seg000:004622B8                 lea     eax, [ebp+ReturnedString]
  51. seg000:004622BE                 push    offset FileName ; lpFileName
  52. seg000:004622C3                 push    4Dh             ; nSize
  53. seg000:004622C5                 push    eax             ; lpReturnedString
  54. seg000:004622C6                 push    offset pszFaceName ; lpDefault
  55. seg000:004622CB                 push    offset off_49C0A0 ; lpKeyName
  56. seg000:004622D0                 push    offset off_49C080 ; lpAppName
  57. seg000:004622D5                 call    ds:GetPrivateProfileStringW
  58. seg000:004622DB                 test    eax, eax
  59. ; Условный переход NOP'ится
  60. seg000:004622DD                 jz      short loc_46228F
  61. seg000:004622DF                 lea     ecx, [ebp+ReturnedString]
  62. seg000:004622E5                 call    sub_46252A
  63. seg000:004622EA                 mov     edi, ds:lstrlenW
  64. seg000:004622F0                 lea     eax, [ebp+ReturnedString]
  65. seg000:004622F6                 push    eax             ; lpString
  66. seg000:004622F7                 call    edi ; lstrlenW
  67. seg000:004622F9                 cmp     eax, 14h
  68. ; Условный переход NOP'ится
  69. seg000:004622FC                 jl      short loc_46228F
  70. seg000:004622FE                 push    208h
  71. seg000:00462303                 lea     eax, [ebp+psz1]
  72. seg000:00462309                 push    0
  73. seg000:0046230B                 push    eax
  74. ...
  75. ...
  76. ...
  77. seg000:0046233B                 mov     ecx, esi        ; lpString
  78. seg000:0046233D                 call    sub_457AF1
  79. seg000:00462342                 mov     ebx, eax
  80. seg000:00462344                 cmp     edi, 208h
  81. ; Условный переход NOP'ится
  82. seg000:0046234A                 jnb     loc_462412
  83. seg000:00462350                 xor     eax, eax
  84. seg000:00462352                 mov     [ebp+edi+psz1], ax
  85. seg000:0046235A                 lea     eax, [ebp+psz1]
  86. ...
  87. ...
  88. ...
  89. seg000:0046238B                 mov     edi, 2E9h
  90. seg000:00462390                 pop     ecx
  91. seg000:00462391                 pop     ecx
  92. seg000:00462392                 mov     ecx, 0E8h
  93. seg000:00462397                 lea     edx, [ecx+6Fh]
  94. seg000:0046239A                 cmp     esi, eax
  95. seg000:0046239C                 jnz     short loc_4623CE
  96. seg000:0046239E                 mov     ds:dword_4B2A34, ecx
  97. seg000:004623A4                 mov     ds:dword_4B2A38, edx
  98. seg000:004623AA                 mov     ds:dword_4B2A3C, edi
  99. seg000:004623B0                 mov     ds:dword_4B2A40, 0EAh
  100. seg000:004623BA                 mov     ds:dword_4B2A44, 34Fh
  101. seg000:004623C4                 mov     ds:dword_4B2A30, 3B3h
  102. seg000:004623CE loc_4623CE:
  103. seg000:004623CE                 xor     eax, eax
  104. seg000:004623D0                 cmp     ebx, [ebp+var_2AC]
  105. ; Условный переход NOP'ится
  106. seg000:004623D6                 jnz     loc_462291
  107. seg000:004623DC                 mov     ds:dword_4B2A34, ecx
  108. seg000:004623E2                 inc     eax
  109. seg000:004623E3                 mov     ds:dword_4B2A38, edx
  110. seg000:004623E9                 mov     ds:dword_4B2A3C, edi
  111. seg000:004623EF                 mov     ds:dword_4B2A40, 0EAh
  112. seg000:004623F9                 mov     ds:dword_4B2A44, 34Fh
  113. seg000:00462403                 mov     ds:dword_4B2A30, 3B3h
  114. seg000:0046240D                 jmp     loc_462291
Сохраняем изменения, запускаем программу. Окно регистрации при запуске пропало, все функции работают без ограничений, пункт меню регистрации стал неактивным. Отлично, основная цель достигнута.

Теперь нам известны все адреса для патча, можно сделать inline-патч прямо поверх протектора. Для этого возьмем ASProtect SKE Inline Patcher. Принцип его работы следующий: к защищенному файлу дописывается код, который ожидает, когда отработает протектор и защищенный файл будет распакован в памяти. После этого управление передается на специальный участок кода, который и вносит нужные нам изменения. Таким образом снимать протектор вовсе не обязательно. Способ inline-патчинга применяется в тех случаях, когда не получается корректно отодрать протектор от файла.

DWORD в распакованном файле
DWORD в распакованном файле

Возвращаемся к патчеру. Надо выбрать метод патча. Сложно сказать, какой метод сработает, это выясняется только опытным путем. В нашем случае надо выбрать "Method 2". Для того, чтобы inline-код мог перехватить момент распаковки программы, предусмотрены два следующих поля "RVA" и "Bytes". Это адрес в памяти распакованного файла и значение, которое там должно быть, когда файл распакован. По опыту лучше всего искать последовательность байт "FF FF FF FF", расположенную ближе всего к началу секции кода. Можете использовать любую другую последовательность на ваш выбор, но только кроме нулевых байт.

Патчим файл
Патчим файл

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

Записываем переход на inline-патч
Записываем переход на inline-патч

Открываем пропатченный файл в вашем любимом HEX-редакторе. Надо перейти в конец файла, куда был записан код inline-патча и найти последовательность NOP'ов. Сюда надо вписывать код, который вносит изменения в память. Для небольших патчей в пару байт этого места достаточно, но у нас несколько мест для патчинга, поэтому воспользуемся кучей нулевых байт после inline-кода. А в участок NOP'ов запишем команду CALL на начало нулевых байт.

Записываем inline-патч
Записываем inline-патч

В пустое пространство помещаем команды изменения условных переходов. Для экономии места будем не целиком NOP'ить переходы, а только обнулять адреса их прыжков, перенаправляя на следующую за ними команду. В конце добавляем команду RET, чтобы вернуть управление основному inline-коду.

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

Сохраняем изменения, запускаем. Если все сделано правильно, то программа, пропатченная inline-способом будет вести себя точно так же, как и пропатченная программа со снятым протектором. То есть никаких триальных ограничений не будет. Цель достигнута. Теперь вы не только получили хороший оптимизатор системы, но и научились работать с инструментом для inline-патча ASProtect.

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

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

Комментарии

Отзывы посетителей сайта о статье
ManHunter (22.06.2016 в 11:14):
Отучиванию от чего? Все лицензии и соединения проверяются на их сервере, никаких взломов быть не может в принципе. Могу написать, как убрать окна спонсируемого сеанса, а больше там ничего не сделать.
Compiller (22.06.2016 в 09:41):
А не могли бы вы туториал по отучиванию TeamViewer сделать?
Vladimir (21.06.2016 в 09:41):
Рег-органайзером пользуюсь достаточно давно, работает ровно, без нареканий. Только я все ключи, что он предлагает, просматриваю, а то мало ли.
ManHunter (21.06.2016 в 07:21):
А у меня как раз печальный опыт с этим Органайзером :)
Жека (21.06.2016 в 01:41):
user, рекомендую эту в качестве "подопытного"  Reg Organizer - с этой точно у меня никогда не было проблем, прога тоже защищена  ASProtect... но это не главное, она действительно нечего лишнего не трогает, как говорится - кряк будет в пользу))
user (20.06.2016 в 19:52):
Ну всё понятно, программа подопытная,
но никогда не использовал такие вот программы для "чистки реестра", считая их небезопасными, не без основания - сейчас, пока возился, "почистил реестр" - и сразу перестали запускаться две проинсталлированные софтины, и что самое прикольное, пропал интернет - пакеты какие-то короткие мотались непрерывно, в "свойствах подключения" значилось "Подключено", но реально ничего раскрыть не мог. Всё восстановилось тут же после восстановления реестра из бэкапа - вот это, пожалуй, и есть самый нормальный способ "чистки реестра"..
lelitz (19.06.2016 в 08:51):
voffka, ты мега-мозг, я помню zx-spectrum, набор комманд был простой очень, уважаю людей, которые разбираются в криптографии
voffka (18.06.2016 в 01:08):
SHREEF, там кейген пишется за 5 минут. даже вручную можно посчитать, только crc32 "калькулятор" понадобится
SHREEF (17.06.2016 в 18:44):
тогда лучше наити где идет сравнения что бы сделать кеиген
X-Wing Top Ace (17.06.2016 в 15:37):
Насчет основной цели статьи, разумеется, виднее тому, кто ее написАл. ;) Просто лично я с инлайнерами и прочими лодырями связыватся не люблю - все же не так надежно, как кряк распакованного экзюка. И когда можно не связываться - не связываюсь. Крякнутый WinTools работает отменно, уже сделал DUP'овскую ломалку, где в качестве автора кряка указаны, ясен пень, вы.

И спасибище за наводку на DecomAS - этого распаковщика я не знал, пропустил его релиз. ;)
ManHunter (17.06.2016 в 15:23):
Основная цель статьи - инлайн ASProtect, а софтина просто под раздачу попала.
X-Wing Top Ace (17.06.2016 в 15:07):
Как раз тот случай, когда не подменишь правильным инитом проверку, выдавать ли NAGлый экран (как я делаю с HIEW'ом и другими прогами) - пришлось материться в коде и нопить. Не так элегантно, зато надежно работает. Просто слишком объемный код инита защиты.

Для интереса попробую отловить в клоподаве самую первую чекушку рега и посмотреть, не втиснется ли все же туда инитилка вместо чекушки - но не факт, что хватит терпения. ;) Особенно когда есть ваш уже рабочий кряк.
ManHunter (17.06.2016 в 00:52):
Отлови вызов этого окна, перебей условный переход перед ним, добавь в инлайн. Вот и все решение.
pawel97 (16.06.2016 в 23:47):
Ничего не понимаю: распакованный вылечился, а заинлайненный только на половину - пункт "регистрация" отключился, но наг вылазит. В патчере указывал rva 0000A50E, bytes - FFFFFFFF, method 2. После запуска заинлайненной проги и присоединения отладчика видно, что нужные байты пропатчены... Результат прилагаю - www.upload.ee/files/5890990/asp.7z.html
Также пытался сделать подобное в DUP в виде лодыря, с функцией MemCheck, получил  Protection Error 45. RVA и байты указывал те же самые.

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

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

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