Blog. Just Blog

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

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

Salview - шустрый просмотрщик изображений для Windows, поддерживающий основные графические форматы, но работающий также и с другими изоображениями при наличии установленных кодеков. Ничем особо не выделяется, до признанных топчиков типа XnView, IrfanView и ACDSee ему как до Китая ползком, но тем не менее, имеет место быть. А шароварность мы сейчас поправим.

Забираем с сайта дистрибутив, устанавливаем, смотрим. Единственный исполняемый файл ничем не упакован и не защищен, отправляем его в дизассемблер. Нам надо найти зацепку, чтобы начать исследование. На ввод неправильных регистрационных данных программа реагирует следующим сообщением:

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

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

Строка сообщения в файле
Строка сообщения в файле

Теперь нам надо найти условие, при котором она появляется, то есть при каких условиях серийник считается неправильным. По перекрестным ссылкам в дизассемблере выходим на следующий код:
  1. .text:004B58CD                 push    dword_A2CEAC    ; hWnd
  2. .text:004B58D3                 call    ds:GetWindowTextLengthW
  3. ; Первая проверка. Длина серийника = 29 символов
  4. .text:004B58D9                 cmp     eax, 1Dh
  5. .text:004B58DC                 jnz     loc_4B5B0B
  6. .text:004B58E2                 push    1Eh             ; nMaxCount
  7. .text:004B58E4                 lea     eax, [esp+2CCh+String]
  8. .text:004B58E8                 push    eax             ; lpString
  9. .text:004B58E9                 push    dword_A2CEAC    ; hWnd
  10. .text:004B58EF                 call    ds:GetWindowTextW
  11. ; Вторая проверка. Разделительные дефисы на своих позициях
  12. .text:004B58F5                 cmp     [esp+2C8h+var_28A], 2Dh
  13. .text:004B58FB                 jnz     loc_4B5B0B
  14. .text:004B5901                 cmp     [esp+2C8h+var_27E], 2Dh
  15. .text:004B5907                 jnz     loc_4B5B0B
  16. .text:004B590D                 cmp     [esp+2C8h+var_272], 2Dh
  17. .text:004B5913                 jnz     loc_4B5B0B
  18. .text:004B5919                 cmp     [esp+2C8h+var_266], 2Dh
  19. .text:004B591F                 jnz     loc_4B5B0B
  20. .text:004B5925                 xor     ecx, ecx
  21. .text:004B5927                 mov     [esp+2C8h+hKey], 6
  22. .text:004B592F                 lea     edi, [esp+2C8h+Data]
  23. ; Выделить все валидные символы из серийника
  24. .text:004B5933 loc_4B5933:
  25. .text:004B5933                 lea     eax, [ecx+1]
  26. .text:004B5936                 cdq
  27. .text:004B5937                 idiv    [esp+2C8h+hKey]
  28. .text:004B593B                 test    edx, edx
  29. .text:004B593D                 jz      short loc_4B5963
  30. .text:004B593F                 movzx   eax, [esp+ecx*2+2C8h+String]
  31. .text:004B5944                 cmp     eax, 30h
  32. .text:004B5947                 jb      short loc_4B594E
  33. .text:004B5949                 cmp     eax, 39h
  34. .text:004B594C                 jbe     short loc_4B5960
  35. .text:004B594E loc_4B594E:
  36. .text:004B594E                 cmp     eax, 41h
  37. .text:004B5951                 jb      loc_4B5B0B
  38. .text:004B5957                 cmp     eax, 5Ah
  39. .text:004B595A                 ja      loc_4B5B0B
  40. .text:004B5960 loc_4B5960:
  41. .text:004B5960                 mov     [edi], al
  42. .text:004B5962                 inc     edi
  43. .text:004B5963 loc_4B5963:
  44. .text:004B5963                 inc     ecx
  45. .text:004B5964                 cmp     ecx, 1Dh
  46. .text:004B5967                 jl      short loc_4B5933
  47. .text:004B5969                 lea     ecx, [esp+2C8h+Data]
  48. ; Вызвать основную функцию проверки
  49. .text:004B596D                 call    sub_4B42E0
  50. .text:004B5972                 test    al, al
  51. ; Если она вернула AL!=0, то серийник правильный
  52. .text:004B5974                 jz      loc_4B5B0B
  53. .text:004B597A                 cmp     dword_A2C660, 0
  54. .text:004B5981                 lea     eax, [esp+2C8h+hKey]
  55. ...
  56. ...
  57. .text:004B5B0B loc_4B5B0B:
  58. .text:004B5B0B                 push    10h             ; uType
  59. .text:004B5B0D                 push    offset aRegistrationEr
  60. ; "Registration error"
  61. .text:004B5B12                 push    offset aInvalidKey_
  62. ; "Invalid key."
  63. .text:004B5B17                 push    esi             ; hWnd
  64. .text:004B5B18                 call    ds:MessageBoxW
  65. .text:004B5B1E                 push    dword_A2CEAC    ; hWnd
  66. .text:004B5B24                 call    ds:SetFocus
  67. .text:004B5B2A                 jmp     loc_4B5C67
А таких условий обнаруживается дофига и больше. Начнем разбирать проверки, для удобства я их прокомментировал в листинге. Продублирую буковками. Первая проверка - длина введенного серийника. Она должна быть 29 символов, не больше, не меньше. Дальше проверяется наличие символов-разделителей "-" на своих позициях, для удобства этот процесс можно посмотреть в отладчике. По итогу получается, что серийник состоит из пяти групп по пять символов, разделенных "-". Дальше из серийника выбираются символы, входящие в группу [0-9] и [A-Z]. Логично предположить, что именно они должны входить в каждую группу. Затем вызывается основная проверка и по ее результату выносится вердикт о валидности или невалидности введенного серийника. Посмотрим ее повнимательнее.
  1. .text:004B42E0                 push    ebp
  2. .text:004B42E1                 mov     ebp, esp
  3. .text:004B42E3                 sub     esp, 28h
  4. .text:004B42E6                 mov     eax, dword_A268A4
  5. .text:004B42EB                 xor     eax, ebp
  6. .text:004B42ED                 mov     [ebp+var_4], eax
  7. .text:004B42F0                 push    esi
  8. .text:004B42F1                 push    edi
  9. .text:004B42F2                 xorps   xmm0, xmm0
  10. .text:004B42F5                 mov     [ebp+var_8], 0
  11. .text:004B42FC                 mov     esi, ecx
  12. .text:004B42FE                 mov     edi, 2
  13. .text:004B4303                 movups  [ebp+var_28], xmm0
  14. .text:004B4307                 sub     edi, esi
  15. .text:004B4309                 movups  [ebp+var_18], xmm0
  16. .text:004B430D                 nop     dword ptr [eax]
  17. .text:004B4310 loc_4B4310:
  18. .text:004B4310                 mov     al, [ecx+2]
  19. .text:004B4313                 cmp     al, [ecx+1]
  20. .text:004B4316                 jnz     short loc_4B4320
  21. .text:004B4318                 cmp     al, [ecx]
  22. .text:004B431A                 jz      loc_4B44A5
  23. .text:004B4320 loc_4B4320:
  24. .text:004B4320                 inc     ecx
  25. .text:004B4321                 lea     eax, [edi+ecx]
  26. .text:004B4324                 cmp     eax, 19h
  27. .text:004B4327                 jl      short loc_4B4310
  28. .text:004B4329                 xor     ecx, ecx
  29. .text:004B432B                 nop     dword ptr [eax+eax+00h]
  30. .text:004B4330 loc_4B4330:
  31. .text:004B4330                 mov     dl, [esi+ecx]
  32. .text:004B4333                 lea     eax, [edx-41h]
  33. .text:004B4336                 cmp     al, 19h
  34. .text:004B4338                 ja      short loc_4B4343
  35. .text:004B433A                 movzx   eax, dl
  36. .text:004B433D                 inc     byte ptr [ebp+eax-69h]
  37. .text:004B4341                 jmp     short loc_4B4355
  38. .text:004B4343 ; ------------------------------------
  39. .text:004B4343 loc_4B4343:
  40. .text:004B4343                 lea     eax, [edx-30h]
  41. .text:004B4346                 cmp     al, 9
  42. .text:004B4348                 ja      loc_4B44A5
  43. .text:004B434E                 movzx   eax, dl
  44. .text:004B4351                 inc     [ebp+eax+var_3E]
  45. .text:004B4355 loc_4B4355:
  46. .text:004B4355                 inc     ecx
  47. .text:004B4356                 cmp     ecx, 19h
  48. .text:004B4359                 jl      short loc_4B4330
  49. .text:004B435B                 xor     eax, eax
  50. .text:004B435D                 nop     dword ptr [eax]
  51. .text:004B4360 loc_4B4360:
  52. .text:004B4360                 cmp     byte ptr [ebp+eax+var_28], 3
  53. .text:004B4365                 ja      loc_4B44A5
  54. .text:004B436B                 inc     eax
  55. .text:004B436C                 cmp     eax, 24h
  56. .text:004B436F                 jl      short loc_4B4360
Первую часть проверки без отладчика понять будет трудно. Тут проверяется, чтобы во-первых, не было трех одинаковых символов подряд, а во-вторых, чтобы ни один символ серийника не повторялся более трех раз. Зато вторая часть как по написанному, хоть прямиком из листинга в кейген.
  1. .text:004B4371                 movzx   ecx, byte ptr [esi]
  2. .text:004B4374                 xor     edx, edx
  3. .text:004B4376                 movzx   eax, byte ptr [esi+11h]
  4. .text:004B437A                 add     eax, ecx
  5. .text:004B437C                 mov     ecx, 6
  6. .text:004B4381                 div     ecx
  7. .text:004B4383                 cmp     edx, 5
  8. .text:004B4386                 jnz     loc_4B44A5
  9. .text:004B438C                 movzx   ecx, byte ptr [esi+13h]
  10. .text:004B4390                 movzx   eax, byte ptr [esi+1]
  11. .text:004B4394                 add     ecx, eax
  12. .text:004B4396                 cmp     ecx, 80h
  13. .text:004B439C                 jnz     loc_4B44A5
  14. .text:004B43A2                 movzx   ecx, byte ptr [esi+2]
  15. .text:004B43A6                 xor     edx, edx
  16. .text:004B43A8                 movzx   eax, byte ptr [esi+7]
  17. .text:004B43AC                 add     eax, ecx
  18. .text:004B43AE                 mov     ecx, 0Bh
  19. .text:004B43B3                 div     ecx
  20. .text:004B43B5                 cmp     edx, 2
  21. .text:004B43B8                 jnz     loc_4B44A5
  22. .text:004B43BE                 movzx   ecx, byte ptr [esi+3]
  23. .text:004B43C2                 xor     edx, edx
  24. .text:004B43C4                 movzx   eax, byte ptr [esi+18h]
  25. .text:004B43C8                 add     eax, ecx
  26. .text:004B43CA                 mov     ecx, 0Fh
  27. .text:004B43CF                 div     ecx
  28. .text:004B43D1                 cmp     edx, 9
  29. .text:004B43D4                 jnz     loc_4B44A5
  30. .text:004B43DA                 movzx   ecx, byte ptr [esi+4]
  31. .text:004B43DE                 xor     edx, edx
  32. .text:004B43E0                 movzx   eax, byte ptr [esi+16h]
  33. .text:004B43E4                 add     eax, ecx
  34. .text:004B43E6                 mov     ecx, 11h
  35. .text:004B43EB                 div     ecx
  36. .text:004B43ED                 cmp     edx, 3
  37. .text:004B43F0                 jnz     loc_4B44A5
  38. .text:004B43F6                 movzx   ecx, byte ptr [esi+5]
  39. .text:004B43FA                 xor     edx, edx
  40. .text:004B43FC                 movzx   eax, byte ptr [esi+0Ch]
  41. .text:004B4400                 add     eax, ecx
  42. .text:004B4402                 mov     ecx, 0Eh
  43. .text:004B4407                 div     ecx
  44. .text:004B4409                 cmp     edx, 7
  45. .text:004B440C                 jnz     loc_4B44A5
  46. .text:004B4412                 movzx   ecx, byte ptr [esi+6]
  47. .text:004B4416                 xor     edx, edx
  48. .text:004B4418                 movzx   eax, byte ptr [esi+12h]
  49. .text:004B441C                 add     eax, ecx
  50. .text:004B441E                 mov     ecx, 17h
  51. .text:004B4423                 div     ecx
  52. .text:004B4425                 test    edx, edx
  53. .text:004B4427                 jnz     short loc_4B44A5
  54. .text:004B4429                 movzx   ecx, byte ptr [esi+15h]
  55. .text:004B442D                 movzx   eax, byte ptr [esi+8]
  56. .text:004B4431                 add     ecx, eax
  57. .text:004B4433                 cmp     ecx, 88h
  58. .text:004B4439                 jnz     short loc_4B44A5
  59. .text:004B443B                 movzx   ecx, byte ptr [esi+9]
  60. .text:004B443F                 movzx   eax, byte ptr [esi+0Dh]
  61. .text:004B4443                 add     eax, ecx
  62. .text:004B4445                 mov     ecx, 1Ch
  63. .text:004B444A                 div     ecx
  64. .text:004B444C                 cmp     edx, 8
  65. .text:004B444F                 jnz     short loc_4B44A5
  66. .text:004B4451                 movzx   ecx, byte ptr [esi+0Fh]
  67. .text:004B4455                 movzx   eax, byte ptr [esi+0Ah]
  68. .text:004B4459                 add     ecx, eax
  69. .text:004B445B                 cmp     ecx, 0A2h
  70. .text:004B4461                 jnz     short loc_4B44A5
  71. .text:004B4463                 movzx   ecx, byte ptr [esi+10h]
  72. .text:004B4467                 movzx   eax, byte ptr [esi+0Bh]
  73. .text:004B446B                 add     ecx, eax
  74. .text:004B446D                 cmp     ecx, 9Dh
  75. .text:004B4473                 jnz     short loc_4B44A5
  76. .text:004B4475                 movzx   ecx, byte ptr [esi+0Eh]
  77. .text:004B4479                 xor     edx, edx
  78. .text:004B447B                 movzx   eax, byte ptr [esi+14h]
  79. .text:004B447F                 add     eax, ecx
  80. .text:004B4481                 mov     ecx, 0Dh
  81. .text:004B4486                 div     ecx
  82. .text:004B4488                 cmp     edx, 2
  83. .text:004B448B                 jnz     short loc_4B44A5
  84. .text:004B448D                 test    byte ptr [esi+17h], 3
  85. .text:004B4491                 jnz     short loc_4B44A5
Поочередно проверяются пары символов, если они удовлетворяют условиям, то все нормально. Только последняя проверка на битовую маску. Простейший алгоритм генерации представляет собой брутфорс парных символов и битовой маски с последующей проверкой количества вхождений символов. Так, валидным серийником, удовлетворяющим всем условиям, будет строка "C3Z1I-RAXXR-HDAB2-ZYFIM-R018P".

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

Повторяем регистрацию с найденным серийником. Программа благодарит за регистрацию. Да не за что, всегда пожалуйста, рад был помочь, заходите еще. Цель достигнута, кейген нарисуете самостоятельно.

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

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

Комментарии

Отзывы посетителей сайта о статье
ManHunter (07.06.2021 в 14:38):
Если патчить под любой серийник, то придется нейтрализовать целую груду условных переходов. И не только здесь при вводе, но и при старте программы наверняка есть какой-то подобный код. По-моему, оно того не стоит.
федя (07.06.2021 в 13:24):
Не совсем понял кусок кода отвечающий за финальную проверку чтоб его пропачить

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

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

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