Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #57, АВГУСТ 2005 г.

Мануальная терапия

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

Спецвыпуск: Хакер, номер #057, стр. 057-080-3


Первые эксперименты

Рассмотрим простейшую программу, которая запрашивает пароль и контролирует целостность своего кода. Ключевой фрагмент исходного текста может выглядеть, например, так (полный вариант можно найти на компакт-диске в файле demo.c):

Парольная защита с традиционным самоконтролем

#define _PSW_ "godown" // оригинальный пароль

// начало охранной зоны

begin(){ return 0;}endA();

main(int c, char **v)

{

int CRC=0;char buf[1024];unsigned char *a;

// переменная должна быть статической, потому что локальные

// переменные инициируются прямо в коде, изменяя его CRC

static int _CRC_= -1;

// подсчет CRC

for(a=(unsigned char*) begin; a<(unsigned char *)endA;a++)

CRC = (CRC + *a);

// отладочная дверь под служебные нужды

if ((c>1) && !strcmp(v[1],"--debug")) printf("%X\n",CRC);

// если CRC не совпадают, выйти не прощаясь!

// внимание! нельзя выводить никаких ругательств, иначе нас засекут

if (CRC ^ _CRC_) return 0;

// проверка пароля

printf("enter password:"); gets(buf);

if (strcmp(buf, _PSW_))

printf("wrong passwod\n");

else

printf("password ok\n");

}

// конец охранной зоны

endA(){ return 0;}

Откомпилировав программу своим любимым транслятором (например Microsoft Visual C++), запустим ее с ключом "--debug" и посмотрим, какую контрольную сумму она напишет (в моем случае это 47h). Присвоим это значение переменной _CRC_ и перекомпилируем исходный код. Конечно, оставлять отладочный механизм в теле готовой программы нехорошо, однако в качестве демонстрационного примера такой трюк вполне сойдет. Не будем обращать внимание на то, что оригинальный пароль лежит открытым текстом и кто угодно может подсмотреть его. Сосредоточимся исключительно на механизме самоконтроля.

Дизассемблирование защитного механизма сразу же показывает тот заветный условный переход, который рулит всем. Вот он - лежит по адресу 4010B1h (см. скрин).

Как видно, он ведет к той ветке кода, которая выводит "password ok", поэтому, если мы заменим jz loc_4010CA на jmp short loc_4010CA, любой пароль будет воспринят как правильный. Для этого необходимо заменить 74 17 (машинный код jz loc_4010CA) на EB 17 (jmp short loc_4010CA). Берем любой hex-редактор, например HTE, создаем копию ломаемого файла (я называл ее demo.crk.exe), загружаем в редактор, нажимаем <F6> (mode), выбираем режим pe/image, давим <F5> (goto), вводим адрес условного перехода (4010B1h), затем нажимаем <F4> (edit) и заменяем "74" на "EB". Клавиша <F2> сохраняет все изменения в файле, а <F10> выводит нас из редактора.

Запускаем хакнутую программу и… опс! Она не запускается! Так где там наш старый добрый SoftIce? Загружаем программу в Symbol Loader, даем команду "bpm 4010B1" (установить точку доступа на обращение к ячейке 4010B1h, в которой расположен хакнутый условный переход) и по <Ctrl-D> выходим из отладчика, возвращая управление программе.

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

Назад на стр. 057-080-2  Содержание  Вперед на стр. 057-080-4