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

BWMeter от DeskSoft - одна из лучших программ для подсчета трафика на локальном компьютере. При помощи BWMeter можно раздельно считать внутрисетевой или же исходящий/входящий интернет-трафик. Присутствуют настраиваемые фильтры, отчеты можно представлять как в цифровом, так и в графическом виде. Также BWMeter может служить в качестве ограничителя скорости при различных условиях.


Скриншот программы BWMeter

Но при всех многочисленных достоинствах у программы есть один большой недостаток: она стоит $30 и работает в ознакомительном режиме 30 дней. Что ж, придется исправлять эту ошибку автора.

Дистрибутив последней на момент публикации версии BWMeter 4.0.8 можно скачать с офсайта (около 600 килобайт). Установим программу и приступим к изучению ее внутренностей. Когда-то давно в интернете выкладывали одну валидную лицензию, все данные регистрации в ней основаны на криптографических алгоритмах, так что про подбор и генерацию ключей можно сразу забыть. Придется вносить изменения в программный код. Файл лицензии имел расширение "dlc", попробуем поискать эту строчку в исполняемом файле. Найдется только одно вхождение.


Поиск строки расширения

Там же рядом видны строки, очень похожие на фрагменты из лицензии, но они нас не интересуют. Посмотрим в дизассемблере код, который ссылается на строку "dlc".
.text:00425C90 ; int __cdecl sub_425C90(char ArgList)
.text:00425C90 sub_425C90      proc near               ; CODE XREF: sub_425D80+2B
.text:00425C90                                         ; sub_425D80+47
.text:00425C90
.text:00425C90 Dst             = byte ptr -464h
.text:00425C90 var_10          = dword ptr -10h
.text:00425C90 var_C           = dword ptr -0Ch
.text:00425C90 var_4           = dword ptr -4
.text:00425C90 ArgList         = byte ptr  4
.text:00425C90
.text:00425C90                 push    0FFFFFFFFh
.text:00425C92                 push    offset loc_44B3CB
.text:00425C97                 mov     eax, large fs:0
.text:00425C9D                 push    eax
.text:00425C9E                 sub     esp, 458h
.text:00425CA4                 mov     eax, dword_477EA0
.text:00425CA9                 xor     eax, esp
.text:00425CAB                 mov     [esp+464h+var_10], eax
.text:00425CB2                 mov     eax, dword_477EA0
.text:00425CB7                 xor     eax, esp
.text:00425CB9                 push    eax
.text:00425CBA                 lea     eax, [esp+468h+var_C]
.text:00425CC1                 mov     large fs:0, eax
.text:00425CC7                 mov     eax, dword ptr [esp+468h+ArgList]
.text:00425CCE                 push    offset aDlc     ; "dlc"
.text:00425CD3                 push    eax             ; ArgList
.text:00425CD4                 lea     eax, [esp+470h+Dst]
.text:00425CD8                 push    offset aS_S     ; "%s\*.%s"
.text:00425CDD                 push    eax             ; Dst
.text:00425CDE                 call    sub_42C920
.text:00425CE3                 add     esp, 10h
.text:00425CE6                 lea     ecx, [esp+468h+Dst] ; int
.text:00425CEA                 mov     [esp+468h+var_4], 0
.text:00425CF5                 call    sub_42CB00
.text:00425CFA                 test    al, al
.text:00425CFC                 jz      short loc_425D24
.text:00425CFE                 mov     edi, edi
.text:00425D00
.text:00425D00 loc_425D00:                             ; CODE XREF: sub_425C90+92
.text:00425D00                 lea     ecx, [esp+468h+Dst]
.text:00425D04                 call    sub_42C9A0
.text:00425D09                 push    eax             ; lpFileName
.text:00425D0A                 call    sub_4258B0
.text:00425D0F                 add     esp, 4
.text:00425D12                 lea     ecx, [esp+468h+Dst] ; int
.text:00425D16                 cmp     eax, 1
.text:00425D19                 jz      short loc_425D5E
.text:00425D1B                 call    sub_42CB00
.text:00425D20                 test    al, al
.text:00425D22                 jnz     short loc_425D00
.text:00425D24
.text:00425D24 loc_425D24:                             ; CODE XREF: sub_425C90+6C
.text:00425D24                 lea     ecx, [esp+468h+Dst]
.text:00425D28                 mov     [esp+468h+var_4], 0FFFFFFFFh
.text:00425D33                 call    sub_42CA00
.text:00425D38                 xor     al, al
.text:00425D3A
.text:00425D3A loc_425D3A:                             ; CODE XREF: sub_425C90+E0
.text:00425D3A                 mov     ecx, [esp+468h+var_C]
.text:00425D41                 mov     large fs:0, ecx
.text:00425D48                 pop     ecx
.text:00425D49                 mov     ecx, [esp+464h+var_10]
.text:00425D50                 xor     ecx, esp
.text:00425D52                 call    sub_435EAC
.text:00425D57                 add     esp, 464h
.text:00425D5D                 retn
.text:00425D5E ; ---------------------------------------------------------------
.text:00425D5E
.text:00425D5E loc_425D5E:                             ; CODE XREF: sub_425C90+89
.text:00425D5E                 mov     [esp+468h+var_4], 0FFFFFFFFh
.text:00425D69                 call    sub_42CA00
.text:00425D6E                 mov     al, 1
.text:00425D70                 jmp     short loc_425D3A
.text:00425D70 sub_425C90      endp

Под отладчиком можно протрассировать эту процедуру и выяснить, что здесь ищутся все файлы с расширением *.dlc, и в случае если такие файлы будут найдены, то с ними последовательно выполняются какие-то проверки. Из процедуры при разных условиях в регистре AL возвращается два значения - 0 в случае если не найдено ни одной валидной лицензии и 1 в случае если программа зарегистрирована. Не будем мудрить и просто пропишем в начало функции по адресу 00425C90 две последовательные ассемблерные команды MOV AL,1 и RET. Теперь при любом раскладе программа будет считать себя зарегистрированной и это подтверждается окном "About".


Программа считает себя зарегистрированной

То, что нет имени и типа лицензии вполне логично, ведь мы даже не проверяли ни одного файла с регистрационными данными. Но это нас волновать не должно, ведь программа работает почти без нареканий. Почему почти? Потому что, несмотря на внешнюю "зарегистрированность", ровно через 30 дней при старте BWMeter мы получим вот такое неприятное окно:


Лицензия закончилась

Попытки найти эту строку в файле терпят неудачу, автор предусмотрительно зашифровал все текстовые строки, так или иначе сигнализирующие о состоянии регистрации программы. Ничего страшного, запускаем отладчик. Пошаговой трассировкой добираемся до места, где расшифровывается строка и выводится окно. Перед ним выполняется очень интересная проверка:
00422893   |.  C687 42020000 00        MOV BYTE PTR DS:[EDI+242],0
0042289A   |.  84DB                    TEST BL,BL
0042289C   |.  75 0A                   JNZ SHORT 004228A8
                                       ; 1Eh = 30 в десятичной системе
0042289E   |.  837D 00 1E              CMP DWORD PTR SS:[EBP],1E
                                       ; Переход если меньше или равно
004228A2       0F86 79010000           JBE 00422A21
                                       ; Этот код выводит "нехорошее" окно
004228A8   |>  68 04010000             PUSH 104
004228AD   |.  8D5424 68               LEA EDX,DWORD PTR SS:[ESP+68]
004228B1   |.  52                      PUSH EDX
004228B2   |.  6A 00                   PUSH 0

То есть выполняется сравнение какого-то счетчика с числом 30, а это и есть количество дней триального срока. Если счетчик превысил это значение, то выводится окно. Чтобы обойти проверку достаточно изменить условный переход JBE по адресу 004228A2 на безусловный переход JMP. Сохраняем изменения, запускаем, все работает как часики. Именно это нам и требовалось. Этот способ снятия защиты работает на всех версиях BWMeter, но естественно, что в разных версиях программы все адреса памяти будут отличаться. А на сэкономленную тридцатку баксов идем пить пиво.
Теги:
защита, взлом
Добавлено: 21 Сентября 2013 05:13:01 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...