УДК 681.326

МЕТОДЫ ЗАЩИТЫ ОТ ДИЗАССЕМБЛЕРОВ

©1999 г. Ю. В. Машевский

Введение

Вполне объяснимо желание подавляющего большинства программистов работать с твердой копией исследуемой программы. Вследствии этого первоочередной проблемой, с которой сталкивается потенциальный злоумышленник при взломе практически любой системы защиты, является дизассеблирование [1] исполняемого кода программы и получение листинга с мнемоническим изображением ассемблерных команд [2].

Поэтому любая серьезная система защиты немыслима без средств противодействия дизассемблерам.

В этой статье рассмотрим некоторые методы противодействия дизассемблерам. Эти методы получены автором статьи на основе анализа существующих систем защиты и вирусов.

Методы защиты от дизассемблеров

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

Ниже приведены некоторые приемы, которые следует использовать для противодействия дизассемблерам.

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

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

2.1. Косвенная передача управления.

2.2. Модификация адреса перехода в коде программы (таблица 1).

Таблица 1

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

mov word ptr cs:m[1],1234h

. . .

m:

jmp place

. . .

модификация адреса перехода - подстановка нового адреса
. . .

mov word ptr cs:m[1],es

mov word ptr cs:m[3],5678h

. . .

m:

call far 0000h

. . .

модификация адреса вызываемой подпрограммы
mov bx,1234h

jmp dword ptr cs:[bx]

. . . ;или

call word ptr es:[si]

модифицировать адрес гораздо проще, если использовать косвенные переходы и вызовы
and byte ptr cs:m, 0EFh ;обнулить

;4ый байт

;по адресу m

m:

push ax ;команда преобразуется

;в inc ax

 

2.3. Использование нестандартных способов передачи управления (jmp через ret, ret и call через jmp) (таблицу 2).

Таблица 2

Первичный код Альтернативный код
. . .

jmp m

. . .

m:

. . .

mov ax,offset m ; занести в стэк push ax ; адрес метки.

ret ; перейти на метку

. . .

m:

. . .

call subr

m:

. . .

subr:

. . .

ret

mov ax,offset m ; занести в стэк

push ax ; адрес возврата.

jmp subr ; перейти на под-

m: ; программу

. . .

subr:

. . .

ret

. . .

int 13h

. . .

pushf ; занести в стэк флаги.

push cs ; занести в стэк CS.

mov ax,offset m ; занести в стэк

push ax ; адрес возврата.

xor ax,ax

mov es,ax

jmp dword ptr es:[13h*4]

m:

. . .

. . .

ret

. . .

; взять из стэка

pop bx ; адрес возврата и

jmp bx ; перейти на него

iret

. . .

mov bp,sp ; переход на точку

jmp dword ptr [bp] ; возврата из пре-

; рывания.

. . .

add sp,4 ; точка возврата.

popf

  1. Перекрывающийся код. Расмотрим следующий пример:

eat_sr:

mov ax,02EBh

jmp $-2 ; huh?

... ; rest of code остальной код

Первая инструкция заносит "незначимое" значение в AX. Вторая делает переход на значение операнда команды MOV AX. '02EB' переводится как 'jmp$+2'. Этот переход перепрыгивает первый JMP и продолжает дальше по коду. Вот еще один пример:

erp: mov ax,0FE05h

jmp $-2h

add ah,03Bh

... ; rest of code

Этот код более полезен. Смоделируем трассировку, показвыая HEX-дамп каждый шаг, чтобы прояснить ситуацию.

B8 05 FE EB FC 80 C4 3B mov ax,0FE05h ; ax=FE05h

^^ ^^ ^^

B8 05 FE EB FC 80 C4 3B jmp $-2 ; jmp into '05 FE'

      ^^ ^^

B8 05 FE EB FC 80 C4 3B add ax,0EBFEh ; 05 is 'add ax'

   ^^ ^^ ^^

B8 05 FE EB FC 80 C4 3B cld ; a dummy instruction

      ^^

B8 05 FE EB FC 80 C4 3B add ah,3Bh ; ax=2503h

         ^^ ^^ ^^

Инструкция ADD AH,03Bh здесь означает просто занесение 2503h в AX. Добавив 5 байт (вместо простого использования 'mov ax,2503h'), этот код очень хорошо затруднит работу дизассемблеру. Даже если инструкции дизассемблированы верно, значение AX будет неизвестно до тех пор, пока не будет помещено в AX. Вы можете скрывать значение от дизассемблера, используя 'ADD AX' или 'SUB AX' везде, где это только возможно. Если Вы хорошо проверите это, Вы сможете увидеть, что любое значение может быть занесено в AX. Два этих значения могут быть изменены на 0FEh в первой строке и 03Bh - в последней.

4. Использование возможностей установки префикса сегментного регистра перед некоторыми командами (pushf, pushfd, cld и др.). Дизассемблер не в состоянии правильно распознать программу (db 3Eh, 2Eh, 90h = ds: cs: nop).

5. Дизассемблер сбивается на нестандартном формате загружаемого модуля (например, перекрыть весь сегмент кода exe-файла DOS стеком).

Заключение

Приведенный список методов противодействия дизассемблерам является неполным, но вполне достаточным для противодействия попыткам получить дизассемблированный листинг программы. Дополнительные методы защиты от дизассемблеров можно найти в [3, 4, 5].

ЛИТЕРАТУРА

  1. Расторгуев С. П., Дмитриевский Н. Н. Искусство защиты и "раздевания программ". - М., 1991.
  2. Шнайдер А. Язык ассемблера для персонального компьютера фирмы IBM. Пер. с англ. - М.: Мир, 1998. - 406 с.
  3. Правиков Д. И. Ключевые дискеты. Разработка элементов систем защиты от несанкционированного копирования. - М.: Радио и связь, 1995. - 128 с.
  4. Спесивцев А. В., Вегнер В. А., Крутяков А. Ю. и др. Защита информации в персональных ЭВМ. - М.: Радио и связь, 1992. - 190 с.
  5. Щербаков А. Защита от копирования. - М.: Эдель, 1992. - 80 с.


Кафедра вычислительной техники

Смоленский филиал Московского энергетического института

(Технический университет)

Поступила в редакцию 28.11.99.