Библиотека knigago >> Компьютеры: Разработка ПО >> Крэкинг и реверсинжиниринг >> Неявный самоконтроль как средство создания не ломаемых защит

Крис Касперски - Неявный самоконтроль как средство создания не ломаемых защит

Неявный самоконтроль как средство создания не ломаемых защит
Книга - Неявный самоконтроль как средство создания не ломаемых защит.  Крис Касперски  - прочитать полностью в библиотеке КнигаГо
Название:
Неявный самоконтроль как средство создания не ломаемых защит
Крис Касперски

Жанр:

Статьи и рефераты, Самиздат, сетевая литература, Литература ХXI века (эпоха Глобализации экономики), Крэкинг и реверсинжиниринг

Изадано в серии:

неизвестно

Издательство:

неизвестно

Год издания:

-

ISBN:

неизвестно

Отзывы:

Комментировать

Рейтинг:

Поделись книгой с друзьями!

Помощь сайту: донат на оплату сервера

Краткое содержание книги "Неявный самоконтроль как средство создания не ломаемых защит"

Аннотация к этой книге отсутствует.

Читаем онлайн "Неявный самоконтроль как средство создания не ломаемых защит". [Страница - 4]

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

6

Неявный самоконтроль как средство создания не ломаемых защит
Допустим, критическая часть защиты выглядит так и нам необходимо про
контролировать целостность условного оператора if, выделенного жирным синим
шрифтом:
int my_func()
{
if (check_user())
{
fprintf(stderr, "passwd ok\n");
}
else
{
fprintf(stderr, "wrong passwd\n");
exit(1);
}
return 0;
}

Загрузив откомпилированный файл в дизассемблер, мы получим следую
щий код (чтобы быстро узнать которая из всех процедур и есть my_func, опирайтесь
на тот факт, что большинство компиляторов располагает функции в памяти в по
рядке их объявления, т. е. my_func будет вторая по счету функция):
.text:00401060
.text:00401060
.text:00401065
.text:00401067
.text:00401069
.text:0040106E
.text:00401073
.text:00401078
.text:0040107B
.text:0040107D
.text:0040107E
.text:0040107E
.text:0040107E
.text:0040107E
.text:00401083
.text:00401088
.text:0040108D
.text:0040108F
.text:0040108F

sub_401060

proc near
; CODE XREF: sub_4010A0+AFvp
call
sub_401000
test
eax, eax
jz
short loc_40107E
push
offset aPasswdOk
; "passwd ok\n"
push
offset unk_407110
call
_fprintf
add
esp, 8
xor
eax, eax
retn
; 

loc_40107E:

sub_401060

push
push
call
push
call
endp

; CODE XREF: sub_401060+7^j
offset aWrongPasswd ; "wrong passwd\n"
offset unk_407110
_fprintf
0FFFFFFFFh
; int
_exit

Как нетрудно сообразить, условный переход, расположенный по адресу
0x401067 и есть тот самый "if", который нам нужен. Однако, это не весь if, а только
малая чего часть. Хакер может и не трогать условного перехода, а заменить инструк
цию test eax, eax на любую другую инструкцию, сбрасывающую флаг нуля. Так же
он может модифицировать защитную функцию sub_401000, которая и осуществля
ет проверку пароля. Словом, тут много разных вариантов и на этом несчастном
условном переходе свет клином не сошелся, а потому для надежного распознавания
взлома нам потребуются дополнительные проверки. Впрочем, это уже детали. Глав
ное, что мы определили смещение контролируемого байта. Кстати, а почему имен
но байта?! Ведь мы можем контролировать хоть целое двойное слово, расположен
ное по данному смещению! Особого смысла в этом нет, просто так проще.
Крис Касперски

7

Неявный самоконтроль как средство создания не ломаемых защит
Чтобы не работать с непосредственными смещениями (это неудобно и вооб
ще некрасиво), давайте загоним их в специально на то предназначенную структуру
следующего вида:
union anti_hack
{
// буфер, содержащий оригинальный код программы
char buf[MAX_CODE_SIZE];
// локальные переменные программы
struct local_var
{
int
local_var_1;
int
local_var_2;
};
// неявно контролируемые переменные программы
struct code_control
{
char
gag_1[OFFSET_1];
int
x_val_1;
char
gag_2[OFFSET_2  OFFSET_1  sizeof(int)];
int
x_val_2;
};
};

Массив buf – это тот самый буфер, в который загружается оригинальный
код программы для его последующей расшифровки (распаковки). Поверх массива
накладываются две структуры: local_val, содержащая в себе локальные перемен
ные, которые в процессе своей инициализации затирают соответствующие им
ячейки buf'a и тем самым создают впечатление, что прежнее содержимое буфера
стало теперь ненужным и более уже не используется. Количество локальных пере
менных может быть любым, главное – следить за тем, чтобы они не перекрывали
контрольные точки программы, изменять содержимое которых нельзя. В приве
денном выше примере, по соображениям наглядности, контрольные точки выне
сены в отдельную структуру code_control, два массива которой gag_1 и gag_2 ис
пользуются лишь для того, чтобы переменные x_val_1 и x_val_2 были размещены
компилятором по необходимым нам адресам. Как нетрудно долгаться: константа
OFFSET_1 задает смещение первой контрольной точки, а OFFSET_2 – второй.
Достоинство такой схемы заключается в том, что при добавлении или удалении
локальных переменных в структуру local_var, структура code_contorl остается не
изменной. Напротив, если объединить локальные переменные и контрольные
точки --">

Оставить комментарий:


Ваш e-mail является приватным и не будет опубликован в комментарии.