Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #85, ЯНВАРЬ 2006 г.

Капитуляция защитных механизмов

Крис Касперски ака мыщъх

Хакер, номер #085, стр. 085-110-4


Код выглядит полной бессмыслицей. Какие тут еще sahf, and и add? Но это еще что! Присмотревшись повнимательнее (Options-> Text representation -> Number of opcode bytes -> 4), мы обнаруживаем, что инструкции MOV EAX,2019Eh соответствует... однобайтовый код B8h (во всяком случае, IDA Pro уверяет нас в этом), чего не может быть! На самом деле это - багофича ИДЫ, не обновившей дизассемблерный листинг после расшифровки. Подгоняем курсор к строке 20004Bh и нажимаем <U>, чтобы перевести его в неопределенную (undefined) форму. То же самое необходимо проделать и с массивом байт, начинающимся со строки 00200053h. Но это еще не все! Ведь после расшифровки этот массив стал частью нашей процедуры, а IDA ошибочно оборвала функцию на адресе 200050h, влепив сюда «endp» (end of procedure). Чтобы восстановить статус-кво, необходимо подогнать курсор к концу массива и нажать <E> (Edit->Functions->Set Function End). После этого можно вернуться в начало строки 20004Bh и нажать «C», чтобы превратить неопределенные байты в CODE.

После расшифровки скриптом на экране дизассемблера мы получим читабельный код, в конце которого просматриваются текстовые строки «Wrong password, sorry» и «Success! Congratulations» с перекрестными ссылками возле них. Перекрестная ссылка это то, что начинается с префикса «XREF» (cross reference). Это мощное оружие против защиты, ведущее прямо в сердце защитного механизма. В частности, чтобы увидеть, какой код выводит сообщение о неправильном пароле, достаточно перейти по перекрестной ссылке к строке «loc_2000B9». Суффикс «o» в конце обозначает offset (смещение). Это говорит о том, что данная строка адресуется по ее смещению, то есть мы имеем дело с указателем.

На самом деле в окрестностях строки 2000B9h нет и не может быть ничего интересного. Тот код просто выводит сообщение wrong password на экран. Правосудие уже свершилось! Карающая рука Немезиды находится совсем в другом месте. В каком? Мы видим, что рядом со строкой 2000B9h имеется еще одна перекрестная ссылка, ведущая к метке «start+C7j». Суффикс «j» подразумевает jump, то есть прыжок. Это уже интереснее! Возможно, здесь-то и кроется тот самый заветный условный переход, который решает, правильный ли этот пароль или нет. Подводим курсор к перекрестной ссылке и нажимаем ENTER, IDA автоматически переносит нас на нужное место к строке 2000СFh. Что ж, все вполне логично, функция start расположена по адресу 200008h, а 200008h + C7h = 2000СFh.

Окрестности кода, в который нас привела цепочка перекрестных ссылок

LOAD:002000CC pop ebx ; CODE XREF: start:loc_200099?j

LOAD:002000CD test ebx,ebx ; проверка ebx на равенство нулю

LOAD:002000CF jnz short loc_2000B9 ; прыжок, если ebx не нуль

LOAD:002000D1 mov ecx,offset aSuccssCngrt; ветка «правильного пароля»

Держите мой мыщъх'иный хвост! По этому адресу действительно находится условный переход, сравнивающий содержимое регистра EBX с нулем, и если он не равен нулю, то происходит переход на подпрограмму, выводящую сообщение wrong password на экран. В противном случае управление получает ветка, выводящая «Success! Congratulations».

Назад на стр. 085-110-3  Содержание  Вперед на стр. 085-110-5