воскресенье, 31 июля 2011 г.

Конкурс от журнала ПРОграммист. Подбор кода. Начало

А дальше идут ветвления. Здесь бы в нормальном отладчике просмотреть трассировку, но нормального отладчика не дали. Значит буду трассировать через OllyDbg. Сначала, с помощью hardware breakpoint нахожу место, где изменяется память (0x4791F5) командного регистра виртуальной машины(ВМ). Ставлю Conditional log breakpoint. В поле Condition пишу (EAX > 00008DF6) && (EAX< 00008EAE), это означает что точка останова будет срабатывать только когда значение командного регистра ВМ будет в пределах нашей функции. В поле Explanation(описание) пишу PC (название командного регистра). В поле Expression пишу [5E4994] чтобы показывало значение регистра. Pause programm Never. Log Value of expression - allways.
Работает! К сожалению, ужасно медленно, но что имеем - то имеем.

по фрагменту лога (ассемблерный код я подставил чтобы понятно было)
004791F5 LOG: PC = 8E38 (36408.) ;cmpi.w #$DBB7,$773C(a4)
004791F5 LOG: PC = 8E90 (36496.) ;bne.s loc_8E90
004791F5 LOG: PC = 8E94 (36500.) ;move.w #$10,d1
видно, что выполнился условный переход. Что-то мне говорит, что это как раз и есть контроль правильности пароля. Сейчас проверим. Нужно подбрать пароль, чтобы соответствовал условию.

Выбираю из таблицы все символы, которые соответствуют буквам пароля.
B C D F G H J K L M N P Q R S T V W X Y Z
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14
0 1 2 3 4 5 6 7 8 9 !
15 16 17 18 19 1A 1B 1C 1D 1E 1F

Как видно из таблицы, для кодирования пароля в памяти, используются все варианты перестановки 5-ти бит. В результате работы цикла loc_8E14, по адресу 773C оказывается 64-битовая последовательность двенадцати 5-битовых символов. Младшие 4 бита этой последовательности всегда равны 0.
Затем она маскируется, с помощью сложения по модулю 2, этим числом
B2 9A 56 B2 B2 EB B2 00.

Чтобы переход не выполнился, нам нужно найти такие числа, чтобы получить из B29A DBB7 сложением по модулю 2. Дальше идут переходы, смысл которых такой-же, поэтому запишу все вместе.

B 1011 D 1101 0110 6
2 0010 B 1011 1001 9
9 1001 B 1011 0010 2
A 1010 7 0111 1101 B

5 0101 6 0110 0011 3
6 0110 B 1011 1101 D
B 1011 A 1010 0001 1
2 0010 7 0111 0101 5

B 1011 C 1100 0111 7
2 0010 4 0100 0110 6
E 1110 5 0101 1011 B
B 1011 3 0011 1000 8

B 1011 4 0100 1111 F
2 0010 D 1101 1111 F
0 0000 F 1111 1111 F
0 0000 0 0000 0000 0

разобью на наборы по 5 бит и посмотрю что получится
R G 1 Y 5 H P 1 2 F ! !
01101 00100 10110 10011 11010 00101 01011 10110 10111 00011 11111 11111

Теперь, когда я по можно упростить граф дизассемблера, сгруппировав его узлы. Если я не ошибся ни с чем, то теперь он будет выглядеть так:

1 комментарий: