Содержание статьи
Одно из основных направлений в "битве умов" между авторами компьютерных
вирусов и антивирусных программ связано с размещением тела вируса в оперативной
памяти. На первый взгляд, все банально: задача вируса – спрятаться так, чтобы не
нашли, задача антивируса – найти. В ходе эволюции технологий, используемых как
для написания вредоносных программ, так и для противодействия им, появились
достаточно нетривиальные решения. Поле деятельности уже давно не ограничивается
механизмами управления памятью, входящими в состав операционной системы.
Сегодня, для того, чтобы быть "на уровне", авторам, как вирусов, так и
антивирусов необходимо понимание принципов взаимодействия программ и
оборудования, таких как работа с конфигурационными регистрами чипсета,
Model-Specific регистрами процессора (MSR), использование областей памяти,
имеющих специальный статус с точки зрения контроллера памяти (SMRAM, Shadow и
т.п.).
Автор данной статьи не является вирусологом и тем более "вирусописателем", а
работает в области разработки аппаратного и системного программного обеспечения.
Поэтому предлагаемый материал подготовлен как информация о потенциальной
уязвимости, дающей возможность вирусу "спрятаться" нетривиальным методом. Речь
идет об использовании "теневой" памяти или Shadow RAM и представлении вируса в
статусе части выполняемого блока BIOS.
Как все начиналось
Около двух десятилетий назад, когда у процессоров еще не было Model-Specific
регистров, а вместо чипсета использовались микросхемы "мелкой логики", для
размещения вируса использовалась схема, упоминание о которой сегодня может
вызвать иронию у многих специалистов, в силу ее простоты и наивности. Но для
полноты изложения, вспомним и о ней.
Как известно BIOS материнской платы использует 256-байтный блок переменных в
ОЗУ по адресам 00400h-004FFh. Одна из переменных, а именно 16-битное слово по
адресам 00413h-00414h хранит значение размера "нижней" памяти в килобайтах.
Например, если в системе 640 Кб, то значение этой переменной равно 0280h.
Операционная система, для получения доступного размера нижней памяти вызывает
прерывание INT 12h, процедура обработки которого входит в состав BIOS. Эта
процедура возвращает в регистре AX значение рассматриваемой переменной.
Если вирус получает управление до того, как операционная система запросит
размер памяти у BIOS (например, если тело вируса расположено в загрузочном
секторе диска), он может уменьшить значение этой переменной, например с 280h до
27Fh. Это приведет к тому, что ОС и программы не будут использовать последний
килобайт "нижней" памяти по адресам 9FC00h-9FFFFh и там может расположиться
вирус. Разумеется, авторы антивирусов отреагировали адекватно и научились
находить вирусы, спрятавшиеся таким образом.
Использование Shadow RAM
Этот метод значительно эффективнее, но и значительно сложнее рассмотренного
выше. Здесь требуется работа с регистрами MSR и конфигурационными регистрами
чипсета. Выполняемые действия будут различными, в зависимости от модели
процессора и набора системной логики, поэтому потребуется детектирование
платформы. В результате всех этих усилий вирус становится частью выполняемого
кода BIOS, а как распорядится подобным статусом – дело фантазии
"вирусописателя". Сразу оговоримся, что речь идет не о модификации содержимого
ПЗУ BIOS (Flash ROM), а о модификации области оперативной памяти Shadow RAM,
куда переписывается содержимое ПЗУ BIOS на время рабочего сеанса. Поэтому речь о
выводе из строя материнской платы здесь не идет.
В данной статье, автор сконцентрировал внимание исключительно на вопросах
снятия защиты записи Shadow RAM. Разумеется, это только часть дела. Вирус также
должен уметь находить неиспользуемые области в памяти (по понятным причинам,
протоколы управления памятью операционной системы, здесь не применимы),
использовать механизмы активации, срабатывающие, например, при вызове
определенных функций BIOS и т.п.
Напомним, что диапазон адресов C0000h-EFFFFh (768-960 KB) используется для
размещения в ОЗУ выполняемого блока BIOS периферийных адаптеров, диапазон
F0000h-FFFFFh (960-1024 KB) для выполняемого блока системного BIOS (приведено
распределение адресов, имеющее место в большинстве платформ, иногда бывают
некоторые отклонения).
Перейдем к практике. Если мы попытаемся изменить содержимое какой-либо ячейки
памяти, относящейся к указанному диапазону адресов, выполнив, например
инструкции:
mov ax,0F000h
mov ds,ax
xor bx,bx
mov ax,1234h
mov ds:[bx],ax ; Запись
mov ax,ds:[bx] ; Контрольное считывание
то увидим, что содержимое перезаписываемой ячейки не изменилось в результате
перезаписи. Почему так происходит, ведь по указанному адресу находится
оперативная память (Shadow RAM)? Дело в том, что большинство платформ, для
корректной эмуляции ПЗУ, используют специальные аппаратные средства,
обеспечивающие защиту данной области ОЗУ от записи. Защиту включает BIOS перед
загрузкой ОС, естественно, после того как копирование (или распаковка)
выполняемого блока в ОЗУ завершена. Остановимся подробнее на снятии такой
защиты. Как уже было сказано выше, набор действий, которые надо выполнить,
зависит от модели процессора и чипсета. Рассмотрим два примера. Предлагаемые
процедуры для иллюстрации снятия защиты Shadow RAM записывают 16 байт со
значением 11h в диапазон F0000h-F000Fh.
Эксперимент 1.
Платформа Intel. Процессор класса Socket 775 (Celeron-D 2.66 GHz), чипсет
Intel 915, материнская плата Gigabyte GA-8i915PL-G.
; Изменяем статус PAM
cli
mov ax,0B108h ; PCIBIOS Function 8 = Read Byte
xor bx,bx ; Bus=0, Device=0, Function=0
mov di,0090h ; Register=90h (PAM0)
int 1Ah
push cx ; Save PAM0
or cl,00110000b ; Bits[5,4]=11b, RAM mode
mov ax,0B10Bh ; PCIBIOS Function 8 = Write Byte
xor bx,bx ; Bus=0, Device=0, Function=0
int 1Ah
; Заполняем 16 байт константой 11h
mov ax,0F000h
mov es,ax
xor di,di ; ES:DI = Address
mov cx,0010h ; CX = Length
mov al,11h ; AL = Data
cld
rep stosb
; Восстанавливаем статус PAM и когерентность кэш
pop cx ; Restore old value PAM0
mov ax,0B10Bh ; PCIBIOS Function 8 = Write Byte
xor bx,bx ; Bus=0, Device=0, Function=0
mov di,0090h ; Register=90h (PAM0)
int 1Ah
sti
wbinvd ; Write-Back and Invalidate cache
В основе работы программы лежит управление атрибутами диапазона адресов
F0000h-F0FFFh (4 Кбайт) посредством регистров PAM (Programmable Attribute Map),
входящими в состав "северного моста" чипсета. Область Shadow RAM, расположенная
по адресам C0000h-FFFFFh, разбита на диапазоны, за каждым из диапазонов
закреплен свой регистр PAM. Таблица соответствия диапазонов и регистров, а также
другие подробности содержатся в [6].
Программный доступ к регистрам PAM, как и ко всем другим конфигурационным
регистрам, осуществляется через конфигурационное пространство, в соответствии со
спецификацией PCI. Подробности в [16-17]. В программе используются сервисные
функции PCIBIOS (прерывание 01Ah, функция 0B1h) для доступа к конфигурационным
регистрам. Подробности в [15].
Если диапазон адресов, статус которого мы изменили, является кэшируемым, то
мы должны принять меры во избежание расхождения информации в кэш памяти и ОЗУ,
то есть обеспечить когерентность кэш. Для этого используется инструкция WBINVD,
подробности в [3]. Кэшируемость диапазонов зависит от содержимого регистров MTRR
(Memory Type Range Registers), которые инициализирует BIOS при старте.
Подробности в [4-5].
Интервал времени, в течение которого содержимое регистров PAM находится в
измененном состоянии, отрабатывается с запрещенными прерываниями. Используются
инструкции CLI и STI. Подробности в [2-3]. Так сделано не случайно, при отладке
автор заметил, что при использовании некоторых сервисных функций BIOS, состояние
регистров PAM для сегмента F0000h автоматически восстанавливается, то есть BIOS
периодически возвращает старое значение. Поэтому если мы, например,
перепрограммируем PAM, а затем попытаемся редактировать Shadow RAM в каком-либо
отладчике в режиме дампа, мы можем столкнуться с проблемой – память через
некоторое время перестанет быть перезаписываемой. Для редактирования Shadow RAM
в режиме дампа потребуется написать собственную программу, которая будет
перепрограммировать PAM при записи каждого байта или блока байтов.
В приведенном примере мы работаем с диапазоном адресов Main BIOS Shadow,
который в исходном состоянии инициализирован как Read-Only, согласно атрибутам
PAM циклы чтения направляются на шину памяти, циклы записи – на шину
ввода-вывода, подробности в [6]. Поэтому, после восстановления, диапазон,
содержащий выполненные нами модификации, будет доступен для чтения. Но если мы
изменяем статус не используемого диапазона Shadow RAM (например, в сегменте
D0000h), то следует помнить, что в исходном состоянии он может быть закрыт как
для записи, так и для чтения. Поэтому, чтобы наш вирус остался доступным в
адресном пространстве, следует установить режим Read-Only или Read-Write, а не
восстанавливать исходное состояние PAM.
Отметим, что если вирус расположен в диапазоне со статусом Read-Only, удалить
его из памяти, мягко говоря, затруднительно. Для этого антивирус должен иметь
библиотеку процедур поддержки чипсетов.
Эксперимент 2.
Платформа AMD. Процессор класса Socket 754 (Sempron 3000+), чипсет VIA
K8T800, материнская плата Gigabyte GA-K8VT800.
; Изменяем статус MTRR для разрешения записи в Shadow RAM
cli
mov ecx,0C0010010h ; Адрес регистра SYS_CFG MSR
rdmsr
push eax
push edx
bts eax,19 ; RdDRAM, WrDRAM visible = 1
wrmsr
mov ecx,0000026Eh ; Адрес регистра IA32_MTRR_FIX4K_F000 MSR
rdmsr ; Read MSR to EDX:EAX
push eax ; Save old value
push edx
or al,00011000b ; RdDRAM=1, WrDRAM=1
wrmsr
; Заполняем 16 байт константой 11h
mov ax,0F000h
mov es,ax
xor di,di
mov cx,0010h
mov al,11h
cld
rep stosb
; Восстанавливаем статус MTRR и когерентность кэш
pop edx ; Restore old value
pop eax
mov ecx,0000026Eh ; Адрес регистра IA32_MTRR_FIX4K_F000 MSR
wrmsr
pop edx ; Restore old value
pop eax
mov ecx,0C0010010h ; Адрес регистра SYS_CFG MSR
wrmsr
sti
wbinvd ; Write-Back and Invalidate cache
Здесь, как и в примере для платформы Intel, приведенном ранее, работа
выполняется по схеме: разрешаем запись в Shadow RAM, выполняем запись,
восстанавливаем исходное состояние контроллера памяти. Но для платформы AMD, в
отличие от Intel, разрешение записи и направление шинных циклов на шины памяти и
ввода-вывода осуществляется за счет расширенной функциональности регистров MTRR.
Область Shadow RAM, расположенная по адресам C0000h-FFFFFh, разбита на
диапазоны, за каждым из диапазонов закреплено свое битовое поле в блоке
регистров MTRR. Таблица соответствия диапазонов и битовых полей MTRR, а также
другие подробности содержаться в [8] и [12-14].
Регистры MTRR расположены в пространстве регистров MSR (Model Specific
Registers). Для доступа к ним используются инструкции RDMSR, WRMSR. Подробности
в [8-9]. Замечания по необходимости запрета прерываний на время модификации и
обеспечению когерентности кэш, приведенные в первом примере, актуальны и здесь.
Использование SMRAM
Память System Management RAM и методы проникновения в нее были описаны в
ранее опубликованной статье "SMM
и SMRAM или 128Кб потусторонней памяти. Исследовательская работа № 5 и
6". По сравнению с
использованием Shadow RAM, использование SMRAM и режима SMM дает больше
возможностей, как с точки зрения функциональности вируса, так и его маскировки.
Вместе с тем, использование Shadow RAM можно рассматривать как компромисс – этот
метод значительно проще и здесь значительно меньше причин для несовместимости с
различными платформами.
Модификация BIOS ROM
В ранее опубликованной статье "Программно-аппаратные
угрозы или хрупкий мир глазами "железячника" № 1 и
2" были рассмотрены
вопросы, связанные с разрушением содержимого BIOS ROM вирусами, методы
минимизации такой угрозы, а также восстановление работоспособности материнской
платы в случае, если это уже произошло. Напомним, там речь шла о "затирании"
BIOS, приводящем к отсутствию старта материнской платы.
Вместе с тем, теоретически, существует возможность и для более деликатного
вмешательства, при котором функциональность BIOS сохраняется, но в него
дописывается некоторый фрагмент, выполняющий заданные функции.
В силу того, что содержимое BIOS ROM существенно различается у разных
платформ и здесь не существует единых стандартов, возможность написания такой
программы, совместимой со всеми существующими платформами, автор оценивает
скептически. Вместе с тем, для частного случая (для одной заданной платформы с
заданной версией BIOS), задача вполне решаема.
Прилагаемые файлы
Ассемблерные примеры, рассмотренные в статье содержаться
в прилагаемом каталоге WORK. Как и в ранее опубликованных статьях данного
цикла, в целях монопольного и беспрепятственного взаимодействия программы с
аппаратным обеспечением автор применил "древнюю" технологию отладки под DOS.
Аргументация такого шага и рекомендации по организации рабочего места приведены
в ранее опубликованной статье "64-битный
режим под DOS: исследовательская работа № 1".
Заключение
Разумеется, предлагаемый материал не позиционируется как "справочник
практикующего вредителя". Знания об уязвимостях и их использовании полезны
авторам не только вирусов, но и антивирусных программ, а также другим
специалистам, работающим в области информационной безопасности. К тому же,
многие из предложенных технологий могут быть использованы и в "мирных целях",
например, при отладке системного программного обеспечения. При проектировании
материнских плат и отладке опытных образцов, для программистов, занимающихся
написанием BIOS, возможность внесения изменений в процедуры Runtime блока в
Shadow RAM прямо в сеансе ОС, без "перешивки" Flash и перезагрузки компьютера,
может существенно уменьшить трудоемкость отладки указанных процедур, сократив
сроки и стоимость выполнения проекта.
Источники информации
Электронные документы, доступные на сайте
developer.intel.com.
1) Intel 64 and IA-32 Architectures Software Developer’s Manual. Volume 1:
Basic Architecture. Order Number 253665-023US.
2) Intel 64 and IA-32 Architectures Software Developer’s Manual. Volume 2A:
Instruction Set Reference, A-M. Order Number 253666-023US.
3) Intel 64 and IA-32 Architectures Software Developer’s Manual. Volume 2B:
Instruction Set Reference, N-Z. Order Number 253667-023US.
4) Intel 64 and IA-32 Architectures Software Developer’s Manual. Volume 3A:
System Programming Guide, Part 1. Order Number 253668-023US.
5) Intel 64 and IA-32 Architectures Software Developer’s Manual. Volume 3B:
System Programming Guide, Part 2. Order Number 253669-023US.
6) Intel 915G/915P Express Chipset Datasheet. Document Number 301467-001.
Электронные документы, доступные на сайте
developer.amd.com.
7) AMD64 Architecture Programmer’s Manual. Volume 1: Application Programming.
Publication No. 24592.
8) AMD64 Architecture Programmer’s Manual. Volume 2: System Programming.
Publication No. 24593.
9) AMD64 Architecture Programmer’s Manual. Volume 3: General-Purpose and System
Instructions. Publication No. 24594.
10) AMD64 Architecture Programmer’s Manual. Volume 4: 128-Bit Media Instructions.
Publication No. 26568.
11) AMD64 Architecture Programmer’s Manual. Volume 5: 64-Bit Media and x87
Floating-Point Instructions. Publication No. 26569.
12) BIOS and Kernel Developer’s Guide for AMD Athlon 64 and AMD Opteron
Processors. Publication No. 26094.
13) BIOS and Kernel Developer’s Guide for AMD NPT Family 0Fh Processors.
Publication No. 32559.
14) BIOS and Kernel Developer’s Guide (BKDG) For AMD Family 10h Processors.
Publication No. 31116.
Электронные документы, доступные на сайте
pcisig.com.
Документы [16], [17] на сайте pcisig.com доступны только для членов PCI
Special Interest Group. Воспользовавшись поисковыми системами, можно найти
данные документы для свободной загрузки.
15) PCI BIOS Specification. Revision 2.1.
16) PCI Local Bus Specification. Revision 3.0.
17) PCI-to-PCI Bridge Architecture Specification. Revision 1.1.