Купить
 
 
Жанр: Учеба

Как защитить информацию (пособие по борьбе с хакерами)

страница №5

блок.) ¦
¦ db ........ ; конец блока, адрес = nn + ll ¦
¦мм: db ........ ; 3 модуль (и так далее) ¦
¦ ¦
¦ После декодирования 1 блока и исполнения остальных¦
¦команд управление передается на декодированный блок, который¦
¦начинается с такой же процедуры, декодирующей следующий¦
¦участок. И таких вложений - 156. ¦
L-------------------------------------------------------------

рис. 5.1

ИСПОЛЬЗОВАНИЕ ТЕКСТА КАК КОДА ПРОГРАММЫ
(для микропроцессора Z80)
-------------------------------------------------------------¬
¦6E1E C3 6C 71 jmp 716Ch ; завершение предыдущего ¦
¦ ; участка ¦
¦6E21 47 mov B,A ; начало подпрограммы ¦
¦6E22 31 55 D0 mov SP,0D055h ;1UP - текст первого ¦
¦ ; сообщения ¦
¦6E25 47 mov B,A ; ¦
¦6E26 32 55 D0 mov (0D055h),A ;2UP - текст второго ¦
¦ ; сообщения ¦
¦6E29 45 mov B,L ; ¦
¦6E2A 48 mov C,B ;H - третье сообщение ¦
¦6E2B C9 ret ;I (оно же завершает ¦
¦6E2C 21 00 00 mov HL,0000 ; подпрограмму) ¦
L-------------------------------------------------------------

рис. 5.2

Таблица 5.1
ВЗАИМОЗАМЕНЯЕМЫЕ КОМАНДЫ
----------------------T------------------------¬
¦ Первичный код ¦ Альтернативный код ¦
+---------------------+------------------------+
¦ Команды пересылки: ¦
+---------------------T------------------------+
¦ mov op1,op2 ¦ push op2 ¦
¦ ¦ pop op1 ¦
+---------------------+------------------------+
¦ xchg op1,op2 ¦ push op1 ¦
¦ ¦ push op2 ¦
¦ ¦ pop op1 ¦
¦ ¦ pop op2 ¦
+---------------------+------------------------+
¦ lds r,dword ptr op ¦ mov r,word ptr op ¦
¦ ¦ mov ds,word ptr op+2¦
+---------------------+------------------------+
¦ les r,dword ptr op ¦ mov r,word ptr op ¦
¦ ¦ mov es,word ptr op+2¦
+---------------------+------------------------+
¦ Арифметические команды: ¦
+---------------------T------------------------+
¦ add op1,op2 ¦ xchg op2,ax ¦
¦ ¦ add op1,ax ¦
¦ ¦ xchg op2,ax ¦
+---------------------+------------------------+
¦ adc,sub,sbb и др. ¦ аналогично add ¦
+---------------------+------------------------+
¦ inc op ¦ add op,1 ¦
+---------------------+------------------------+
¦ dec op ¦ sub op,1 ¦
+---------------------+------------------------+
¦ Логические команды: ¦
+---------------------T------------------------+
¦ and,or,xor и др. ¦ аналогично add ¦
+---------------------+------------------------+
¦ not op ¦ xor op,0ff(ff)h ¦
+---------------------+------------------------+
¦ Цепочечные команды: ¦
+---------------------T------------------------+
¦ rep movsb ¦ push ax ¦
¦ ¦ m: mov al,[si] ¦
¦ ¦ mov es:[di],al ¦
¦ ¦ inc si ¦
¦ ¦ inc di ¦
¦ ¦ loop m ¦
¦ ¦ pop ax ¦
+---------------------+------------------------+
¦ repe(repne) cmpsb ¦ push ax ¦
¦ ¦ m: mov al,[si] ¦
¦ ¦ cmp al,es:[di] ¦
¦ ¦ jne(je) m1 ¦
¦ ¦ inc si ¦
¦ ¦ inc di ¦
¦ ¦ loop m ¦
¦ ¦ m1: pop ax ¦
+---------------------+------------------------+
¦ lodsb ¦ mov al,[si] ¦
¦ ¦ inc si ¦
+---------------------+------------------------+
¦ stosb ¦ mov es:[di],al ¦
¦ ¦ inc di ¦
+---------------------+------------------------+
¦ shift op,cnt ¦ push cx ¦
¦ ¦ mov cx,cnt ¦
¦ ¦ m: shift op,1 ¦
¦ ¦ loop m ¦
¦ ¦ pop cx ¦
+---------------------+------------------------+
¦ Команды передачи управления: ¦
+---------------------T------------------------+
¦ j(условие) loc ¦ jn(условие) loc1 ¦
¦ ¦ jmp loc ¦
¦ ¦ loc1: . . . ¦
+---------------------+------------------------+
¦ loop loc ¦ dec cx ¦
¦ ¦ jne loc ¦
+---------------------+------------------------+
¦ jmp addr ¦ push addr ¦
¦ ¦ ret ¦
+---------------------+------------------------+
¦ jmp dword ptr addr ¦ push addr+2 ¦
¦ ¦ push addr ¦
¦ ¦ retf ¦
+---------------------+------------------------+
¦ call addr ¦ push m ¦
¦ ¦ jmp addr ¦
¦ ¦ m: . . . ¦
L---------------------+-------------------------
Сокращения: op, op1, op2 - операнды команд; r - операнд-регистр;
shift - код команды сдвига; cnt - счетчик в командах сдвига; loc -
метка в командах перехода и цикла; addr - адрес в командах перехода и
вызова подпрограмм.


6. ИСПОЛНЯЕМЫЙ МОДУЛЬ - ЧТО МОЖНО СДЕЛАТЬ
БЕЗ ИСХОДНЫХ ТЕКСТОВ?
Одной из самых сложных работ в программировании является
модификация исполняемых модулей при отсутствии исходных текстов. Надо
признать, что программисту не часто приходится заниматься подобными
работами, но, однако, никто не застрахован от потери собственных
исходных текстов программ. В частности, мы обратились к решению
названной задачи для того, чтобы исправить найденную в нашем пакете
ошибку. "Исходники" к тому времени были случайно уничтожены при борьбе
с вирусом. Бесполезно вспоминать и переписывать весь пакет - за тот
срок, в течении которого гарантировалось устранение любых замечаний,
мы в любом случае не успевали этого сделать. Поэтому стали искать
другие пути. В результате разработали соответствующий метод и даже
набор инструментальных средств, который с успехом применяем по сей
день.
Разумеется, приемы корректировки исполняемых модулей
предназначены профессиональным разработчикам ПО для IBM PC в среде
DOS. Поэтому опустим некоторые детали, которые профессионал должен
знать, а в качестве примера возьмем лишь EXE-файлы - более сложные для
модификации, поскольку все сказанное может быть отнесено и к
COM-файлам.
Напомним, что EXE-файл состоит из заголовка, таблицы перемещения
и собственно исполняемого кода. Информация заголовка используется
операционной системой для загрузки модуля в оперативную память.
Устанавливаются значения основных регистров, обрабатывается таблица
перемещения, а затем управление передается задаче. В ходе работы все
основные функции ввода/вывода, захвата или освобождения ОЗУ и т.п.
обрабатываются операционной системой через прерывание 21h, а значит,
всегда могут быть изменены с помощью специального драйвера, который
либо резидентно находится в памяти, либо непосредственно включен в
модифицируемый EXE-файл. Второй подход более удобен.
Для корректировки функций EXE-файла необходимо: внедрить в него
этот драйвер; осуществить передачу управления на драйвер.

ВКЛЮЧЕНИЕ В ТЕЛО EXE-файла СВОЕГО МОДУЛЯ
Вариантов включения собственного блока в существующий EXE-файл
несколько: можно добавить его в конец или в начало файла; встроить в
свободное место внутри программы или "склеить" им оба EXE-файла (свой
и модифицируемый).
Легче всего добавить дополнительные команды в конец EXE-файла и
исправить в заголовке размер загружаемой части (с учетом добавленных
байт). Однако предварительно необходимо проверить, возможна ли их
загрузка в ОЗУ. Дело в том, что задача может быть оверлейной и DOS
загрузит только ее корневой сегмент. Например, в BORLAND C++ размер
BCC.EXE более 800 кб, а объем ОЗУ всего 640 кб. Ясно, что загрузкой и
выгрузкой отдельных частей гиганта занимается специальный блок в
корневом сегменте программы, который ничего не знает о "прилепленном"
в конце модуле, и поэтому тот никогда не попадет в оперативную память.
А в заголовке имеется информация только о корневом блоке, небольшом по
размеру. Так что если к загружаемой части не относится "хвост", значит
данный метод здесь не годится.
В этом случае можно поискать "пустые" места в загружаемой части
EXE-файла. Например, цепочку любых повторяющихся кодов. Если размер
найденного пространства больше модуля, то все в порядке и следует
вписать туда свои команды.
Если же и этого нет, то пробуем включить свой модуль в начало
программы, сразу за таблицей перемещения, конечно, при наличии там
свободного места. Впрочем, в отличие от предыдущего способа, здесь его
всегда можно создать. Достаточно "раздвинуть" файл и изменить таблицу
перемещения с учетом сдвига, затем подправить заголовок (адрес первой
исполняемой команды и размер загружаемой в память части файла).
Кстати, пример такой программы с комментариями приводится на дискете.
В принципе, можно и не раздвигать файл, а создать модуль в виде
такого же COM или EXE-файла. Затем изменить список распределения
кластеров в FAT-таблице каталога, не трогая их самих.
FAT (File allocation table) - это таблица в начальных секторах
дискеты, которая содержит связный список цепочек кластеров, занимаемых
тем или иным файлом на диске или относящимися к свободному
пространству [2]. Ее дополняет оглавление файлов (называемое также
директорий или каталог). Два байта по смещению 1Ah в элементе
оглавления каждого файла содержат номер начального кластера цепочки, а
каждый элемент цепочки в FAT-таблице указывает на следующее звено или
информирует о конце файла.
Для включения модуля в EXE-файл необходимо найти в FAT-таблице
цепочку, отмечающую занятые модулем кластеры диска и заменить в ней
метку "конец модуля" ссылкой на начальный кластер встраиваемого
исполняемого файла. Затем в элементе оглавления файла исправить номер
начального кластера (вместо него вписать стартовый номер кластера
нашего модуля), а сам модуль пометить как удаленный.

В результате при запуске EXE-файла на выполнение операционная
система загрузит в память содержимое всей цепочки кластеров с диска, в
том числе и кластеров нашего файла, который первым получит управление.
Теперь уже его команды должны отвечать за запуск исполняемой части
EXE-файла, в который он был внедрен.
Основная сложность при "склейке" двух программ заключается в том,
чтобы после первой корректно запустить вторую. Если первая - ваша,
вопрос решается просто: при ее завершении нужно передать управление по
адресам, взятым из заголовка второй задачи. Если же обе из
"склеиваемых" - "чужие", причем завершаются в неизвестном месте и
неизвестным способом, то выход один - необходимо изменить часть DOS,
обрабатывающую функции завершения процессов.
Это можно сделать двумя способами. Первый. Создается специальный
драйвер перехватывающий все функции завершения работы программ
(назовем его монитор). Затем, "склеиваются" вместе все выбранные EXE
или COM-файлы, причем сначала в полученном конгламерате размещается
монитор. При запуске он принимает на себя обработку прерываний, а
получив управление, анализирует - какая из задач уже отработала,
освобождает ресурсы, выбирает и размещает в ОЗУ следующую задачу, и
передает ей управление. После последней задачи монитор восстанавливает
исходную подпрограмму DOS и завершает свою работу.
Второй вариант является модификацией первого. Разница заключается
только в том, что монитор не обладает суверенитетом отдельной задачи,
а прикрепляется к первой из них одним из уже описанных способов. После
этого, к "зараженной" монитором задаче можно командой COPY добавлять
любое количество EXE-файлов.

ПЕРЕДАЧА УПРАВЛЕНИЯ
Управление автоматически перейдет на модуль, внедренный в тело
EXE-файла, если изменены начальные значения регистров CS и IP в
заголовке файла (байты 20 - 23 заголовка) или первый оператор, на
который указывают эти регистры (вместо него ставят команду перехода
JMP либо CALL по адресу своего модуля). Но можно перехватить
управление исправив номер прерывания в двухбайтовой команде INT.
Рассмотрим эти методы подробнее.
Для изменения начальных значений регистров CS и IP в заголовке
EXE-файла после внедрения блока команд в его тело нужно скопировать с
20 по 23-й байт заголовка (CS:IP) в специальный буфер, предусмотренный
в модуле. Затем вписать в заголовок файла адрес первой команды модуля,
а по его завершении передать управление на сохраненный в буфере адрес
начала выполнения EXE-файла.
Впрочем, можно измененить первую команду (указанную регистрами
CS:IP), не меняя сам заголовок. После внедрения блока команд в тело
файла скопируем первые байты в заранее предусмотренный буфер, а вместо
них впишем JMP или CALL с адресом модуля. По завершении его работы
выполним сохраненные в буфере команды EXE-файла и передадим управление
ему самому (на адрес из заголовка файла с учетом уже выполненных
команд).
Если же недалеко от начала EXE-файла встретится собственный JMP
или CALL с атрибутом far , то достаточно изменить адрес перехода у
существующей команды (запомнив первоначальное значение) на адрес
встроенного модуля. Удостовериться в том, что обнаруженный вами байт (
EAh или 9Ah ) действительно является первым байтом команды JMP или
CALL с аттрибутом FAR можно используя таблицу перемещения: один из ее
элементов должен указывать на адрес на 3 больший, чем адрес найденного
байта (это сегментная часть адреса в команде).
Изменение номера прерывания в двухбайтной команде INT является
самым простым из всех перечисленных способов перехвата управления.
Метод не требует внедрения своего модуля в тело "чужого" файла.
Достаточно лишь изготовить резидентный драйвер, отрабатывающий любое
свободное прерывание DOS. А в EXE-файле ищем первое попавшееся
прерывание и заменяем его тем, на котором "висит" наш драйвер.
Естественно, что он должен обрабатывать и функцию исправленной команды
INT в ЕХЕ-файле.

ДИНАМИЧЕСКАЯ КОРРЕКТИРОВКА ПРОГРАММЫ.
Допустим, надо отстранить резидентную задачу от обработки
какого-либо прерывания. В этом случае необходимо выяснить, какая из
загруженных в ОЗУ программ получает, словно эстафетную палочку,
обработку данного прерывания.
Доступ к диску осуществляется, в основном, через 13h и 21h
прерывания. Системы защиты обычно "забирают" их на себя и проверяют,
разрешен ли доступ по ним. Если разрешен, то остальной процесс
возвращается обратно к операционной системе. Порой, чтобы снять
защиту, достаточно восстановить переустановленный вектор прерывания,
направив его на DOS. А найти старый адрес поможет пошаговый режим
(трассировка) отладчика. Но как определить, что "процесс дошел" именно
до защитного механизма? Это можно сделать автоматически. Текст такой
программы (на языке Си) находится на дискете в директории FTRACE.

Заметим, что трассировкой пользуются не только отладчики, но и
вирусы. Метод их работы демонстрируется программой RV (файлы rv.c,
ftrace.asm, ftrace.h). Кстати, "вирусный" подход можно использовать и
для борьбы с вирусами же. Практика показала его эффективность:
например, приведенная на дискете программа protect.asm мешает "хорошо
себя чувствовать" некоторым вирусам, но и, правда, некоторым
антивирусам тоже.

7. КАК ОЧИСТИТЬ ПРОГРАММУ ОТ ВИРУСОВ И
ПРИСТЫКОВАННЫХ ЗАЩИТ
В прерыдущей главе описано, как внедрить защитный механизм в тело
программы. В этой, напротив, расскажем о способе его удаления с
помощью программы EXEB, имеющейся на дискете.

НАЗНАЧЕНИЕ
Программа EXEB.EXE предназначена для анализа исполняемых модулей
и удаления из них пристыковочных частей - вирусов, защит и т.п. Она
корректно работает на ПЭВМ типа IBM PC/XT/AT в среде MS DOS версии 3.1
и выше.
СОДЕРЖИМОЕ ДИСКЕТЫ И ПОРЯДОК УСТАНОВКИ
Поставляемая дискета содержит следующие файлы:
README - описание;
EXEB.EXE - основная программа;
CHSIZE - утилита для уменьшения размера результирующей задачи.
Перед началом работы необходимо скопировать дискету на жесткий диск
в любой директорий.

Формат команды запуска:
EXEB [!] "IntNumber" "FuncNumber" "Counter" "TaskName"
["CommandLine"]
где:
! - признак "холостого" срабатывания;
"IntNumber" ::= номер перехватываемого прерывания;
"FuncNumber" ::= номер функции (AH) указанного прерывания;
"Counter" ::= счетчик появлений функции FuncNumber;
"TaskName" ::= имя исследуемой задачи;
"CommandLine"::= аргументы командной строки исследуемой
задачи.
Примечание:
В командной строке в качестве аргумента FuncNumber разрешен
символ "*".
Числовые аргументы задаются в 16-ричной системе счисления.
Например, "EXEB 21 30 1 a.exe" - означает: перенести код
исследуемой задачи a.exe в результирующий EXE-файл при первом
обращении к 30h функции 21h прерывания после запуска a.exe.
Аргументы желательно выбирать таким образом, чтобы они
соответствовали первому после пристыкованного блока прерыванию в теле
исследуемой задачи.
Если программа была создана компиляторами с языков высокого
уровня (С, PASCAL, BASIC и т.п.), то рекомендуются следующие значения
аргументов:
"IntNumber" = 21 "IntNumber" = 21
"FuncNumber" = 30 или "FuncNumber" = 35
"Counter" = 1 "Counter" = 1.
EXEB позволяет исследовать исполняемый EXE-модуль на команды
вызова прерываний (int). Их номера фиксируются программой EXEB, если в
качестве аргумента FuncNumber использован символ "?". Например: при
строке запуска программы "EXEB 10 ? 1 a.exe" в крайнем правом столбце
экрана будут высвечиваться текущие номера функций 10-го прерывания.
Первый аргумент командной строки "!" - признак "холостого"
срабатывания - необязателен. Его функциональное назначение - выдача
звукового сигнала в момент обнаружения указанной вами в командной
строке ситуации (без реальной ее обработки программой EXEB, т.е. без
создания результирующего EXE-файла).
Итогом работы EXEB является файл с именем TASK.EXE, который можно
запускать на выполнение (в той же среде, в которой он был создан:
версия DOS, конфигурация ПЭВМ).
ПРИНЦИПЫ РАБОТЫ
Будучи запущенной, EXEB захватывает указанное в командной строке
прерывание, запускает исследуемую задачу и начинает отсчитывать
обращения к указанной в командной строке функции захваченного
прерывания. Когда счетчик обращений станет равен 0, EXEB переносит
образ исследуемой задачи из оперативной памяти на диск. При этом
первой исполняемой командой задачи станет вызов указанного в командной
строке EXEB прерывания (int ??). Схематично последовательность работы
EXEB представлена на рис. 7.1 - 7.3.

После запуска задача EXEB выдает на экран сообщение о готовности
и ожидает нажатия любой клавиши. В этот момент пользователь при
желании может вставить дискету в дисковод (при исследовании задачи,
имеющей защиту по ключевой дискете).
ОСОБЕННОСТИ РАБОТЫ И НЕДОСТАТКИ
Результирующая задача TASK.EXE не всегда способна воспринять
командную строку, указанную в аргументе "CommandLine" при ее создании.
TASK.EXE должна запускаться примерно в той же среде, где она была
создана (объем свободной оперативной памяти). В случае какого-либо
несоответствия на экран выдается сообщение об этом и TASK.EXE
прекращает работу.
Так как EXEB "снимает" в файл TASK.EXE практически всю
оперативную память, то его объем может быть очень большим. Для
уменьшения размера TASK.EXE можно использовать утилиту CHSIZE, формат
запуска которой вы можете выяснить запустив ее без аргументов.

СХЕМА РАБОТЫ ПРОГРАММЫ EXEB.EXE
--------------------------------------------------------------¬
¦ ¦
¦ ЗАХВАТ ПРЕРЫВАНИЯ И ЗАПУСК ЗАДАЧИ ¦
¦ ¦
¦ --"¬ ¦
¦ ¦ ¦2 ¦
¦ -T----------------------T------T-+-----------¬ 1) Захват ¦
¦ ¦ a.exe int 10 ¦вирус ¦ EXEB ¦ обработки по¦
¦ -+----------------------+------+-------------- 10 вектору. ¦
¦ --"-----------"------------"--------- 2) Запуск ¦
¦ 10 вектор 1 задачи a.exe.¦
¦ ¦
¦ рис. 7.1 ¦
¦ ¦
¦ ¦
¦ ПЕРЕХВАТ УПРАВЛЕНИЯ ¦
¦ ¦
¦ -T----------------------T------T-------------¬ ¦
¦ ¦ a.exe int 10 ¦вирус ¦ EXEB ¦ ¦
¦ -+------------------T---+------+-------------- ¦
¦ ¦ ¦ ¦
¦ L-"-----"-----"--- ¦
¦ ¦
¦ рис. 7.2 ¦
¦ ¦
¦ ¦
¦ ЗАПИСЬ СОДЕРЖИМОГО ПАМЯТИ В ФАЙЛ ¦
¦ ¦
¦ -T----------------------T------T-------------¬ ¦
¦ ¦ a.exe int 10 ¦вирус ¦ EXEB ¦ ¦
¦ -+-----------------T----+------+-------------- ¦
¦ ¦ ¦ ¦
¦ ¦ ¦ ¦
¦ L=================¦====-" TASK.EXE (дискета) ¦
¦ ¦
¦ рис. 7.3 ¦
L--------------------------------------------------------------

8. ПРОВЕРКА УСВОЕННОГО
Если вы внимательно прочитали весь предшествующий материал, то
справиться с двумя головоломками будет несложно. Если же задания
оказались вам не под силу, вновь проштудируйте статьи.

ГОЛОВОЛОМКА 1
На рис. 8.1 приведена программа, которая не работает под
отладчиком в пошаговом режиме. Проверьте это, оттранслировав и
запустив ее, например, под Turbo Debugger. Нажимая клавишу F8 (без
захода в п/п), благополучно доберетесь до ее конца. Если же попробуете
пройти программу в потактовом режиме (клавиша F7), с заходом в
подпрограмму "DEL", то после выполнения оператора STOSW продолжение
будет невозможно. Почему?

ГОЛОВОЛОМКА 2
Программа на рис. 8.2 также не работает в пошаговом режиме, но
причина здесь иная. В чем тут дело?

ГОЛОВОЛОМКА 1
-------------------------------------------------------------¬
¦ cseg segment para public 'code' ¦
¦ assume cs:cseg ¦
¦ exam proc ¦
¦ start: ¦
¦ jmp frwd ¦
¦ del: ¦
¦ pushf ¦
¦ cld ¦
¦ mov ax,cs ¦
¦ mov es,ax ¦
¦ rep stosw ¦
¦ popf ¦
¦ ret

Список страниц

Закладка в соц.сетях

Купить

☏ Заказ рекламы: +380504468872

© Ассоциация электронных библиотек Украины

☝ Все материалы сайта (включая статьи, изображения, рекламные объявления и пр.) предназначены только для предварительного ознакомления. Все права на публикации, представленные на сайте принадлежат их законным владельцам. Просим Вас не сохранять копии информации.