Blog. Just Blog

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

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

Программа LogViewer предназначена для просмотра файлов логов. Работает очень шустро, поддерживает огромные файлы даже от 4 гигов, отслеживает последние изменения в реальном времени, подсвечивает строки по сигнатурам, портативная, да и вообще полезный инструмент для системных администраторов. Без регистрации при запуске выводит напоминание о необходимости покупки и ограничивает количество активных вкладок.

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

Триальное окно
Триальное окно

Кроме этого в заголовке обнаруживается приметная надпись "Unregistered", тоже хорошая зацепка. Исполняемый файл ничем не упакован, отправляем его в дизассемблер.

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

Строка легко обнаруживается поиском по файлу. Переходим в дизассемблер и смотрим, при каких условиях она появляется.
  1. CODE:252C8C41                 lea     edx, [ebp+var_5]
  2. CODE:252C8C44                 lea     eax, [ebp+var_4]
  3. ; Вызвать функцию проверки
  4. CODE:252C8C47                 call    sub_252C8AF0
  5. ; Сохранить ее результат
  6. CODE:252C8C4C                 mov     ds:byte_252E0BA8, al
  7. ; Проверить результат
  8. CODE:252C8C51                 cmp     ds:byte_252E0BA8, 0
  9. ; Программа работает в триальном режиме
  10. CODE:252C8C58                 jz      short loc_252C8C6E
  11. CODE:252C8C5A                 mov     eax, offset unk_252E3094
  12. CODE:252C8C5F                 mov     ecx, [ebp+var_4]
  13. CODE:252C8C62                 mov     edx, offset dword_252C8CA8
  14. CODE:252C8C67                 call    sub_25204968
  15. CODE:252C8C6C                 jmp     short loc_252C8C7D
  16. CODE:252C8C6E ; ----------------------------------------------------------------
  17. CODE:252C8C6E loc_252C8C6E:
  18. ; Дописать в заголовок строку " - Unregistered"
  19. CODE:252C8C6E                 mov     eax, offset unk_252E3094
  20. CODE:252C8C73                 mov     edx, offset aUnregistered
  21. ; " - Unregistered"
  22. CODE:252C8C78                 call    sub_252046A0
  23. CODE:252C8C7D
По комментариям все должно быть понятно. Вызывается функция проверки, по ее результатам в заголовок главного окна дописывается строка " - Unregistered" или же не дописывается. Теперь посмотрим функцию проверки, приведу ее текст полностью.
  1. CODE:252C8AF0 sub_252C8AF0    proc near
  2. CODE:252C8AF0                 push    ebp
  3. CODE:252C8AF1                 mov     ebp, esp
  4. CODE:252C8AF3                 xor     ecx, ecx
  5. CODE:252C8AF5                 push    ecx
  6. CODE:252C8AF6                 push    ecx
  7. CODE:252C8AF7                 push    ecx
  8. CODE:252C8AF8                 push    ecx
  9. CODE:252C8AF9                 push    ecx
  10. CODE:252C8AFA                 push    ecx
  11. CODE:252C8AFB                 push    ebx
  12. CODE:252C8AFC                 push    esi
  13. CODE:252C8AFD                 push    edi
  14. CODE:252C8AFE                 mov     [ebp+var_4], edx
  15. CODE:252C8B01                 mov     esi, eax
  16. CODE:252C8B03                 xor     eax, eax
  17. CODE:252C8B05                 push    ebp
  18. CODE:252C8B06                 push    offset loc_252C8BDC
  19. CODE:252C8B0B                 push    dword ptr fs:[eax]
  20. CODE:252C8B0E                 mov     fs:[eax], esp
  21. CODE:252C8B11                 xor     ebx, ebx
  22. CODE:252C8B13                 mov     eax, esi
  23. CODE:252C8B15                 call    sub_2520464C
  24. CODE:252C8B1A                 mov     eax, [ebp+var_4]
  25. CODE:252C8B1D                 mov     byte ptr [eax], 0
  26. CODE:252C8B20                 lea     edx, [ebp+var_18]
  27. CODE:252C8B23                 mov     eax, ds:off_252E0F50
  28. CODE:252C8B28                 mov     eax, [eax]
  29. CODE:252C8B2A                 call    sub_2526D39C
  30. CODE:252C8B2F                 mov     eax, [ebp+var_18]
  31. CODE:252C8B32                 lea     edx, [ebp+var_14]
  32. CODE:252C8B35                 call    sub_25209C88
  33. CODE:252C8B3A                 mov     edx, [ebp+var_14]
  34. CODE:252C8B3D                 lea     eax, [ebp+var_8]
  35. ; Проверить наличие файла 
  36. CODE:252C8B40                 mov     ecx, offset aKey_txt ; "\\Key.txt"
  37. CODE:252C8B45                 call    sub_25204968
  38. CODE:252C8B4A                 mov     eax, [ebp+var_8]
  39. CODE:252C8B4D                 call    sub_25209B28
  40. CODE:252C8B52                 test    al, al
  41. CODE:252C8B54                 jz      short loc_252C8BC1
  42. CODE:252C8B56                 mov     ecx, [ebp+var_8]
  43. CODE:252C8B59                 mov     dl, 1
  44. CODE:252C8B5B                 mov     eax, off_25286B64
  45. CODE:252C8B60                 call    sub_25286C14
  46. CODE:252C8B65                 mov     ebx, eax
  47. CODE:252C8B67                 push    0
  48. CODE:252C8B69                 lea     eax, [ebp+var_C]
  49. CODE:252C8B6C                 push    eax
  50. CODE:252C8B6D                 mov     ecx, offset aName ; "Name"
  51. CODE:252C8B72                 mov     edx, offset aKey ; "Key"
  52. CODE:252C8B77                 mov     eax, ebx
  53. CODE:252C8B79                 mov     edi, [eax]
  54. ; Неявный вызов GetPrivateProfileStringA
  55. CODE:252C8B7B                 call    dword ptr [edi]
  56. CODE:252C8B7D                 push    0
  57. CODE:252C8B7F                 lea     eax, [ebp+var_10]
  58. CODE:252C8B82                 push    eax
  59. CODE:252C8B83                 mov     ecx, offset aStr ; "Str"
  60. CODE:252C8B88                 mov     edx, offset aKey ; "Key"
  61. CODE:252C8B8D                 mov     eax, ebx
  62. CODE:252C8B8F                 mov     edi, [eax]
  63. ; Неявный вызов GetPrivateProfileStringA
  64. CODE:252C8B91                 call    dword ptr [edi]
  65. CODE:252C8B93                 mov     eax, ebx
  66. CODE:252C8B95                 call    sub_252037C0
  67. CODE:252C8B9A                 mov     edx, [ebp+var_10]
  68. CODE:252C8B9D                 mov     eax, [ebp+var_C]
  69. ; Вызов функции проверки регистрации
  70. CODE:252C8BA0                 call    sub_252C88A4
  71. CODE:252C8BA5                 mov     ebx, eax
  72. CODE:252C8BA7                 test    bl, bl
  73. CODE:252C8BA9                 jz      short loc_252C8BC1
  74. CODE:252C8BAB                 mov     eax, esi
  75. CODE:252C8BAD                 mov     edx, [ebp+var_C]
  76. CODE:252C8BB0                 call    sub_252046A0
  77. CODE:252C8BB5                 mov     eax, esi
  78. CODE:252C8BB7                 call    sub_252C8AA8
  79. CODE:252C8BBC                 mov     edx, [ebp+var_4]
  80. CODE:252C8BBF                 mov     [edx], al
  81. CODE:252C8BC1 loc_252C8BC1:
  82. CODE:252C8BC1                 xor     eax, eax
  83. CODE:252C8BC3                 pop     edx
  84. CODE:252C8BC4                 pop     ecx
  85. CODE:252C8BC5                 pop     ecx
  86. CODE:252C8BC6                 mov     fs:[eax], edx
  87. CODE:252C8BC9                 push    offset loc_252C8BE3
  88. CODE:252C8BCE loc_252C8BCE:
  89. CODE:252C8BCE                 lea     eax, [ebp+var_18]
  90. CODE:252C8BD1                 mov     edx, 5
  91. CODE:252C8BD6                 call    sub_25204670
  92. CODE:252C8BDB                 retn
  93. CODE:252C8BDC ; --------------------------------------
  94. CODE:252C8BDC loc_252C8BDC:
  95. CODE:252C8BDC                 jmp     loc_25203F68
  96. CODE:252C8BE1 ; --------------------------------------
  97. CODE:252C8BE1                 jmp     short loc_252C8BCE
  98. CODE:252C8BE3 ; --------------------------------------
  99. CODE:252C8BE3 loc_252C8BE3:
  100. CODE:252C8BE3                 mov     eax, ebx
  101. CODE:252C8BE5                 pop     edi
  102. CODE:252C8BE6                 pop     esi
  103. CODE:252C8BE7                 pop     ebx
  104. CODE:252C8BE8                 mov     esp, ebp
  105. CODE:252C8BEA                 pop     ebp
  106. CODE:252C8BEB                 retn
  107. CODE:252C8BEB sub_252C8AF0    endp
Первый и самый простой способ обхода защиты - это патч функции проверки. Как мы знаем из предыдущего кода, в случае корректной регистрации она должна возвращать AL=1. Впечатываем в ее начало пару команд MOV AL,1 и RET, сохраняем изменения.

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

Триальное окно пропало, в заголовке окна больше не показывается "Unregistered", в окне "О программе" отображается бизнес-лицензия, а главное, больше нет ограничений по функционалу. В принципе, цель достигнута. Но можно сделать все красиво, то есть добиться корректной регистрации. Если посмотреть функцию проверки, то там, во-первых, проверяется наличие файла "Key.txt", а во-вторых, из него читаются данные регистрации. Функции чтения данных вызываются неявно, но если посмотреть под отладчикам, то все сводится к обычному вызову GetPrivateProfileStringA. Это значит, что файл "Key.txt" имеет структуру ini-файла с секцией [Key] и параметрами Name и Str. Открываем блокнотик и создаем в нем этот файл, после чего возвращаемся к логу дизассемблера. После чтения из файла регистрационных данных по адресу 252C8BA0 вызывается следующая функция проверки, результат которой влияет на возвращаемое значение. Она тоже не такая большая, приведу ее полностью.
  1. CODE:252C88A4 sub_252C88A4    proc near
  2. CODE:252C88A4                 push    ebp
  3. CODE:252C88A5                 mov     ebp, esp
  4. CODE:252C88A7                 xor     ecx, ecx
  5. CODE:252C88A9                 push    ecx
  6. CODE:252C88AA                 push    ecx
  7. CODE:252C88AB                 push    ecx
  8. CODE:252C88AC                 push    ecx
  9. CODE:252C88AD                 push    ecx
  10. CODE:252C88AE                 push    ebx
  11. CODE:252C88AF                 mov     [ebp+var_8], edx
  12. CODE:252C88B2                 mov     [ebp+var_4], eax
  13. CODE:252C88B5                 mov     eax, [ebp+var_4]
  14. CODE:252C88B8                 call    sub_25204B0C
  15. CODE:252C88BD                 mov     eax, [ebp+var_8]
  16. CODE:252C88C0                 call    sub_25204B0C
  17. CODE:252C88C5                 xor     eax, eax
  18. CODE:252C88C7                 push    ebp
  19. CODE:252C88C8                 push    offset loc_252C89A4
  20. CODE:252C88CD                 push    dword ptr fs:[eax]
  21. CODE:252C88D0                 mov     fs:[eax], esp
  22. CODE:252C88D3                 lea     eax, [ebp+var_4]
  23. CODE:252C88D6                 call    sub_252C87F4
  24. CODE:252C88DB                 mov     eax, [ebp+var_8]
  25. ; Получить длину серийника
  26. CODE:252C88DE                 call    sub_2520491C
  27. CODE:252C88E3                 cmp     eax, 0Eh
  28. CODE:252C88E6                 jnz     short loc_252C88FA
  29. ; Проверить наличие символов "-" на указанных позициях
  30. CODE:252C88E8                 mov     eax, [ebp+var_8]
  31. CODE:252C88EB                 cmp     byte ptr [eax+4], 2Dh
  32. CODE:252C88EF                 jnz     short loc_252C88FA
  33. CODE:252C88F1                 mov     eax, [ebp+var_8]
  34. CODE:252C88F4                 cmp     byte ptr [eax+9], 2Dh
  35. CODE:252C88F8                 jz      short loc_252C88FE
  36. CODE:252C88FA loc_252C88FA:
  37. CODE:252C88FA                 xor     ebx, ebx
  38. CODE:252C88FC                 jmp     short loc_252C8900
  39. CODE:252C88FE ; --------------------------------------
  40. CODE:252C88FE loc_252C88FE:
  41. CODE:252C88FE                 mov     bl, 1
  42. CODE:252C8900 loc_252C8900:
  43. CODE:252C8900                 test    bl, bl
  44. CODE:252C8902                 jz      loc_252C8989
  45. CODE:252C8908                 push    ebp
  46. CODE:252C8909                 lea     eax, [ebp+var_C]
  47. CODE:252C890C                 push    eax
  48. CODE:252C890D                 mov     ecx, 4
  49. CODE:252C8912                 mov     edx, 1
  50. CODE:252C8917                 mov     eax, [ebp+var_8]
  51. CODE:252C891A                 call    sub_25204B7C
  52. CODE:252C891F                 mov     eax, [ebp+var_C]
  53. ; Контрольное значение для первой части серийника
  54. CODE:252C8922                 mov     edx, 1
  55. ; Проверить первую часть серийника
  56. CODE:252C8927                 call    sub_252C8864
  57. CODE:252C892C                 pop     ecx
  58. CODE:252C892D                 test    al, al
  59. CODE:252C892F                 jz      short loc_252C8983
  60. CODE:252C8931                 push    ebp
  61. CODE:252C8932                 lea     eax, [ebp+var_10]
  62. CODE:252C8935                 push    eax
  63. CODE:252C8936                 mov     ecx, 4
  64. CODE:252C893B                 mov     edx, 6
  65. CODE:252C8940                 mov     eax, [ebp+var_8]
  66. CODE:252C8943                 call    sub_25204B7C
  67. CODE:252C8948                 mov     eax, [ebp+var_10]
  68. ; Контрольное значение для второй части серийника
  69. CODE:252C894B                 mov     edx, 2
  70. ; Проверить вторую часть серийника
  71. CODE:252C8950                 call    sub_252C8864
  72. CODE:252C8955                 pop     ecx
  73. CODE:252C8956                 test    al, al
  74. CODE:252C8958                 jz      short loc_252C8983
  75. CODE:252C895A                 push    ebp
  76. CODE:252C895B                 lea     eax, [ebp+var_14]
  77. CODE:252C895E                 push    eax
  78. CODE:252C895F                 mov     ecx, 4
  79. CODE:252C8964                 mov     edx, 0Bh
  80. CODE:252C8969                 mov     eax, [ebp+var_8]
  81. CODE:252C896C                 call    sub_25204B7C
  82. CODE:252C8971                 mov     eax, [ebp+var_14]
  83. ; Контрольное значение для третьей части серийника
  84. CODE:252C8974                 mov     edx, 3
  85. ; Проверить третью часть серийника
  86. CODE:252C8979                 call    sub_252C8864
  87. CODE:252C897E                 pop     ecx
  88. CODE:252C897F                 test    al, al
  89. CODE:252C8981                 jnz     short loc_252C8987
  90. CODE:252C8983 loc_252C8983:
  91. CODE:252C8983                 xor     ebx, ebx
  92. CODE:252C8985                 jmp     short loc_252C8989
  93. CODE:252C8987 ; --------------------------------------
  94. CODE:252C8987 loc_252C8987:
  95. CODE:252C8987                 mov     bl, 1
  96. CODE:252C8989 loc_252C8989:
  97. CODE:252C8989                 xor     eax, eax
  98. CODE:252C898B                 pop     edx
  99. CODE:252C898C                 pop     ecx
  100. CODE:252C898D                 pop     ecx
  101. CODE:252C898E                 mov     fs:[eax], edx
  102. CODE:252C8991                 push    offset loc_252C89AB
  103. CODE:252C8996 loc_252C8996:
  104. CODE:252C8996                 lea     eax, [ebp+var_14]
  105. CODE:252C8999                 mov     edx, 5
  106. CODE:252C899E                 call    sub_25204670
  107. CODE:252C89A3                 retn
  108. CODE:252C89A4 ; --------------------------------------
  109. CODE:252C89A4 loc_252C89A4:
  110. CODE:252C89A4                 jmp     loc_25203F68
  111. CODE:252C89A9 ; --------------------------------------
  112. CODE:252C89A9                 jmp     short loc_252C8996
  113. CODE:252C89AB ; --------------------------------------
  114. CODE:252C89AB loc_252C89AB:
  115. CODE:252C89AB                 mov     eax, ebx
  116. CODE:252C89AD                 pop     ebx
  117. CODE:252C89AE                 mov     esp, ebp
  118. CODE:252C89B0                 pop     ebp
  119. CODE:252C89B1                 retn
  120. CODE:252C89B1 sub_252C88A4    endp
Код я немного прокомментировал, но поясню словами, так как большая часть функционала получена под отладчиком. Сперва проверяется формат серийника. Он должен быть ровно 14 символов и содержать на 4-й и 9-й позиции символы "-". То есть правильный серийник должен иметь вид "XXXX-XXXX-XXXX".
  1. CODE:252C8864 sub_252C8864    proc near
  2. CODE:252C8864                 push    ebp
  3. CODE:252C8865                 mov     ebp, esp
  4. CODE:252C8867                 push    ebx
  5. CODE:252C8868                 push    esi
  6. CODE:252C8869                 mov     esi, edx
  7. CODE:252C886B                 mov     ebx, eax
  8. CODE:252C886D                 mov     eax, [ebp+arg_0]
  9. CODE:252C8870                 mov     eax, [eax-4]
  10. CODE:252C8873                 mov     edx, esi
  11. ; Манипуляции с регистрационным именем
  12. CODE:252C8875                 call    sub_252C8768
  13. CODE:252C887A                 push    eax
  14. CODE:252C887B                 xor     eax, eax
  15. ; Просуммировать символы фрагмента серийника
  16. CODE:252C887D                 mov     al, [ebx]
  17. CODE:252C887F                 xor     edx, edx
  18. CODE:252C8881                 mov     dl, [ebx+1]
  19. CODE:252C8884                 add     eax, edx
  20. CODE:252C8886                 xor     edx, edx
  21. CODE:252C8888                 mov     dl, [ebx+2]
  22. CODE:252C888B                 add     eax, edx
  23. CODE:252C888D                 xor     edx, edx
  24. CODE:252C888F                 mov     dl, [ebx+3]
  25. CODE:252C8892                 add     eax, edx
  26. CODE:252C8894                 pop     edx
  27. ; Разделить на число из регистрационного имени
  28. CODE:252C8895                 mov     ecx, edx
  29. CODE:252C8897                 cdq
  30. CODE:252C8898                 idiv    ecx
  31. CODE:252C889A                 inc     esi
  32. ; Сравнить полученный результат с контрольным значением
  33. CODE:252C889B                 cmp     edx, esi
  34. CODE:252C889D                 setz    al
  35. CODE:252C88A0                 pop     esi
  36. CODE:252C88A1                 pop     ebx
  37. CODE:252C88A2                 pop     ebp
  38. CODE:252C88A3                 retn
  39. CODE:252C88A3 sub_252C8864    endp
Для каждого четырехсимвольного фрагмента серийника выполняется следующая последовательность действий. С частью регистрационного имени производятся некие вычисления, которые дают определенное число. Символы серийника суммируются и делятся на это число. Остаток от деления должен совпадать с контрольным значением, которое передается в эту функцию проверки. Нужная последовательность символов легко подбирается в отладчике, начинаете со строки "1111" и затем просто увеличиваете на единицу любой из ее символов до достижения нужного значения.

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

[Key]
Name=ManHunter / PCL
Str=1112-1116-1111

Запускаем программу и смотрим, что получилось. Тут приведен серийник для моего регистрационного имени, у вас он, естественно, будет другой.

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

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

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

Комментарии

Отзывы посетителей сайта о статье
ManHunter (25.01.2023 в 10:45):
Тут релоков нет, поставил флаг в заголовке и все работает.
pawel97 (25.01.2023 в 07:55):
И поломается файл, ибо релоки применяются, если система грузит его не по своему адресу. Но вопрос же не в этом, просто факт интересный и для чего-то сделано.
А бизнес или сайтовую лицензию можно получить, просто добавив в имя [B] или [S]
ManHunter (24.01.2023 в 23:22):
В заголовке перебить на 400000h и все
pawel97 (24.01.2023 в 22:56):
Вот сколько файлов перековырял под 32 и 64 бита, ImageBase 25200000h ещё не встречал.

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

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

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