Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
выпущен 12 ноября!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

ASProtect - протектор или подставщик?

Обсудить статью на форуме

Массу крэкерских инструментов, видеоуроков и статей вы сможете найти на видеокурсе от нашего сайта. Подробнее здесь.

Автор: dragon <dtdcs@mail.ru>

        Вот попалась мне недавно прога такая, ISO Commander называется, версия 1.1, build 014. Служит она для того, чтобы редактировать любые образы для CD и DVD - .iso, .nrg(Nero burning rom), .cue(CloneCD) и ещё несколько. Просто незаменима для тех, у кого есть рекордер или хотя бы виртуальный CD/DVD. Но у неё есть один, весьма существенный недостаток, требование бабок. Вот его устранением мы сейчас и займёмся. Вот что для этого пригодится:

          SoftIce + IceExt(или IceDump, если всё ещё под своим Win9x/ME сидите.)
          IDA Pro(лучше ничем не заменять!)
          PE Tools by Neox - лучший редактор для PE, который я видел.
          Resource rebuilder by Dr. Golova
          ImpRec
          WinHex, который тоже значительно лучше своих аналогов
          FASM - лучший ассемблер для написания бинарного кода
          MS Spy++, или чего-нибудь подобное(например я для этогу свою прогу накатал)

        По традиции смотрим в PE Sniffer'е, какие штуки использовались для создания и упаковки проги. Оказалось, что упаковщик - ASProtect, причём последней версии, которая из краденых байтов делает зашифрованный полиморфный код.(только не пугайтесь!) Компилятор естесственно не видно, но его можно определить каким-нибудь другим способом, но не сейчас. Итак, часть I - распаковка:

        Как же распаковать эту версию аспра? Да как обычно, найти OEP, снять дамп и восстановить импорт. Не думаю, что какой-нибудь пакер или протектор снимается по-другому. Итак, ищем OEP. Но т.к. нам нужен не только OEP, но и спёртые байты, то придётся идти "пешком". Я здесь не буду рассказывать подробно, если надо, то найдите статью Hex'а про нахождение OEP. Здесь я расскажу лишь в общих чертах, а также, как быстрее искать OEP немного быстрее тем же методом. Как вы наверное знаете, первым делом надо искать создание импорта. Его можно найти, ставя бряки bpx MapViewOfFile, а затем bpx GetProcAddress. Но это же можно сделать короче, зачем лишние бряки нужны? Делаем так, придумываем функцию, которая аспру нафиг не нужна, а проге без неё не обойтись. Взгляд у меня остановился на UpdateWindow. Набираем в WinHex'е это название и выписываем первые 4 байта - 55 70 61 64. Значит в айсе всё будет выглядеть так: bpx GetProcAddress if (@(@(esp+8))==61647055). Вот и сразу попали в искомую процедуру. Найдём теперь IAT, где-то должны быть инструкции вроде:

mov edx, [edi]
mov [edx], eax

Вот здесь можно сделать ed edx и найти начало IAT, должно быть 45С000, значит запомним на будущее, что IAT RVA - 5С000, а то ImpRec не всегда провильно его определяет. Теперь выходим из этой процедуры(ret по адресу B338D1), и начинаем с умеренной скоростью трассировать по F10. Если вдруг вылетите в ntdll, то делаем bpm fs:0, и жмём F5, пока опять не попадаем в прогу.(Так что по F8, как Hex писал, заходить не надо) Так и делаем, пока не видим подряд два ret. После этого надо быть поосторожнее, и смотреть, куда ведёт call. Если слишком близко, то входим в него по F8. Теперь ждём появления таких инструкций:

push DWORD PTR [eax]
push DWORD PTR [ebp-10]
push DWORD PTR [ebp-14]
ret

Теперь записываем где-нибудь этот адрес(должен быть B33D9C) - это переход на последнюю процедуру аспра. Чтобы ещё раз быстро сюда попасть, можно поймать создание импорта и поставить bpm B33D9C x(Только не bpx! Их после срабатывания всегда стирать надо, т.к. аспр целостность кода проверяет) Теперь трассируем только по F8, обходим два цикла, после второго почти сразу ret появится. Жмём на нём F8, и попадаем в тот самый полиморфный код, в котором где-то припрятаны байты с OEP. Что же делать? Ну во-первых остановится(!suspend для IceExt) и снять дамп, пора уже. А теперь сделаем !resume и будем записывать все инструкции, которые выполняются, кроме jmp. Привожу, что у меня получилось(учитывая, что код был у меня по адресу B4651C, но это не так уж важно.)

xor [00B4652A], 0D11 push ebx ;>stack(1)
bswap ebx
lea ebx, [edi+00B4652D]
sub ebx, edi call [ebx+1F] ;>stack(2)
pop ebx ;<stack(2)
xor ebx, [esp+18]
bsf ebx, esp
lea ebx, [ebp*4+1A0C6D19]
pop ebx ;<stack(1)
sub esp, 1B
add esp, 17

xor [00B4658E], 0D11
mov [esp+0], ebp ;push ebp***
mov ebp, esp***
push -1***
push 00461A00***
push 004550EE***
mov eax, [fs:0]***
sub esp, 1B
add esp, 17

xor [00B465BD], 0D11 mov [esp+0], eax ;push eax***
mov [fs:0], esp***
sub esp, 68***
sub esp, 1B
add esp, 17

xor [00B465E2], 0D11
mov [esp+0], ebx ;push ebx***
sub esp, 1B
add esp, 17

xor [00B465FD], 0D11
mov [esp+0], esi ;push esi***
sub esp, 1B
add esp, 17

xor [00B46618], 0D11
mov [esp+0], edi ;push edi***
mov [ebp-18], esp***
xor ebx, ebx***
mov [ebp-4], ebx***
push 2***
xor [00B46637], 8077
push 45512D
push B46485
ret

Я думаю, что в листинге всё понятно. Вообще это хорошо, что такого кода мало, надо думать, как автоматизировать восстановление этих байтов. Ну да ладно. После последнего ret'а попадём на процедуру затирания кода распаковщика, а затем пападём на 45512D. Можно пролистать вверх и убедиться, что OEP - 455100. Теперь начнём очищать дамп от противного кода аспра. Видно, что это две последние секции, но не надо спешить их сразу удалять. Перед ними стоит секция ресурсов, и удалив секции, мы можем вместе с ними удалить и часть директории ресурсов. Сопоставив размеры, убеждаемся, что аспр действительно спёр не только байты с OEP, но и часть ресурсов. Воров принято наказывать, вот и мы это сделаем - берём resource rebuilder by Dr. Golova(спасибо ему большое за эту прогу) и набираем: resrebld dumped.exe(или как вы его там назвали) .rsrc, вот теперь удаляем все три секции вместе с ресурсами и можно сделать Rebuild PE. Только не пытайтесь сейчас этот дамп запускать, не получится. Дальше определяем raw offset, куда засунем в файл ресурсы. берём raw offset предыдущей секции(6A800) и складываем его c размером в файле, т.е. raw size(71CB). В уме это считать тяжеловато, поэтому возьмите лучше калькулятор и посчитайте. Если калькулятор считает правильно, то должно получится 719CB. Учитывая выравнивание секций на 512, получаем 71A00 - смещение будущей секции ресурсов в файле. В WinHex'е заполняем остаток до этого смещения нулями и пишем секцию ресурсов(файл .rsrc) Теперь можно создать в PE редакторе новую секцию с параметрами: RVA=74000, VirtualSize=34000(это размер файла .rsrc), raw offset=71A00, raw size=34000, Characteristics=40000040, и даже можно сделать ещё раз Rebuild PE. Ну сколько же возни с этим аспротектом... Ведь ещё байты в OEP вставлять и импорт восстанавливать... Ну с байтами нет ничего сложного, компилируем все эти инструкции в FASM(или в HIEW, но мне он чего-то не нравится, просто время TEXT MODE закончилось...), в FASM'е не забудьте в начале USE32 написать, и после каждого числа h поставить. Вот и опять WinHex пригодится, считаем raw offset OEP, это 54500(проще всего считать так - 455100-401000(RVA начала секции)+400(raw offset начала секции). Пишем эти байты, и выставляем дампу правильную Entry Point. Всё, теперь можно заняться импортом.

        Запускаем Imprec и ISO Commander. В Imprec'е можно выставить правильную IAT RVA, размер пока не обязательно, просто ставим там какое-нибудь большое число(больше 1000). Потом отрезаем неправильные адреса в конце, таким образом размер будет составлять F9C. В импорте естессвенно много неправильного, но после Trace Level 1 - disasm неправильного осталось мало. Доверять плагину не стоит, он путает некоторые функции, например GetCommandLineA и GetVersion, GetCurrentProcessId и GetCurrentProcess. Поэтому выписываем неправильные адреса - B31578, B31504, B31590, B31568, B3152C, B310B0, И B31560. После внимательно рассмотрения становится видно, что функция по адресу B31578 возвращает адрес, по которому находится командная строка, значит это GetCommandLineA; B31504 - запутанная, но всё же GetModuleHandleA, B3152C возвращает версию Windows(такие числа надо узнавать!), это GetVersion. B310B0 - GetProcAddress с добавкой, сейчас некогда разбираться, а B31560 возвращает какое-то странное число, похожее на ID процесса. Набираем addr и убеждаемся, что это оно и есть, значит наша функция - GetCurrentProcessId. Что за функции находятся по адресам B31590 и B31568 - я до сих пор не въехал. Может кто знает, подскажите. Но что-то с ними надо же делать, вот их код мы прямо в дамп на свободное место и засунем. Сейчас их можно удалить из дерева и восстановить дампу импорт.(Только надо создавать новую IAT, а то две функции не опознались) Теперь ищем в любой секции свободное место(например в .mackt) и пихаем код этих функций туда. по адресу B31590 функция возвращает командную строку и примимает при этом один параметр. это код

call DWORD [004A8124h]
ret 4

Число 4A8124 - адрес, взятый из новой таблицы импорта, которую можно посмотреть в PE Tools. Записываем этот код например по адресу 4AA700, а по адресу 45C150(в IAT) - этот самый адрес, 4AA700.(Это всё конечно же RVA+IMAGE BASE, файловые смещения сами считайте). Аналогично проделываем всё и со второй функцией, которая принимая один параметр, его же и возвращает(???). Распаковка закончена! Теперь часть II - собственно взлом:

Сделаем копию для дизассемблирование и отдаём её IDA на съедение. Сами пока замечаем, что прога вылетает. Вообще айс должен каждый раз вылетать при ошибке, но он вылетел, только когда я первый раз запустил прогу. Я уж чуть не начал вручную искать, где же этот дамп вылетает. Но вдруг обратил внимание на файл test.log, из которого и взял EIP - 77C33714. Авторы сделали такую штуку для устранения багов в программе, но к сожалению для них мы использовали это для взлома. Теперь ставим бряк на этот адрес, и смотрим, что что-то читается с адреса B23951. Смотрим в стеке адрес, откуда вызывается эта функция, оказалось, что с адреса 42C886. Смотрим в IDA, по названию и дурак поймет, что это функция сравнения строк. И интересно, что если строки совпадают, то мы проскакиваем функцию диалога DoModal, т.е. появления на экране диалога about. А что же это значит? А значит то, что аспр считай сам указал нам путь ко взлому!!! Вот тебе и протектор! Программеры, подумайте, прежде чем им пользоваться... Так вот, составляем список, где же проверяется регистрация, для этого смотрим Cross references на адрес 46F0C4. Нам нужны адреса call'ов на strcmp. Вот и они(CTRL+X на 46F0C4 и смотрим чуть ниже): 42C830, 42C886, 42E219, 443BC2, 443C9F, 44483E. Высчитываем raw offset'ы и заменяем call'ы на

xor eax, eax
inc eax
nop
nop

Опкоды - 33 C0 40 90 90. Такие тоже знать надо. Всё, прога полностью функционирует. Единственное, что не в порядке, так это about диалог. Не закрывается по кнопке OK(хотя по ALT+F4 закрывается), не показывается имя. Я не буду приводить здесь, как это исправить. Ну например можно переопределить процедуру окна у уничтожать его по нажатию на кнопку, по адресу 42BB5F вписать push 0E вместо push 0F, и.т.д. Надеюсь вам удасться привести в порядок этот диалог, как это удалось мне. Ну чтож, надеюсь, что вам эта программа пригодится, согласитесь, все же она не плохая.

        Программеры, если вы читали эту статью, подумайте, прежде чем использовать протекторы, не сделав собственной защиты. ISO Commander тому пример.

автор: dragon, который естесственно не несёт ответственности за противозаконное использование данных материалов.
мылить сюда: dtdcs@mail.ru

1 июля 2003 г.

Обсуждение статьи: ASProtect - протектор или подставщик? >>>


Материалы находятся на сайте https://exelab.ru



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS