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".

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

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

Поделиться ссылкой ВКонтакте
Просмотров: 1026 | Комментариев: 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-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0048 сек.) / Память: 4.5 Mb
Наверх