
Исследование защиты программы AppToService
AppToService от Basta Computing - полезная программа, позволяющая запускать любые приложения как сервисы Windows. Но, как и большинство полезных программ, требует денег после испытательного срока. Будем это исправлять. Скачать пациента можно с офсайта, последняя версия на сегодняшний день 3.0. После установки запускаем программу, видим список параметров запуска и нехорошую строчку, предупреждающую, что надо бы заплатить.
Скриншот программы AppToService
Если посмотреть повнимательнее, то там же будет ключ командной строки для регистрации:
/Key:x Unlock AppToService.
Программа написана на C++ и ничем не упакована. Сперва попробуем найти строчку с ключом "Key:" и посмотреть как она обрабатывается. Строка в юникоде, поэтому символы разделены нулевым байтом. Участок кода, где идет обращение к этой строке, будет только один.
Code (Assembler) : Убрать нумерацию
- .text:00403074 mov edx, offset aKey ; "Key:"
- .text:00403079 call sub_402BE0
- .text:0040307E add esp, 4
- .text:00403081 test eax, eax
- ; Если параметр в командной строке не равен "Key:", то перейти дальше
- .text:00403083 jz short loc_4030E7
- .text:00403085 or dword ptr [esp+10h], 2
- .text:0040308A call sub_40A54B
- .text:0040308F mov eax, [eax+4]
- .text:00403092 lea ecx, [esp+46h]
- .text:00403096 push ecx
- .text:00403097 add eax, 0A4h
- .text:0040309C push eax
- ; Вот это интересная функция, похоже тут проверяется валидность ключа, и
- ; в зависимости от результатов выполняется прыжок на выход или сообщение об
- ; успешной регистрации программы
- .text:0040309D call sub_4017B0
- .text:004030A2 test eax, eax
- .text:004030A4 jz loc_403B0D
- .text:004030AA call sub_40A54B
- .text:004030AF mov eax, [eax+4]
- ; Установить флажок зарегистрированности
- .text:004030B2 mov dword ptr [eax+0C0h], 1
- .text:004030BC call sub_40A54B
- .text:004030C1 mov eax, [eax+4]
- .text:004030C4 lea ecx, [eax+0CCh]
- .text:004030CA call sub_402590
- ; Вывести на экран сообщение об удачной регистрации
- .text:004030CF push offset aOk ; "OK\n"
- .text:004030D4 mov dword_4402AC, ebx
- .text:004030DA call sub_413BCB
- .text:004030DF add esp, 4
- ; И потом пойти куда-то дальше, это нам уже не очень интересно
- .text:004030E2 jmp loc_403A95
Code (Assembler) : Убрать нумерацию
- .text:004019CD sar eax, 1
- .text:004019CF lea ecx, [eax+eax+2]
- .text:004019D3 push ecx ; cbData
- .text:004019D4 push edi ; lpData
- .text:004019D5 push 1 ; dwType
- .text:004019D7 push 0 ; Reserved
- .text:004019D9 push offset aReserved2 ; "Reserved2"
- .text:004019DE push esi ; hKey
- .text:004019DF call ds:RegSetValueExW
- .text:004019E5 push esi ; hKey
- .text:004019E6 mov edi, eax
- .text:004019E8 call ds:RegCloseKey
- .text:004019EE push edi ; dwErrCode
- .text:004019EF call ds:SetLastError
Code (Assembler) : Убрать нумерацию
- .text:004013AE xor eax, esp
- .text:004013B0 push eax
- .text:004013B1 lea eax, [esp+54h+var_C]
- .text:004013B5 mov large fs:0, eax
- .text:004013BB mov eax, offset aReserved2 ; "Reserved2"
- .text:004013C0 lea esi, [esp+54h+var_48]
- .text:004013C4 mov ecx, edi
- ; Где-то тут читается значение ключа из реестра
- .text:004013C6 call sub_401000
- .text:004013CB xor ebx, ebx
- .text:004013CD mov [esp+54h+var_4], ebx
- .text:004013D1 call loc_401160
- .text:004013D6 lea eax, [esp+54h+Data]
- .text:004013DA push eax
- .text:004013DB mov eax, [esp+58h+var_48]
- .text:004013DF mov dword ptr [esp+58h+Data], ebx
- ; Тут вызывается проверка валидности ключа
- .text:004013E3 call sub_4074F0
- .text:004013E8 add esp, 4
- .text:004013EB test eax, eax
- ; Если проверка не пройдена, то переход
- .text:004013ED jz short loc_4013FA
- ; Тут какая-то дополнительная проверка данных из ключа
- .text:004013EF xor eax, eax
- .text:004013F1 cmp dword ptr [esp+54h+Data], ebx
- ; Регистр AL устанавливается в зависимости от результатов проверки.
- ; 0 - все плохо, 1 - программа зарегистрирована
- .text:004013F5 setnl al
- .text:004013F8 jmp short loc_4013FC
- .text:004013FA loc_4013FA:
- ; Сюда мы попадаем, если ключ регистрации не найден или он неправильный
- .text:004013FA xor eax, eax
- .text:004013FC loc_4013FC:
- .text:004013FC cmp eax, ebx
- ; Сохранить куда-то в память флажок "зарегистрировано"
- .text:004013FE mov [edi+1Ch], eax
- ; Переход, если программа не зарегистрирована
- .text:00401401 jz short loc_401424
- .text:00401403 mov [esp+54h+var_4], 0FFFFFFFFh
- .text:0040140B mov eax, [esp+54h+var_48]
- .text:0040140F add eax, 0FFFFFFF0h
- .text:00401412 lea ecx, [eax+0Ch]
- .text:00401415 or edx, 0FFFFFFFFh
- .text:00401418 lock xadd [ecx], edx
- .text:0040141C dec edx
- .text:0040141D test edx, edx
- .text:0040141F jmp loc_401589
- .text:00401424 loc_401424:
- ; Программа не зарегистрирована, вычисляется триальный срок и записывается
- ; в другой ключ реестра - "Reserved0"
- .text:00401424 push ebx ; Time
- .text:00401425 call __time64
- .text:0040142A add esp, 4
- .text:0040142D push ebx ; dwDisposition
- .text:0040142E mov ebx, edi
- .text:00401430 mov [esp+58h+var_3C], eax
- .text:00401434 mov [esp+58h+var_38], edx
- .text:00401438 call sub_406700
- .text:0040143D mov esi, eax
- .text:0040143F test esi, esi
- .text:00401441 jz short loc_40147A
- .text:00401443 push 0 ; lpcbData
- .text:00401445 push 0 ; lpData
- .text:00401447 push 0 ; lpType
- .text:00401449 push 0 ; lpReserved
- .text:0040144B push offset aReserved0 ; "Reserved0"
- .text:00401450 push esi ; hKey
- .text:00401451 call ds:RegQueryValueExW
- .text:00401457 push esi ; hKey
- .text:00401458 mov ebx, eax
- .text:0040145A call ds:RegCloseKey
- .text:00401460 push ebx ; dwErrCode
Code (Assembler) : Убрать нумерацию
- .text:004013EB test eax, eax
- ; Заменить JZ на JMP, теперь переход будет выполняться в любом случае
- .text:004013ED jz short loc_4013FA ; <-- JMP
- .text:004013EF xor eax, eax
- .text:004013F1 cmp dword ptr [esp+54h+Data], ebx
- .text:004013F5 setnl al
- .text:004013F8 jmp short loc_4013FC
- .text:004013FA loc_4013FA:
- ; Сюда будет выполняться переход после патча. В регистре EAX должно быть
- ; ненулевое значение, тогда программа будет считать, что она зарегистрирована.
- ; Размер команды XOR EAX,EAX равен 2 байта, проще всего заменить ее на MOV AL,1
- .text:004013FA xor eax, eax ; <-- MOV AL,1

Программа успешно "зарегистрирована"
Очередной гвоздь в гроб капитализма забит, теперь программа будет работать без всяких ограничений по времени. А на сэкономленные деньги покупаем букет любимой девушке :)
Просмотров: 8480 | Комментариев: 7
Метки: исследование защиты

Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
DT
(24.08.2011 в 19:51):
СПС! Решение воркает и по сей день :)

ManHunter
(04.09.2009 в 12:30):
Это просто для примера

Kemper
(04.09.2009 в 10:55):
бесплатные аналоги предлагать? ) - или это просто для примера ?

sasha
(05.06.2009 в 21:41):
молоток!))

Шурик
(20.03.2009 в 23:52):
i like it

ManHunter
(10.03.2009 в 17:51):
Распространение патчей попадает под действие ст.273 УК РФ, так что никаких готовых патчей на этом сайте не будет. Кто хочет - сам сделает, под свою ответственность.

ratatui
(10.03.2009 в 17:39):
а мона патчег? :)

Добавить комментарий
Заполните форму для добавления комментария
