Исследование защиты программы Privacy Inspector
Скриншот программы Privacy Inspector
Privacy Inspector - стотыщпицотмильённый супер-мега-твикер-клинер вашей системы, который, конечно же, лучше всех сохранит вашу приватность и уничтожит персональные данные, накопленные в процессе работы за компьютером, временные файлы, очистит корзину и любезно выполнит еще много всяких действий. Но вот только делает он всю эту даром никому не нужную чушь совсем не даром, за лицензию требуется выложить некоторую сумму вечнозеленых денег.
Начинаем со скачивания дистрибутива. Устанавливаем, смотрим. По всем признакам исполняемый файл накрыт пакером PECompact. Можно воспользоваться какой-нибудь готовой утилитой для его снятия, но больше пользы будет, если распаковать его ручками. Загружаем файл в отладчик, но не запускаем.
Установка SEH-кадра
В PECompact используется антиотладочный трюк, основанный на установке SEH-кадра, адрес которого является адресом перехода на следующий код. Более подробно можете посмотреть здесь. В регистр EAX заносится адрес перехода, затем выполняется запись в запрещенный участок памяти, срабатывает обработчик ошибок и управление передается на адрес перехода.
Адрес перехода из SEH
Поставим сюда точку останова и запустим программу. Если сработает исключение (а оно сработает), то надо принудительно продолжить исполнение программы в обход исключения (Shift+F9).
Переход на OEP
Проматываем пару экранов вниз, пока не доберемся до характерной команды JMP EAX, после которой следует куча нулевых байт. Это и есть переход на OEP. Ставим точку останова на JMP EAX и снова запускаем программу.
OEP
После срабатывания точки останова делаем одну пошаговую трассировку и попадаем на OEP. Все, программа готова для снятия дампа и восстановления импорта.
Делаем дамп
Делаем дамп. Я использую для этого плагин OllyDump, но никто не мешает использовать для этого какие-нибудь другие инструменты, суть от этого не меняется.
Загружаем таблицу импорта
Ищем и загружаем таблицу импорта. Адрес OEP вычисляется вычитанием базы кода из виртуального адреса OEP (00428A01 - 00400000 = 28A01), подставляем его в ImpREC, дальше два клика на "IAT AutoSearch" и "Get Imports". таблица импорта не повреждена, можно сразу же прикручивать ее к дампу.
Исправляем дамп
Клик на "Fix Dump", выбираем созданный файл дампа и через пару секунд получаем полностью распакованный и работоспособный файл. Точно по такому же алгоритму распаковываются и другие файлы, накрытые PECompact. На описание ушло гораздо больше времени, чем на саму распаковку.
Все навесы с файла сняты, можно отправлять распакованный и восстановленный файл в дизассемблер. Регистрация работает следующим образом: программа принимает любой серийный номер, но после этого требует перезапуск. Никаких сообщений о правильности и неправильности введенных данных не выводится. Ориентироваться можно только по надписям, например, в заголовке. В файле ничего подобного не нашлось, зато нашлось в языковом файле English.ini в папке \Language. Надпись, которая выводится в заголовок, состоит из нескольких частей.
IDS_SUBMAIN1=(Unregistered - Day
IDS_SUBMAIN2=of 15)
IDS_SUBMAIN3=(Function-Limited)
Значит надо искать не сами строки, а их индексы. По первому же индексу обнаружится вот такой код:
Code (Assembler) : Убрать нумерацию
- ; Проверить значение в ячейке памяти
- .text:0041C190 cmp dword_469DA4, ebx
- .text:0041C196 jnz short loc_41C1A9
- ; Если оно не нулевое, то перейти на добавление в заголовок плохих надписей
- .text:0041C198 push offset Caption ; "Privacy Inspector"
- .text:0041C19D mov ecx, esi
- .text:0041C19F call sub_43D788
- .text:0041C1A4 jmp loc_41C33F
- .text:0041C1A9 ; --------------------------------------------------------
- .text:0041C1A9 loc_41C1A9:
- .text:0041C1A9 mov eax, dword_469DA8
- .text:0041C1AE lea ecx, [esp+0Ch]
- .text:0041C1B2 push ecx
- .text:0041C1B3 push ecx
- .text:0041C1B4 test eax, eax
- .text:0041C1B6 mov ecx, esp
- .text:0041C1B8 jnz loc_41C2DF
- .text:0041C1BE mov [esp+2Ch], esp
- ; Загрузить строку по индексу
- .text:0041C1C2 push offset aIds_submain1 ; "IDS_SUBMAIN1"
- .text:0041C1C7 call sub_439BD0
- .text:0041C1CC push ecx
- .text:0041C1CD mov byte ptr [esp+3Ch], 2
- .text:0041C1D2 mov ecx, esp
- .text:0041C1D4 mov [esp+2Ch], esp
- .text:0041C1D8 push offset aMain ; "Main"
- .text:0041C1DD call sub_439BD0
Code (Assembler) : Убрать нумерацию
- .text:0041955D push ecx
- .text:0041955E mov ecx, ebx
- ; Вызвать функцию проверки
- .text:00419560 call sub_419DB0
- .text:00419565 test eax, eax
- ; По ее результатам записать в переменную 0 или 1
- .text:00419567 jz short loc_41957B
- .text:00419569 mov eax, [ebp+lpszUrl]
- .text:0041956C mov dword_469DA4, 1
- .text:00419576 cmp eax, 4
- .text:00419579 jnb short loc_419585
- .text:0041957B loc_41957B:
- .text:0041957B mov dword_469DA4, 0
- .text:00419585 loc_419585:
- .text:00419585 lea edx, [ebp+var_128]
- .text:0041958B mov ecx, ebx
- .text:0041958D push edx
- ; Вызвать еще одну функцию проверки
- .text:0041958E call sub_41A110
- .text:00419593 test eax, eax
- ; Если она вернула 0, то перезаписать переменную этим нулевым значением
- .text:00419595 jnz loc_419715
- .text:0041959B push eax
- .text:0041959C lea ecx, [ebp+var_11F8]
- .text:004195A2 mov dword_469DA4, eax
- .text:004195A7 call sub_41CB00
- .text:004195AC lea ecx, [ebp+var_11F8]
- .text:004195B2 mov byte ptr [ebp+var_4], 0Bh
Code (Assembler) : Убрать нумерацию
- .text:0041A110 mov eax, 2264h
- .text:0041A115 call __alloca_probe
- .text:0041A11A mov ax, word_464AA8
- .text:0041A120 push ebx
- .text:0041A121 push esi
- .text:0041A122 push edi
- .text:0041A123 mov word ptr [esp+2270h+var_2262], ax
- .text:0041A128 mov ecx, 226h
- .text:0041A12D xor eax, eax
- .text:0041A12F lea edi, [esp+2270h+var_1130]
- .text:0041A136 rep stosd
- .text:0041A138 mov ecx, 226h
- .text:0041A13D lea edi, [esp+2270h+var_2260]
- .text:0041A141 rep stosd
- .text:0041A143 mov ecx, 226h
- .text:0041A148 lea edi, [esp+2270h+var_19C8]
- .text:0041A14F rep stosd
- .text:0041A151 mov ecx, 226h
- .text:0041A156 lea edi, [esp+2270h+var_898]
- .text:0041A15D rep stosd
- .text:0041A15F or ecx, 0FFFFFFFFh
- .text:0041A162 mov edi, offset aDcji77cfDf1g75
- ; "DCJI77CF,DF1G752F,GGD24KF7,9FGKD85H,88H"...
- .text:0041A167 repne scasb
- .text:0041A169 not ecx
- .text:0041A16B sub edi, ecx
- .text:0041A16D lea edx, [esp+2270h+var_1130]
- .text:0041A174 mov eax, ecx
- .text:0041A176 mov esi, edi
- .text:0041A178 shr ecx, 2
- .text:0041A17B mov edi, edx
- .text:0041A17D lea edx, [esp+2270h+var_2260]
- .text:0041A181 rep movsd
- .text:0041A183 mov ecx, eax
- .text:0041A185 xor eax, eax
- .text:0041A187 and ecx, 3
- .text:0041A18A rep movsb
- .text:0041A18C mov edi, offset aNbgd3eeqEb3hme
- ; "NBGD3EEQ,EB3HMEQM,C3GH7N3F,IIE3D7HI,BHV"...
- .text:0041A191 or ecx, 0FFFFFFFFh
- .text:0041A194 repne scasb
- .text:0041A196 not ecx
- .text:0041A198 sub edi, ecx
- .text:0041A19A mov eax, ecx
- .text:0041A19C mov esi, edi
- .text:0041A19E mov edi, edx
- .text:0041A1A0 lea edx, [esp+2270h+var_19C8]
- .text:0041A1A7 shr ecx, 2
- .text:0041A1AA rep movsd
- .text:0041A1AC mov ecx, eax
- .text:0041A1AE xor eax, eax
- .text:0041A1B0 and ecx, 3
- .text:0041A1B3 rep movsb
- .text:0041A1B5 mov edi, offset aBqjgbbej5548zg
- ; "BQJGBBEJ,5548ZGB3,5HHF5BIM,2JJE3GZJ,GFB"...
- .text:0041A1BA or ecx, 0FFFFFFFFh
- .text:0041A1BD repne scasb
- .text:0041A1BF not ecx
- .text:0041A1C1 sub edi, ecx
- .text:0041A1C3 mov eax, ecx
- .text:0041A1C5 mov esi, edi
- .text:0041A1C7 mov edi, edx
- .text:0041A1C9 lea edx, [esp+2270h+var_898]
- .text:0041A1D0 shr ecx, 2
- .text:0041A1D3 rep movsd
- .text:0041A1D5 mov ecx, eax
- .text:0041A1D7 xor eax, eax
- .text:0041A1D9 and ecx, 3
- .text:0041A1DC rep movsb
- .text:0041A1DE mov edi, offset aMmv7mb1eGfgj5g
- ; "MMV7MB1E,GFGJ5GJ7,7JDEE6EB,NMHJ12A1,DAA"...
- .text:0041A1E3 or ecx, 0FFFFFFFFh
- .text:0041A1E6 repne scasb
- .text:0041A1E8 not ecx
Программа успешно зарегистрирована
Осталось непонятным, для чего нужно было делить список серийников на несколько частей? Это абсолютно точно не проказы компилятора, так написана исходная программа. И зачем пускать реверсера по ложному следу с генерацией фейкового серийника, если несколькими строчками ниже эта ловушка сама себя нейтрализует? Навесной пакер используется, по всей видимости, чтобы спрятать весь этот ужоснах от глаз посторонних. Кейген же сводится к выбору случайного серийника из списка валидных. Точно так же обходятся защиты остальных программ разработчика, там только набор серийников будет другой. Хотя назвать это защитами можно только с большой натяжкой. Зато немного попрактиковались в ручной распаковке.
Просмотров: 2266 | Комментариев: 11
Метки: исследование защиты
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(26.10.2017 в 08:26):
В этом разделе софт появляется не потому что он такой распрекрасный, а потому что можно потренироваться на реальных примерах вместо синтетических крякмисов.
xussr
(26.10.2017 в 06:57):
Где ты откапал это овно на редкость ....неушто больше софта нет .Утиль кто вооще такое качает
ManHunter
(10.10.2017 в 14:20):
И никогда не будет.
ромка
(10.10.2017 в 13:23):
шикарный блог, только нет поля для емейлов чтоб уведомления приходили.
ManHunter
(07.10.2017 в 16:13):
Нет желания правила почитать?
pc
(07.10.2017 в 13:33):
нет желания исследовать вот эту поделку ?
hxxp://www.lab128.com/lab128_download.html
было бы интересно почитать
hxxp://www.lab128.com/lab128_download.html
было бы интересно почитать
Noobie
(06.10.2017 в 12:13):
Программа - 100% барахло, а вот описание весьма полезно для раздумий и тренировок по части анпака, за что и выражаю благодарность ManHunter.
xussr
(05.10.2017 в 20:30):
Про ресурсы понятноа а функионал скудный это точно..лучшее это Auslogics BoostSpeed v5 а это очередной клон и не самый продвинутый даж не интересно как и чем ее лечить
Bannan
(05.10.2017 в 14:01):
Про приведение ресурсов в нормальный вид, рассказывал vnekrilov (CRACKL@B) в своих статьях по распаковке Asprotect. Смысл в чем. Прежде чем прикручивать импорт, в файле дампа удаляются все секции, связанные с пакером, в том числе и секция ресурсов. После восстановления импорта секция ресурсов прикручивается обратно.
Но как и написал ManHunter, юзверю абсолютно по-барабану, гланое что работает. Единственное, кому это может доставить неудобство, так это локализаторщику.
ManHunter
(05.10.2017 в 00:00):
Перфекционизм не всегда хорошо. По большому счету конечному юзеру начхать, сколько весит поломанный файл, главное, что софтина работает и не требует денег. Лично я никогда не заморачивался на тему отрезания дублей ресурсов, в крайнем случае ненужный участок можно тупо забить нулями и потом упаковать отломанный файл.
pawel97
(04.10.2017 в 23:24):
По мне, лучше Auslogics BoostSpeed v5 (именно 5 версия) ничего лучше так и не придумали. Чистка в 1 клик на любителя, а вот удобнейший твикер и советник - вещь. Всё по категориям, с описаниями, на русском (не гуглтранслейт). Конечно, он тоже не бесплатен...
Что по основной теме, будет ну прям очень полезно, если расскажете про приведение ресурсов в нормальный вид после ентого PECompact. Разумеется, если секция ресурсов под 10 МБ, чтобы она не дублировалась в файле дважды. Пример упакованной жертвы с жирной секцией ресурсов дам, если не будет бан. Анпакер это решает, но мы же сами хотим :)
Импорт же восстанавливаю scylla - импрек под 7-ками рисует в импорте всякие api-ms-win, после чего анпакнутый файл не пашет в xp.
Что по основной теме, будет ну прям очень полезно, если расскажете про приведение ресурсов в нормальный вид после ентого PECompact. Разумеется, если секция ресурсов под 10 МБ, чтобы она не дублировалась в файле дважды. Пример упакованной жертвы с жирной секцией ресурсов дам, если не будет бан. Анпакер это решает, но мы же сами хотим :)
Импорт же восстанавливаю scylla - импрек под 7-ками рисует в импорте всякие api-ms-win, после чего анпакнутый файл не пашет в xp.
Добавить комментарий
Заполните форму для добавления комментария