Blog. Just Blog

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

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

Программа Product Key Explorer предназначена для извлечения из реестра системы информации о регистрационных ключах более 3000 разных программных продуктов, игр и операционных систем (полный список выложен на офсайте). При наличии администраторских привилегий эти данные можно получать и с других машин локальной сети. Также очень удобно, что готовый список можно сохранить в текстовый файл. В общем, Product Key Explorer пригодится как системным администраторам, так и забывчивым пользователям. И опять бы все хорошо, если б разработчики не требовали за нее денег. Хотя для твердолобых поборников аффтарских прав есть другая причина: все было бы хорошо, если бы программа с навешенным протектором запускалась при наличии отладчика в системе. Как вам такой аргумент?

Скачиваем дистрибутив, устанавливаем, смотрим на главный исполняемый файл. Первичный анализ показывает, что он упакован навесным протектором Armadillo. На каждую хитрую защиту есть противодействие, для Armadillo это универсальный распаковщик ArmaGeddon. С его помощью без труда отдираем протектор от программы. Если триальный срок уже прошел, то перед распаковкой придется почистить реестр при помощи Registry Trash Keys Finder.

Распаковываем программу
Распаковываем программу

Затем с помощью CFF Explorer VII удаляем ненужные секции протектора для сокращения размера файла. Восстановленную секцию импорта ".Geddon" переименуйте в ".idata" или оставьте как есть. Должны остаться только те секции, которые показаны на скриншоте. Файл, естественно, должен остаться работоспособным.

Удаляем секции протектора
Удаляем секции протектора

После распаковки файла Product Key Explorer остается незарегистрированным, но в окне About пишет интересную фразу: "Program probably unprotected!". То есть программа как-то взаимодействует с навесным протектором, и скорее всего через переменные окружения Armadillo. Кнопка "Register" в окне About также перестала работать, это только лишний раз подтверждает, что для лицензирования используются средства навесного протектора. Поиск в распакованном файл по стандартным названиям переменных окружения Armadillo сразу же наводит нас на следующий блок данных:

Переменные окружения Armadillo в файле
Переменные окружения Armadillo в файле

Теперь загоняем файл в дизассемблер и посмотрим в нем поподробнее, как эти переменные используются. Обычно регистрационное имя записывается в USERNAME или ALTUSERNAME. На ALTUSERNAME есть только одна перекрестная ссылка из длиннющей процедуры, в которой кроме ALTUSERNAME запрашивается значение USERKEY, сравнивается со значением DEFAULT, куда-то записывается строка "No Key!", проверяется количество лицензий из установленной пользовательской переменной NSALIC, в общем идет активная движуха по проверке регистрации. На выходе из нее получаем EAX=1, если программа зарегистрирована, и EAX=0 в случае с триальным вариантом.
  1. .text:0042C480                 push    0FFFFFFFFh
  2. .text:0042C482                 push    offset SEH_42C480
  3. .text:0042C487                 mov     eax, large fs:0
  4. .text:0042C48D                 push    eax
  5. .text:0042C48E                 mov     large fs:0, esp
  6. .text:0042C495                 sub     esp, 31Ch
  7. .text:0042C49B                 mov     dl, byte_486F70
  8. .text:0042C4A1                 push    ebx
  9. .text:0042C4A2                 push    ebp
  10. .text:0042C4A3                 mov     ebx, ecx
  11. .text:0042C4A5                 push    edi
  12. .text:0042C4A6                 mov     ecx, 3Fh
  13. .text:0042C4AB                 xor     eax, eax
  14. .text:0042C4AD                 lea     edi, [esp+334h+var_20B]
  15. .text:0042C4B4                 mov     [esp+334h+Str1], dl
  16. .text:0042C4BB                 mov     [esp+334h+var_30C], dl
  17. .text:0042C4BF                 rep stosd
  18. .text:0042C4C1                 stosw
  19. .text:0042C4C3                 stosb
  20. .text:0042C4C4                 mov     ecx, 3Fh
  21. .text:0042C4C9                 xor     eax, eax
  22. .text:0042C4CB                 lea     edi, [esp+334h+var_30B]
  23. .text:0042C4CF                 mov     [esp+334h+Src], dl
  24. .text:0042C4D6                 rep stosd
  25. .text:0042C4D8                 stosw
  26. .text:0042C4DA                 stosb
  27. .text:0042C4DB                 mov     ecx, 3Fh
  28. .text:0042C4E0                 xor     eax, eax
  29. .text:0042C4E2                 lea     edi, [esp+334h+var_10B]
  30. .text:0042C4E9                 mov     ebp, ds:GetEnvironmentVariableA
  31. .text:0042C4EF                 rep stosd
  32. .text:0042C4F1                 stosw
  33. .text:0042C4F3                 stosb
  34. .text:0042C4F4                 mov     ecx, 40h
  35. .text:0042C4F9                 xor     eax, eax
  36. .text:0042C4FB                 lea     edi, [esp+334h+Str1]
  37. .text:0042C502                 push    0FFh            ; nSize
  38. .text:0042C507                 rep stosd
  39. .text:0042C509                 mov     ecx, 40h
  40. .text:0042C50E                 lea     edi, [esp+338h+var_30C]
  41. .text:0042C512                 rep stosd
  42. .text:0042C514                 mov     ecx, 40h
  43. .text:0042C519                 lea     edi, [esp+338h+Src]
  44. .text:0042C520                 rep stosd
  45. .text:0042C522                 lea     eax, [esp+338h+Str1]
  46. .text:0042C529                 push    eax             ; lpBuffer
  47. .text:0042C52A                 push    offset aAltusername ; "ALTUSERNAME"
  48. .text:0042C52F                 call    ebp ; GetEnvironmentVariableA
  49. .text:0042C531                 test    eax, eax
  50. .text:0042C533                 jnz     short loc_42C5AB
  51. .text:0042C535                 mov     ecx, off_482C24
  52. .text:0042C53B                 mov     [esp+334h+var_324], ecx
  53. .text:0042C53F                 mov     edi, offset off_468914
  54. .text:0042C544                 push    84h             ; uID
  55. .text:0042C549                 lea     ecx, [esp+338h+var_324]
  56. .text:0042C54D                 mov     [esp+338h+var_4], eax
  57. .text:0042C554                 mov     [esp+338h+var_328], edi
  58. .text:0042C558                 call    ?LoadStringA@CString@@QAEHI@Z
  59. ; CString::LoadStringA(uint)
  60. .text:0042C55D                 lea     eax, [esp+334h+var_328]
  61. .text:0042C561                 lea     edx, [esp+334h+var_324]
  62. .text:0042C565                 neg     eax
  63. .text:0042C567                 sbb     eax, eax
  64. .text:0042C569                 lea     ecx, [ebx+0FCh]
  65. .text:0042C56F                 and     eax, edx
  66. .text:0042C571                 mov     [esp+334h+var_4], 1
  67. .text:0042C57C                 push    eax
  68. .text:0042C57D                 call    sub_456585
  69. .text:0042C582                 lea     ecx, [esp+334h+var_328]
  70. .text:0042C586                 lea     eax, [esp+334h+var_324]
  71. .text:0042C58A                 neg     ecx
  72. .text:0042C58C                 sbb     ecx, ecx
  73. .text:0042C58E                 mov     [esp+334h+var_4], 0FFFFFFFFh
  74. .text:0042C599                 and     ecx, eax
  75. .text:0042C59B                 mov     [esp+334h+var_328], edi
  76. .text:0042C59F                 call    sub_45644C
  77. .text:0042C5A4                 xor     eax, eax
  78. .text:0042C5A6                 jmp     loc_42CB09
  79. .text:0042C5AB ; ------------------------------------------
  80. .text:0042C5AB loc_42C5AB:
  81. .text:0042C5AB                 push    esi
  82. .text:0042C5AC                 lea     ecx, [esp+338h+var_30C]
  83. .text:0042C5B0                 push    0FFh            ; nSize
  84. .text:0042C5B5                 push    ecx             ; lpBuffer
  85. .text:0042C5B6                 push    offset aUserkey_0 ; "USERKEY"
  86. .text:0042C5BB                 call    ebp ; GetEnvironmentVariableA
  87. .text:0042C5BD                 test    eax, eax
  88. .text:0042C5BF                 jnz     short loc_42C5E5
  89. .text:0042C5C1                 mov     edi, offset aNoKey ; "No key!"
  90. .text:0042C5C6                 or      ecx, 0FFFFFFFFh
  91. .text:0042C5C9                 repne scasb
  92. .text:0042C5CB                 not     ecx
  93. .text:0042C5CD                 sub     edi, ecx
  94. .text:0042C5CF                 lea     edx, [esp+338h+var_30C]
  95. .text:0042C5D3                 mov     eax, ecx
  96. .text:0042C5D5                 mov     esi, edi
  97. .text:0042C5D7                 mov     edi, edx
  98. .text:0042C5D9                 shr     ecx, 2
  99. .text:0042C5DC                 rep movsd
  100. .text:0042C5DE                 mov     ecx, eax
  101. .text:0042C5E0                 and     ecx, 3
  102. .text:0042C5E3                 rep movsb
  103. .text:0042C5E5 loc_42C5E5:
  104. .text:0042C5E5                 lea     ecx, [esp+338h+Str1]
  105. .text:0042C5EC                 push    offset aDefault ; "DEFAULT"
  106. .text:0042C5F1                 push    ecx             ; Str1
  107. .text:0042C5F2                 call    __strcmpi
  108. .text:0042C5F7                 add     esp, 8
  109. .text:0042C5FA                 test    eax, eax
  110. .text:0042C5FC                 jnz     short loc_42C678
  111. .text:0042C5FE                 mov     edx, off_482C24
  112. .text:0042C604                 mov     [esp+338h+var_324], edx
  113. .text:0042C608                 mov     edi, offset off_468914
  114. .text:0042C60D                 push    83h             ; uID
  115. .text:0042C612                 lea     ecx, [esp+33Ch+var_324]
  116. .text:0042C616                 mov     [esp+33Ch+var_4], 2
  117. .text:0042C621                 mov     [esp+33Ch+var_328], edi
  118. .text:0042C625                 call    ?LoadStringA@CString@@QAEHI@Z
  119. ; CString::LoadStringA(uint)
  120. .text:0042C62A                 lea     eax, [esp+338h+var_328]
  121. .text:0042C62E                 lea     ecx, [esp+338h+var_324]
  122. .text:0042C632                 neg     eax
  123. .text:0042C634                 sbb     eax, eax
  124. .text:0042C636                 lea     esi, [ebx+0FCh]
  125. .text:0042C63C                 and     eax, ecx
  126. .text:0042C63E                 mov     ecx, esi
  127. ...
Пропатчим начало функции проверки, записав туда команды MOV EAX,1; RET. Сохраняем изменения, запускаем, проверяем. Информация в About стала получше, теперь там нет сообщения, что с программы отодран навесной протектор. Но в остальном ограничения остались - не показываются целиком ключи, нельзя записать найденные ключи в файл. Ищем дальше. Есть еще одна функция, где проверяется значение другой переменной - USERNAME. Тут тоже все очень наглядно:
  1. .text:0042D7E0                 push    0FFFFFFFFh
  2. .text:0042D7E2                 push    offset SEH_42D7E0
  3. .text:0042D7E7                 mov     eax, large fs:0
  4. .text:0042D7ED                 push    eax
  5. .text:0042D7EE                 mov     large fs:0, esp
  6. .text:0042D7F5                 push    ecx
  7. .text:0042D7F6                 mov     eax, off_482C24
  8. .text:0042D7FB                 mov     [esp+10h+Str1], eax
  9. .text:0042D7FF                 lea     edx, [esp+10h+Str1]
  10. .text:0042D803                 mov     [esp+10h+var_4], 0
  11. .text:0042D80B                 push    edx             ; int
  12. .text:0042D80C                 push    offset aUsername_3 ; "USERNAME"
  13. .text:0042D811                 call    sub_42D880
  14. .text:0042D816                 test    eax, eax
  15. .text:0042D818                 jz      short loc_42D85E
  16. .text:0042D81A                 mov     eax, [esp+10h+Str1]
  17. .text:0042D81E                 push    offset aDefault ; "DEFAULT"
  18. .text:0042D823                 push    eax             ; Str1
  19. .text:0042D824                 call    __mbscmp
  20. .text:0042D829                 add     esp, 8
  21. .text:0042D82C                 test    eax, eax
  22. .text:0042D82E                 jz      short loc_42D85E
  23. .text:0042D830                 call    sub_42D6B0
  24. .text:0042D835                 test    eax, eax
  25. .text:0042D837                 jz      short loc_42D85E
  26. .text:0042D839                 lea     ecx, [esp+10h+Str1]
  27. .text:0042D83D                 mov     [esp+10h+var_4], 0FFFFFFFFh
  28. .text:0042D845                 call    sub_45644C
  29. .text:0042D84A                 mov     eax, 1
  30. .text:0042D84F                 mov     ecx, [esp+10h+var_C]
  31. .text:0042D853                 mov     large fs:0, ecx
  32. .text:0042D85A                 add     esp, 10h
  33. .text:0042D85D                 retn
  34. .text:0042D85E ; ----------------------------------------------
  35. .text:0042D85E loc_42D85E:
  36. .text:0042D85E                 lea     ecx, [esp+10h+Str1]
  37. .text:0042D862                 mov     [esp+10h+var_4], 0FFFFFFFFh
  38. .text:0042D86A                 call    sub_45644C
  39. .text:0042D86F                 mov     ecx, [esp+10h+var_C]
  40. .text:0042D873                 xor     eax, eax
  41. .text:0042D875                 mov     large fs:0, ecx
  42. .text:0042D87C                 add     esp, 10h
  43. .text:0042D87F                 retn
На выходе EAX=1 - программа зарегистрирована, EAX=0 - регистрации нет. С этой функцией поступаем аналогичным образом, то есть записываем в начало пару команд MOV EAX,1 и RET. Сохраняем изменения, запускаем. Вот теперь наблюдаем красоту, все ключи найдены, а список сохраняется в файл без каких-либо ограничений.

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

Вот и все, программа "зарегистрирована". В качестве дополнительного приятного бонуса в отломанном виде она становится портативной и может работать с любого съемного носителя. Это особенно удобно, когда приходится иметь дело с чужими компьютерами.

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

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

Комментарии

Отзывы посетителей сайта о статье
Жека (22.07.2014 в 02:31):
REGA, у меня тоже для винды такой же ключ как у ManHunter, мы с ним в одном и том же месте его покупали. (жаль нет весёлых смайликов).
Laki (18.08.2013 в 03:35):
Действительно интересно,только не всё понятно.
ManHunter (02.10.2011 в 17:21):
REGA, я пишу не для 99% людей, а для оставшегося 1%. И ты чо, правда думаешь, что на скриншоте хоть один ключ купленный? :))
REGA (02.10.2011 в 00:26):
срисовал со скриншота ключики
REGA (02.10.2011 в 00:03):
Интересная статья, но бесполезная для 99% людей.
Проще в яше сделать запрос и скачать портативную версию.
Если уж пишите такие статьи то и работу бы выкладывали, а так какая то херь ...
bigcatwar (03.08.2011 в 01:17):
Спасибо ManHunter Огромное!!!
ManHunter (13.06.2011 в 18:16):
Я ж не могу знать всего на свете. Мне всегда было проще пропатчить обработку GetEnvironmentVariable, чем мудохаться с внедрением SetEnvironmentVariable в exe-шншик. Теперь знаю как это делать, буду использовать.
Voffka (13.06.2011 в 18:10):
Ни думал что вы не знаете такой банальности. Если есть Get, то наверное где-то и Set должен быть!? В целях самообразования покурите еще и http://tuts4you.com/download.php?view.299, я сам с него начинал.
ManHunter (13.06.2011 в 03:17):
Хороший способ, особенно с Armadillo Reducer. Приму на вооружение. Спасибо!
Voffka (13.06.2011 в 00:08):
От меня туора не увидите ибо не умею писать больше 2ух строк ткни туда, потом сюда да и арму сейчас не кейгенет только ленивый.Не мной написан, честное слово криво и с ошибками но все же http://tuts4you.com/download.php?view.3153
ManHunter (12.06.2011 в 20:56):
Voffka, я твоих правильных статей с SetEnvironmentVariable как-то тоже не встречал. Напиши как надо, покажи эталонный взлом, я с удовольствием буду равняться на грамотные решения. И да, не стоит коверкать мой ник.
Voffka (12.06.2011 в 20:47):
Почему ты всегда пытаешься все сделать через ж..., т.е. через mov eax,1
ret
Уже не первая программа защищенная армадиллой, а так ни разу про SetEnvironmentVariable не написал, ведь любят люди когда в абауте про них написано.
ManHunter (07.06.2011 в 10:31):
В самом начале вместо push 0FFFFFFFFh две команды mov eax,1 и ret
или по адресу 0042D873 вместо xor eax, eax вбить mov al,1
Compiller (07.06.2011 в 10:15):
А можно поконкретнее где писать mov eax,00000001 ?
А то у меня при выборе About - программа рисует исключение :-(
Compiller (06.06.2011 в 12:59):
Заодно стоит занопить автопроверку обновлений - хотя её можено выключить в триале. Но, судя по всему, она сохраняется в реестре.
ManHunter (06.06.2011 в 12:57):
Удалять надо text1, adata, data1, pdata. В статье тоже поправил, чтобы не было путаницы.
Compiller (06.06.2011 в 12:57):
Есть секции
text
rdata
data
text1
adata
data1
pdata
rsrc
Geddon

Переименовал .Geddon в .idata и удалил три лишние adata text1 data1 - всё заработало.
Спасибо!
ManHunter (06.06.2011 в 12:54):
Это секция импорта, в оригинальном файле ее естественно нет. А после распаковки она может называться ".Geddon"
Compiller (06.06.2011 в 12:53):
В той версии что нынче скачивается с офсайта - секции idata нет после снятия Armadillo :-(

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

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

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