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

Пиши безопасно

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

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


// формирование завершающего нуля и вывод строки на экран

buf[a]=0; printf("%s\n",buf);

return 0;

}

printf("USAGE:crypt.exe password\n");

}

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

Для шифровки не обязательно использовать крутые криптостойкие алгоритмы, такие как RC4 или DES. Сойдет и обычный XOR. Необходимо только убедиться, что ни один символ шифруемой строки не обращается в ноль: С трактует ноль как конец строки. Выражение x XOR y == 0 становится истинным тогда и только тогда, когда x == y, то есть ключ совпадает с одним из символов шифруемой строки. Значение FFh ни разу не встречается ни в одной из двух наших строк, поэтому оно вполне подойдет на роль ключа.

Единственная проблема - как зашифровать строки. В принципе, это можно сделать и после компиляции, воспользовавшись любым hex-редактором (например HIEW), однако при каждом ребилде эту процедуру придется повторять вновь и вновь, что очень достает.

Мы напишем для этой цели специальный отдельный шифратор, захватывающий исходную строку и выплевывающий зашифрованную последовательность, оформленную по всем правилам языка С, после чего нам останется только вставить ее в исходный код.

Его макет может выглядеть так:

Макет простейшего шифратора

main(int c, char **v)

{

int a;

printf("char *var_name=\"");

for(a=0;a<strlen(v[1]);a++)

{ // шифровка по XOR

printf("\\x%02X",v[1][a] ^ atol(v[2]));

printf("\";");

}

}

Если сделать все верно, текстовые строки "password ok/wrong password" исчезнут из откомпилированной программы. Теперь для взлома защиты хакеру придется потратить намного больше времени и усилий. В данном случае разница не так уж заметна, но в программах, состоящих из десятков тысяч строк, все будет пучком!

Совет №2: не давай переменным говорящих имен

Ни в коем случае не назначай защитным компонентам никаких осмысленных имен, особенно при программировании в Delphi и Builder - они попадут в исполняемый файл. Вроде бы очевидный совет (меня даже высмеяли за него пару раз), однако его очевидность не влияет на программистов, и они продолжают наступать на грабли. Взгляни, например, на результат декомпиляции программы Etlin HTTP Proxy на картинке.

Хакер с ходу видит юнит fRegister с процедурой bOkClick, обрабатывающей нажатие кнопки "ОК", расположенной по адресу 48D2DCh. Все! Защитный механизм успешно локализован! Самая сложная часть взлома позади!

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

Совет №3: используй виртуальные функции

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