Blog. Just Blog

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

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

Программа Magic Photo Recovery предназначена для восстановления файлов изображений с различных носителей. Это могут быть просто удаленные файлы или даже информация на поврежденных носителях. Поиск выполняется по внутренней структуре графических файлов, в том числе и RAW, что позволяет с очень хорошей вероятностью восстановить данные. Без платной регистрации имеются ограничения в работе, что не есть правильно. Давайте решим эту проблему.

Первым делом забираем с сайта дистрибутив портативной версии. Можно скачать и обычный инсталлятор, но при прочих равных мне больше нравится портативный софт. В архиве два варианта софтины, потрошить будем 32-битную версию. Главный исполняемый файл ничем не упакован, сразу отправляем его в дизассемблер. Параллельно посмотрим, к чему можно зацепиться для анализа. При попытке регистрации неправильными данными появляется сообщение:

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

Программа мультиязычная, все строки содержатся в соответствующих языковых файлах. К сожалению, в данном случае это нам ничем не поможет, все индексы строк числовые, дефолтных строк на случай недоступности файлов локализации в программе не содержится, искать что-то в огромном листинге по одно-двухзначному числу - задача нетривиальная. Значит поищем в файле что-нибудь из списка типа "trial", "license", "registered" и прочих характерных строчек, так или иначе связанных с регистрацией программы. Обнаружится вот такой интересный кусочек данных:

Строка в файле
Строка в файле

Тут юникодная строка с характерным названием ветки реестра, а также названия двух ключей - "UserName" и "LicenseKey". Чуть ниже эти строчки дублируются еще раз. Очевидно, что это ключи реестра, в которых хранится регистрационная информация, хотя очень странно наблюдать подобное в портативной версии программы. Ну да ладно, это остается на совести автора. Нас же интересует тот факт, что данные в реестр должны быть как минимум один раз записаны при правильной регистрации, а затем один или более раз считаны оттуда при запуске и работе программы. Давайте вернемся в листинг и посмотрим, где и как используются оба найденных комплекта строк.
  1. .text:00794BAD                 lea     ecx, [ebp+var_C]
  2. .text:00794BB0                 mov     edx, [ebp+var_8]
  3. .text:00794BB3                 mov     eax, [ebp+var_4]
  4. ; Вызвать функцию проверки
  5. .text:00794BB6                 call    sub_795A34
  6. .text:00794BBB                 test    al, al
  7. ; Если AL=0, то в реестр ничего не записывать
  8. .text:00794BBD                 jz      loc_794C76
  9. .text:00794BC3                 mov     [ebp+var_D], 1
  10. .text:00794BC7                 mov     eax, off_EAE774
  11. .text:00794BCC                 mov     byte ptr [eax], 1
  12. .text:00794BCF                 mov     eax, off_EB0AB4
  13. .text:00794BD4                 mov     edx, [ebp+var_4]
  14. .text:00794BD7                 call    sub_40BCD0
  15. .text:00794BDC                 mov     eax, off_EB038C
  16. .text:00794BE1                 mov     edx, [ebp+var_8]
  17. .text:00794BE4                 call    sub_40BCD0
  18. .text:00794BE9                 mov     eax, off_EAEBFC
  19. .text:00794BEE                 mov     edx, [ebp+var_C]
  20. .text:00794BF1                 call    sub_40BCD0
  21. .text:00794BF6                 mov     eax, off_EAF254
  22. .text:00794BFB                 mov     edx, [ebp+var_14]
  23. .text:00794BFE                 mov     [eax], edx
  24. .text:00794C00                 mov     dl, 1
  25. .text:00794C02                 mov     eax, ds:off_50F2A0
  26. .text:00794C07                 call    sub_5103EC
  27. .text:00794C0C                 mov     [ebp+var_18], eax
  28. .text:00794C0F                 xor     eax, eax
  29. .text:00794C11                 push    ebp
  30. .text:00794C12                 push    offset loc_794C6F
  31. .text:00794C17                 push    dword ptr fs:[eax]
  32. .text:00794C1A                 mov     fs:[eax], esp
  33. .text:00794C1D                 mov     edx, 80000001h
  34. .text:00794C22                 mov     eax, [ebp+var_18]
  35. .text:00794C25                 call    sub_5104D4
  36. .text:00794C2A                 mov     cl, 1
  37. ; Сохранить в реестре введенное имя и серийный номер
  38. .text:00794C2C                 mov     edx, offset aSoftwareEastIm
  39. ; "Software\\East Imperial Soft\\Magic Photo"...
  40. .text:00794C31                 mov     eax, [ebp+var_18]
  41. .text:00794C34                 call    sub_51062C
  42. .text:00794C39                 mov     ecx, [ebp+var_4]
  43. .text:00794C3C                 mov     edx, offset aUsername
  44. ; "UserName"
  45. .text:00794C41                 mov     eax, [ebp+var_18]
  46. .text:00794C44                 call    sub_510F84
  47. .text:00794C49                 mov     ecx, [ebp+var_8]
  48. .text:00794C4C                 mov     edx, offset aLicensekey
  49. ; "LicenseKey"
  50. .text:00794C51                 mov     eax, [ebp+var_18]
  51. .text:00794C54                 call    sub_510F84
  52. .text:00794C59                 xor     eax, eax
  53. .text:00794C5B                 pop     edx
Первый блок пропускаем, он используется для чтения данных из реестра. А вот второй - самое оно. Тут выполняется некая проверка, затем по ее результатам или выполняется условный переход, или записываются данные в реестр. Если посмотреть на саму функцию проверки, то выяснится, что она вызывается два раза, то есть один раз при проверке введенных данных для регистрации, а второй - при запуске программы. И мы выяснили, что она должна вернуть ненулевое значение в регистре AL. Патчим начало функции парой команд MOV EAX,1 и RET 4, чтобы корректно восстановить стек. Сохраняем изменения, повторяем регистрацию левыми данными.

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

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

Бинарная хирургия - это хорошо и здорово, но давайте теперь копнем поглубже и попробуем зарегистрировать программу правильным серийным номером. Восстанавливаем пропатченный файл и возвращаемся в функцию проверки.
  1. .text:00795A52                 push    dword ptr fs:[eax]
  2. .text:00795A55                 mov     fs:[eax], esp
  3. .text:00795A58                 push    ebp
  4. ; Первая проверка
  5. .text:00795A59                 call    sub_795918
  6. .text:00795A5E                 pop     ecx
  7. .text:00795A5F                 test    al, al
  8. .text:00795A61                 jnz     short loc_795A6D
  9. .text:00795A63                 xor     eax, eax
  10. .text:00795A65                 pop     edx
  11. .text:00795A66                 pop     ecx
  12. .text:00795A67                 pop     ecx
  13. .text:00795A68                 mov     fs:[eax], edx
  14. .text:00795A6B                 jmp     short loc_795AD4
  15. .text:00795A6D ; ---------------------------------------
  16. .text:00795A6D loc_795A6D:
  17. ; Последовательность проверок на тип лицензии
  18. .text:00795A6D                 push    ebp
  19. .text:00795A6E                 mov     eax, offset aHomeEdition
  20. ; "Home Edition"
  21. .text:00795A73                 call    sub_7958BC
  22. .text:00795A78                 pop     ecx
  23. .text:00795A79                 test    al, al
  24. .text:00795A7B                 jnz     short loc_795AA7
  25. .text:00795A7D                 push    ebp
  26. .text:00795A7E                 mov     eax, offset aOfficeEdition
  27. ; "Office Edition"
  28. .text:00795A83                 call    sub_7958BC
  29. .text:00795A88                 pop     ecx
  30. .text:00795A89                 test    al, al
  31. .text:00795A8B                 jnz     short loc_795AA7
  32. .text:00795A8D                 push    ebp
  33. .text:00795A8E                 mov     eax, offset aCommercialEdit
  34. ; "Commercial Edition"
  35. .text:00795A93                 call    sub_7958BC
  36. .text:00795A98                 pop     ecx
  37. .text:00795A99                 test    al, al
  38. .text:00795A9B                 jnz     short loc_795AA7
  39. .text:00795A9D                 xor     eax, eax
  40. .text:00795A9F                 pop     edx
  41. .text:00795AA0                 pop     ecx
  42. .text:00795AA1                 pop     ecx
  43. .text:00795AA2                 mov     fs:[eax], edx
  44. .text:00795AA5                 jmp     short loc_795AD4
  45. .text:00795AA7 ; -------------------------------
  46. .text:00795AA7 loc_795AA7:
  47. .text:00795AA7                 push    ebp
  48. ; Финальная проверка
  49. .text:00795AA8                 call    sub_7952CC
  50. .text:00795AAD                 pop     ecx
  51. .text:00795AAE                 test    al, al
  52. .text:00795AB0                 jnz     short loc_795ABC
  53. .text:00795AB2                 xor     eax, eax
  54. .text:00795AB4                 pop     edx
  55. .text:00795AB5                 pop     ecx
  56. .text:00795AB6                 pop     ecx
  57. .text:00795AB7                 mov     fs:[eax], edx
  58. .text:00795ABA                 jmp     short loc_795AD4
  59. .text:00795ABC ; ---------------------------------------
  60. .text:00795ABC loc_795ABC:
  61. ; Все проверки пройдены, серийный номер правильный
  62. .text:00795ABC                 mov     [ebp+var_D], 1
  63. .text:00795AC0                 xor     eax, eax
  64. .text:00795AC2                 pop     edx
  65. .text:00795AC3                 pop     ecx
Начнем с первой проверки. Запускаем программу под отладчиком, ставим точку останова на начало функции проверки по адресу 00795918, повторяем регистрацию с левыми данными. Когда точка останова сработает, пройдем код этой проверки в пошаговом режиме.
  1. .text:00795938                 push    ebp
  2. .text:00795939                 push    offset loc_7959FB
  3. .text:0079593E                 push    dword ptr fs:[edx]
  4. .text:00795941                 mov     fs:[edx], esp
  5. .text:00795944                 mov     eax, [ebp+arg_0]
  6. .text:00795947                 mov     eax, [eax-4]
  7. .text:0079594A                 test    eax, eax
  8. .text:0079594C                 jz      short loc_795953
  9. .text:0079594E                 sub     eax, 4
  10. ; Длина серийного номера должна быть не менее 13h (19) символов
  11. .text:00795951                 mov     eax, [eax]
  12. .text:00795953 loc_795953:
  13. .text:00795953                 cmp     eax, 13h
  14. .text:00795956                 jl      loc_7959F1
Первый условный переход срабатывает в том случае, когда длина введенного серийного номера будет меньше 13h (19 в десятичной) символов. Подгоняем левый серийник под нужную длину, повторяем регистрацию, эта часть проверки пройдена.
  1. .text:0079595C                 lea     eax, [ebp+var_4]
  2. .text:0079595F                 push    eax
  3. .text:00795960                 mov     eax, [ebp+arg_0]
  4. .text:00795963                 mov     eax, [eax-4]
  5. .text:00795966                 mov     ecx, 12h
  6. .text:0079596B                 mov     edx, 1
  7. .text:00795970                 call    sub_40CDEC
  8. .text:00795975                 lea     eax, [ebp+var_4]
  9. .text:00795978                 mov     ecx, 1
  10. .text:0079597D                 mov     edx, 0Fh
  11. .text:00795982                 call    sub_40CE34
  12. .text:00795987                 lea     eax, [ebp+var_4]
  13. .text:0079598A                 mov     ecx, 1
  14. .text:0079598F                 mov     edx, 0Ah
  15. .text:00795994                 call    sub_40CE34
  16. .text:00795999                 lea     eax, [ebp+var_4]
  17. .text:0079599C                 mov     ecx, 1
  18. .text:007959A1                 mov     edx, 5
  19. .text:007959A6                 call    sub_40CE34
На этом шаге из серийника вырезаются три группы по 4 символа с пропуском одного символа после группы и одну группу из трех символов, оставляя последний символ. Таким образом, серийный номер имеет формат типа "XXXX-XXXX-XXXX-XXXX". Снова подгоняем левый серийник под найденный формат, повторяем регистрацию.
  1. .text:007959AB                 xor     ebx, ebx
  2. .text:007959AD                 mov     eax, 1
  3. .text:007959B2 loc_7959B2:
  4. .text:007959B2                 mov     edx, [ebp+var_4]
  5. .text:007959B5                 movzx   edx, word ptr [edx+eax*2-2]
  6. .text:007959BA                 imul    edx, eax
  7. .text:007959BD                 add     ebx, edx
  8. .text:007959BF                 inc     eax
  9. .text:007959C0                 cmp     eax, 10h
  10. .text:007959C3                 jnz     short loc_7959B2
  11. .text:007959C5                 lea     edx, [ebp+var_8]
  12. .text:007959C8                 mov     eax, ebx
  13. .text:007959CA                 call    sub_4284A0
  14. .text:007959CF                 mov     eax, [ebp+var_8]
  15. .text:007959D2                 test    eax, eax
  16. .text:007959D4                 jz      short loc_7959DB
  17. .text:007959D6                 sub     eax, 4
  18. .text:007959D9                 mov     eax, [eax]
  19. .text:007959DB loc_7959DB:
  20. .text:007959DB                 mov     edx, [ebp+var_8]
  21. .text:007959DE                 movzx   eax, word ptr [edx+eax*2-2]
  22. .text:007959E3                 mov     edx, [ebp+arg_0]
  23. .text:007959E6                 mov     edx, [edx-4]
  24. ; Сравнение контрольного значения и последнего символа серийника
  25. .text:007959E9                 cmp     ax, [edx+24h]
  26. .text:007959ED                 setz    [ebp+var_9]
Тут последовательно берется каждый символ из урезанного серийника, его hex-код умножается на позицию этого символа, все эти значения суммируются. Полученное число в десятичном виде переводится в строку. Последний символ этой строки должен быть равен последнему символу введенного серийного номера. Корректируем серийник с учетом новых значений, повторяем регистрацию, убеждаемся, что первая проверка успешно пройдена. Едем дальше.

Во второй проверке на тип лицензии последовательно вызывается одна и та же функция, которой в качестве параметра передается строка с типом лицензии. Тут особо ничего интересного кроме вызова очередной функции проверки по адресу 007958DD, если результат в AL будет не равен нулю, то тип лицензии принимается.
  1. .text:007958BC                 push    ebp
  2. .text:007958BD                 mov     ebp, esp
  3. .text:007958BF                 push    ecx
  4. .text:007958C0                 push    ebx
  5. .text:007958C1                 push    esi
  6. .text:007958C2                 push    edi
  7. .text:007958C3                 mov     ebx, eax
  8. .text:007958C5                 mov     [ebp+var_1], 0
  9. .text:007958C9                 xor     eax, eax
  10. .text:007958CB                 push    ebp
  11. .text:007958CC                 push    offset loc_795903
  12. .text:007958D1                 push    dword ptr fs:[eax]
  13. .text:007958D4                 mov     fs:[eax], esp
  14. .text:007958D7                 mov     eax, [ebp+arg_0]
  15. .text:007958DA                 push    eax
  16. .text:007958DB                 mov     eax, ebx
  17. ; Вызывать функцию проверки, по ее результатам принимается решение
  18. ; о корректности типа лицензии
  19. .text:007958DD                 call    sub_7955C8
  20. .text:007958E2                 pop     ecx
  21. .text:007958E3                 mov     [ebp+var_1], al
  22. .text:007958E6                 cmp     [ebp+var_1], 0
  23. .text:007958EA                 jz      short loc_7958F9
  24. .text:007958EC                 mov     eax, [ebp+arg_0]
  25. .text:007958EF                 mov     eax, [eax-0Ch]
  26. .text:007958F2                 mov     edx, ebx
  27. .text:007958F4                 call    sub_40BCD0
Смотрим, как проверяется тип лицензии. Ставим точку останова по адресу 007955C8 на начало функции проверки, повторяем регистрацию.
  1. .text:007955F7                 push    dword ptr fs:[edx]
  2. .text:007955FA                 mov     fs:[edx], esp
  3. .text:007955FD                 lea     eax, [ebp+var_2C]
  4. .text:00795600                 mov     edx, [ebp+arg_0]
  5. .text:00795603                 mov     edx, [edx-8]
  6. .text:00795606                 call    sub_40CABC
  7. .text:0079560B                 mov     eax, [ebp+var_2C]
  8. .text:0079560E                 lea     edx, [ebp+var_28]
  9. .text:00795611                 call    sub_427968
  10. .text:00795616                 mov     edx, [ebp+var_28]
  11. .text:00795619                 lea     eax, [ebp+var_24]
  12. .text:0079561C                 call    sub_40CAA8
  13. .text:00795621                 mov     eax, [ebp+var_24]
  14. .text:00795624                 lea     edx, [ebp+var_8]
  15. .text:00795627                 call    sub_427A48
  16. .text:0079562C                 lea     eax, [ebp+var_C]
  17. .text:0079562F                 call    sub_40B8F0
  18. .text:00795634                 lea     edx, [ebp+var_34]
  19. .text:00795637                 mov     eax, offset aMagicPhotoRe_2
  20. ; "Magic Photo Recovery"
  21. .text:0079563C                 call    sub_427968
  22. .text:00795641                 mov     edx, [ebp+var_34]
  23. .text:00795644                 lea     eax, [ebp+var_30]
  24. .text:00795647                 call    sub_40CAA8
  25. .text:0079564C                 mov     eax, [ebp+var_30]
  26. .text:0079564F                 lea     edx, [ebp+var_10]
  27. .text:00795652                 call    sub_427A48
  28. .text:00795657                 lea     eax, [ebp+var_40]
  29. .text:0079565A                 mov     edx, ebx
  30. .text:0079565C                 call    sub_40CABC
  31. .text:00795661                 mov     eax, [ebp+var_40]
  32. .text:00795664                 lea     edx, [ebp+var_3C]
  33. .text:00795667                 call    sub_427968
  34. .text:0079566C                 mov     edx, [ebp+var_3C]
  35. .text:0079566F                 lea     eax, [ebp+var_38]
  36. .text:00795672                 call    sub_40CAA8
  37. .text:00795677                 mov     eax, [ebp+var_38]
  38. .text:0079567A                 lea     edx, [ebp+var_14]
  39. .text:0079567D                 call    sub_427A48
  40. .text:00795682                 mov     dl, 1
  41. .text:00795684                 mov     eax, ds:off_68FA7C
  42. .text:00795689                 call    sub_68FBB0
  43. .text:0079568E                 mov     [ebp+var_20], eax
  44. .text:00795691                 xor     edx, edx
  45. .text:00795693                 push    ebp
  46. .text:00795694                 push    offset loc_795785
  47. .text:00795699                 push    dword ptr fs:[edx]
  48. .text:0079569C                 mov     fs:[edx], esp
  49. .text:0079569F                 lea     eax, [ebp+var_44]
  50. .text:007956A2                 push    eax
  51. .text:007956A3                 lea     eax, [ebp+var_48]
  52. .text:007956A6                 call    sub_679DB4
  53. .text:007956AB                 mov     eax, [ebp+var_48]
  54. .text:007956AE                 push    eax
  55. .text:007956AF                 push    [ebp+var_8]
  56. .text:007956B2                 push    [ebp+var_10]
  57. .text:007956B5                 push    [ebp+var_14]
  58. .text:007956B8                 push    offset a00814250F41b4f
  59. ; "00814250-F41B-4FCF-BF6A-5841E6E76EF9"
  60. .text:007956BD                 lea     eax, [ebp+var_4C]
  61. .text:007956C0                 mov     edx, 4
  62. .text:007956C5                 call    sub_40CCA4
  63. .text:007956CA                 mov     edx, [ebp+var_4C]
  64. .text:007956CD                 mov     eax, [ebp+var_20]
  65. .text:007956D0                 pop     ecx
  66. .text:007956D1                 call    sub_68F2C4
  67. .text:007956D6                 mov     eax, [ebp+var_44]
  68. .text:007956D9                 lea     edx, [ebp+var_18]
  69. .text:007956DC                 call    sub_4274B8
В пошаговом режиме проходим этот участок кода и выясняем, что тут формируется длиннющая строка из регистрационного имени, строки "Magic Photo Recovery", строки типа лицензии и еще какой-то корявой строки "00814250-F41B-4FCF-BF6A-5841E6E76EF9". Причем все эти строки предварительно переводятся в верхний регистр. Итого, для первого типа лицензии формируется юникодная строка вида "MANHUNTER / PCLMAGIC PHOTO RECOVERYHOME EDITION00814250-F41B-4FCF-BF6A-5841E6E76EF9". После этого строка хешируется по алгоритму MD5.
  1. .text:007956F4                 xor     esi, esi
  2. .text:007956F6 loc_7956F6:
  3. .text:007956F6                 mov     eax, edi
  4. .text:007956F8                 add     eax, eax
  5. .text:007956FA                 add     eax, eax
  6. .text:007956FC                 inc     eax
  7. .text:007956FD                 add     eax, esi
  8. .text:007956FF                 mov     edx, [ebp+var_18]
  9. .text:00795702                 movzx   eax, word ptr [edx+eax*2-2]
  10. .text:00795707                 lea     edx, [ebp+var_4]
  11. .text:0079570A                 call    sub_4284A0
  12. .text:0079570F                 mov     ebx, [ebp+var_4]
  13. .text:00795712                 test    ebx, ebx
  14. .text:00795714                 jz      short loc_79571B
  15. .text:00795716                 sub     ebx, 4
  16. .text:00795719                 mov     ebx, [ebx]
  17. .text:0079571B loc_79571B:
  18. .text:0079571B                 lea     eax, [ebp+var_50]
  19. .text:0079571E                 mov     edx, [ebp+var_4]
  20. .text:00795721                 movzx   edx, word ptr [edx+ebx*2-2]
  21. .text:00795726                 call    sub_40C9D8
  22. .text:0079572B                 mov     edx, [ebp+var_50]
  23. .text:0079572E                 lea     eax, [ebp+var_C]
  24. .text:00795731                 call    sub_40CBC4
  25. .text:00795736                 inc     esi
  26. .text:00795737                 cmp     esi, 4
  27. .text:0079573A                 jnz     short loc_7956F6
  28. .text:0079573C                 inc     edi
  29. .text:0079573D                 cmp     edi, 3
  30. .text:00795740                 jnz     short loc_7956E3
  31. .text:00795742                 lea     eax, [ebp+var_54]
  32. .text:00795745                 push    eax
  33. .text:00795746                 mov     eax, [ebp+arg_0]
  34. .text:00795749                 mov     eax, [eax-4]
  35. .text:0079574C                 mov     ecx, 0Eh
  36. .text:00795751                 mov     edx, 1
  37. .text:00795756                 call    sub_40CDEC
Тут символы строки хеша последовательно преобразуются в строку, преобразования выполняется по два символа. В итоге все сводится к сравнению двух строк:
  1. .text:0079575B                 mov     edx, [ebp+var_54]
  2. .text:0079575E                 mov     eax, [ebp+var_C]
  3. .text:00795761                 call    sub_40CDB4
  4. .text:00795766                 setz    [ebp+var_19]
Под отладчиком видно, что тут сравниваются три первые группы из введенного серийного номера и контрольная строка, полученная из хеша. Контрольная строка для каждого типа лицензии своя. Последовательно выясняем, что для регистрационного имени "ManHunter / PCL" будут три серийных номера для каждого типа лицензии: "Home Edition" - "6289-5881-5968", "Office Edition" - "6988-7983-8930" и "Commercial Edition" - "6845-0068-2735". Отлично, мы выяснили первые группы цифр серийника. Возьмем максимальную коммерческую лицензию, подставим в конец группу из произвольных чисел, например, "6845-0068-2735-7777" и вновь повторим регистрацию. Но мы помним, что все символы серийника кроме последнего участвуют в первой проверке и в итоге должна получиться корректная последняя цифра. Возвращаемся к первой проверке и получаем, соответственно, последние группы "7778", "7778" и "7775". Повторяем регистрацию любым из сформированных серийников, обе проверки проходят, программа благодарит за регистрацию, но при этом в заголовке все равно отображается счетчик дней. Непорядок. У нас осталась еще одна большая проверка, которая выполняется после проверки типа лицензии.
  1. .text:00794DBD                 push    dword ptr fs:[eax]
  2. .text:00794DC0                 mov     fs:[eax], esp
  3. .text:00794DC3                 xor     eax, eax
  4. .text:00794DC5                 mov     [ebp+var_8], eax
  5. .text:00794DC8                 xor     ecx, ecx
  6. .text:00794DCA                 push    ebp
  7. .text:00794DCB                 push    offset loc_794E82
  8. .text:00794DD0                 push    dword ptr fs:[ecx]
  9. .text:00794DD3                 mov     fs:[ecx], esp
  10. .text:00794DD6                 xor     eax, eax
  11. .text:00794DD8                 mov     [ebp+var_C], eax
  12. .text:00794DDB                 xor     edx, edx
  13. .text:00794DDD loc_794DDD:
  14. .text:00794DDD                 xor     eax, eax
  15. .text:00794DDF loc_794DDF:
  16. .text:00794DDF                 lea     ecx, [edx+edx*4]
  17. .text:00794DE2                 inc     ecx
  18. .text:00794DE3                 add     ecx, eax
  19. .text:00794DE5                 mov     esi, [ebx]
  20. .text:00794DE7                 movzx   ecx, word ptr [esi+ecx*2-2]
  21. .text:00794DEC                 add     [ebp+var_C], ecx
  22. .text:00794DEF                 inc     eax
  23. .text:00794DF0                 cmp     eax, 4
  24. .text:00794DF3                 jnz     short loc_794DDF
  25. .text:00794DF5                 inc     edx
  26. .text:00794DF6                 cmp     edx, 3
  27. .text:00794DF9                 jnz     short loc_794DDD
  28. .text:00794DFB                 lea     eax, [ebp+var_4]
  29. .text:00794DFE                 push    eax
  30. .text:00794DFF                 push    offset dword_794ECC
  31. .text:00794E04                 lea     edx, [ebp+var_18]
  32. .text:00794E07                 mov     eax, [ebp+var_C]
  33. .text:00794E0A                 call    sub_4284A0
  34. .text:00794E0F                 push    [ebp+var_18]
  35. .text:00794E12                 push    offset dword_794EDC
  36. .text:00794E17                 lea     eax, [ebp+var_14]
  37. .text:00794E1A                 mov     edx, 3
  38. .text:00794E1F                 call    sub_40CCA4
  39. .text:00794E24                 mov     eax, [ebp+var_14]
  40. .text:00794E27                 mov     ecx, 3
  41. .text:00794E2C                 mov     edx, 1
  42. .text:00794E31                 call    sub_40CDEC
  43. .text:00794E36                 lea     eax, [ebp+var_1C]
  44. .text:00794E39                 push    eax
Первые три группы серийника посимвольно складываются, сумма также преобразуется в строку и из нее берутся первые три символа. Они должны быть равны первым трем символам последней группы серийного номера. Проверки выполняются здесь:
  1. .text:00794E4B                 mov     eax, [ebp+var_1C]
  2. .text:00794E4E                 lea     edx, [ebp+var_10]
  3. .text:00794E51                 call    sub_42888C
  4. .text:00794E56                 test    al, al
  5. .text:00794E58                 jz      short loc_794E78
  6. .text:00794E5A                 lea     edx, [ebp+var_C]
  7. .text:00794E5D                 mov     eax, [ebp+var_4]
  8. .text:00794E60                 call    sub_42888C
  9. .text:00794E65                 test    al, al
Таким образом получаем группы из трех символов для каждого типа лицензии. Это будут "165", "165" и "163". Серийники опять изменились, поэтому опять надо вычислить последний символ. Повторяем регистрацию, получая нужные символы из первой проверки. Итоговые серийники для имени "ManHunter / PCL" получились следующие: Home Edition - "6289-5881-5968-1656", Office Edition - "6988-7983-8930-1656", Commercial Edition - "6845-0068-2735-1633". Для релиза вполне достаточно. Закрываем отладчик, повторяем регистрацию с нужным типом лицензии.

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

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

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

Комментарии

Отзывы посетителей сайта о статье
xussr (28.12.2019 в 22:10):
Этот пример более понятен и доступен спасибо!

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

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

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