Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

Subj: Как взломать Emulated Solar CPU_________



Это очень нетривиальный CrackMe и очень приятный. Ломается, правда, просто, но не всеми. Этот опус меня побудил написать один мой знакомый, который уже неделю его копает.

Все-таки математику и хакерам знать не помешает, хотя бы на уровне популяр­ных книжек. В эмуляторе используются только основы булевой алгебры, которые (если я не ошибаюсь) входят и в программу школьного курса информатики.

Solar Designer пишет:

Ø Ну, кто сломает мое творение?;) Кода 80х86 — меньше 100 байт.

Ø Шифрованного кода нет. Защиты от отладки тоже нет.

Ø Пароль сознательно зашифрован так, чтобы можно было разобравшись в коде его

Ø проверки, вычислить подходящий. И тем не

Ø менее сломать будет непросто.;)

Тем не менее сломать просто, и даже очень просто! Ну-с, начнем... Как уже понятно, нам придется иметь дело с эмулятором. Или интерпретатором, кому как больше нравится. Никаких конвейеров, циклов выборки, распараллеленных де­шифраторов команд нет, т.е. приятного особо не много. Минимально рабочий интерпретатор а-ля риск с фиксированной длиной и адресацией всех команд.

Но что примечательно, так это необычная архитектура. Не Фон-Нейманов­ская. Исполняемый код и данные перемешаны. Правда, реализация не очень аккуратная и навешано очень много заплаток 186, что портит все удовольствие и сводит сложность взлома к нулю.

Далее, автор думает, что...

Ø В защитах я такого не встречал, а ведь именно в них это

Ø полезно, т.к. не дает возможности полной декомпиляции из-за невозможности

Ø распознать границы команд более высокого уровня (в данном случае они были

Ø на макросах).

Математику знать надо. А+В+С == (А+В)+С во всяком случае. Чем мы ниже с успехом и воспользуемся. Я думаю, что стрелка Пирса — это не самое лучшее для затруднения декомпиляции. А вот скорость замедляет изрядно. И серьезная защита будет сильно "тормозить". А что булевы термы ассоциативны, надо все же иногда иметь в виду.

Для написания декомпилятора или отладчика мы должны сначала разобраться с механизмом самого эмулятора. Поскольку защиты нет, подойдет даже Debug.com.

> 16FO:0101 8В365201 MOV SI, [0152]; Указатель команд

> 16FO:0105 AD LODSW; Читаем 1st операнд

> 16FO:0106 97 XCHG DI.AX; Dl :" [1st]

> 16FO.-0107 8B3D MOV Dl, [Dl]; "

> 16FO:0109 AD LODSW; Читаем 2st операнд

> 16FO:OIOA 93 XCHG BX.AX; BX:= &2st

> 16FO;OIOB OB3F OR Dl, [BX]; tO:= [1st) I [2st]

> 16FO:OIOD AD LODSW; Читаем 3st операнд

> 16FO:OIOE 97 XCHG Dl,AX; AX:= tO; Dl = 3st

> 16FO:OIOF F7DO NOT AX; AX:= NOT tO

> 16FO:0111 89365201 MOV [0152],SI.• Opdate ernIP

> 16FO:0115 AB STOSW; mov [3st],NOT(OR [1st], [2st])

> 16FO:0116 EBE9 JMP 0101; -- цикл выборки команд --"

> 16FO:0152 5А01; ernREG:: ernIP

Обратите внимание на строку 0115—в ней заключена вся логика эмулятора. Именно тут собака зарыта. MOV [3st], NOT(OR [1st),[2st]). Всего одной этой команды достаточно для реализации всех остальных.

Как учит булевская алгебра, есть только две логические операции NOT и OR, и все остальные (AND, XOR) можно выразить через эти две. Причем, учитывая, что OR А,А = А, можно сказать, что данная функция может действовать как NOT (PIRS А,А), а следовательно, и как OR (PIRS(PIRS(A.B), PIRS(A,B)). Поскольку приемник представляет собой непосредственное значение, то можно также со­здать MOV и JMP (последний — изменяя "регистр" указателя команд).

И все. Защите конец. Мы уже знаем как декодировать числовые последова­тельности и можем без напряжения вычислить "границы команд более высокого уровня". Те, кто знаком с булем, могут пропустить следующий абзац, а для остальных маленький ликбез. Итак:

AND == NOT[(OR(NOT(A), NOT (В))];

XOR == AND[ OR (A,B), NOT(AND (A,B))];

mov == NOT(NOT(A)) или OR (A,A)

JMP =- MOV ([emlP],[A])

jmp == JMP [t0l\t0 DW offset Label

Таким образом, мы теперь имеем базовый набор команд для создания логики "второго уровня". В отличие от первого уровня, одни и те же определения второго могут быть построены различными комбинациями. Это не позволит применить шаблоны. Но что-нибудь еще придумаем.

Автор сдуру включил фрагменты исходников "чтобы легче было ломать". Я так и не понял глубокий смысл этой акции, но, раз нам дали кусок исходника, давайте проверим на совпадение команд первого уровня.

Ø ernNOT macro Src, Dst

Ø ernNOR Src, Src, Dst

Ø endm

Ø emOR macro Srcl, Src2, Dst

Ø ernNOR Srcl, Src2, emRI

Ø ernNOT emRI, Dst

Ø endm

Эти два фрагмента явно включены ради трафика, поскольку никаких других (кроме очевидно избыточных) реализаций данных команд не существует.

>emAND macro Srcl, Src2, Dst

Ø ernNOT Srcl, emRI

Ø ernNOT Src2, emR2

Ø ernNOR emRI, emR2, Dst

Ø endm

Таким образом, математика торжествует и, как мы видим, для написания декомпилятора исходники абсолютно не нужны.

Переходим к логике. Все пестрое множество реализаций может крутиться только вокруг двух формул:

а ===> В == OR(NOT(A),B)

а <--> В == OR [AND (A,B),AND (NOT(A),NOT(B))]

Например, нам встретится следующая последовательность:

OR [AND (А,В), NOT(OR(A.NOT(C)))]

Тех, кто еще не понял, что это делает, попрошу составить логическую матрицу, в которой перечислить все возможные состояния (благо их всего восемь).

Если то же самое записать на привычном сишном наречии, то получится что-то типа а? Ь: с.

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

Анализ программы не должен представить особых трудностей, и я его опускаю. Не хочу вам портить последнее удовольствие, да и в любом случае вопрос дизассемблирования программ далеко выходит за рамки данной заметки.

Но на механизме проверки подлинности пароля я все же остановлюсь. Алгоритм до ужаса простой, и для нахождения пароля нужно решить одно • простенькое линейное уравнение. Сам алгоритм на 186 диалекте выглядит так:

MOV сх,о

LEA SI.Buffer

Repeat:

MOV DX,CX

XOR CX, [SI]

JMF Repeat

Check:

CMP CX,lstConst

JNZ Nag

CMP DX,2stConst

JNZ Nag

Собственно "двойная" проверка обеспечивает дыру достаточных размеров, чтобы в нее можно было без труда пролезть. В самом деле, последние два символа пароля будут равны:

XOR lstConst,2stConst = XOR 7528h, 784Dh = OD65h = 'e

Пароль едва ли не сам приходит на ум, но мы пойдем другим путем:) Найти подходящий пароль несложно; более того, последовательности в стиле <а хог Ь хог с хог d хог е> описываются едва ли не в каждом букваре! Нетрудно даже скалькулировать необходимое число шагов в наихудшем случае в данной разряд­ной сетке. Оно слишком мало. Самый криптостойкий пароль вскрывается даже не за 2^ итераций, а гораздо быстрее. Т.е. криптостойкость меньше выбранной разрядной сетки!

Замечу еще раз, что предложенная мной реализация атаки базируется на элементарной алгебре и в принципе должна быть доступна каждому хакеру.





Дата публикования: 2014-12-08; Прочитано: 227 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.008 с)...