Экспорт символов ядра и таблица системных вызовов

Вопросы программного кода и архитектуры Linux

Модератор: Olej

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Экспорт символов ядра и таблица системных вызовов

Непрочитанное сообщение Olej » 22 дек 2011, 18:37

А вот ещё курьёз! :lol:

Я спешу, а поэтому почти без комментариев:

Код: Выделить всё

#include <linux/module.h>
#include <linux/kallsyms.h>
#include <linux/uaccess.h>

static unsigned long waddr = 0;
static char buf[ 80 ];
static int len;

int symb_fn( void* data, const char* sym, struct module* mod, unsigned long addr ) {
   if( 0 == strcmp( (char*)data, sym ) ) {
      waddr = addr;
      return 1;
   }
   else return 0;
}

/* <linux/syscalls.h>
asmlinkage long sys_write(unsigned int fd, const char __user *buf,
                          size_t count); */
static asmlinkage long (*sys_write) (
   unsigned int fd, const char __user *buf, size_t count );

static int do_write( void ) {
   int n;
   mm_segment_t fs = get_fs();
   set_fs( get_ds() );
   sys_write = (void*)waddr;
   n = sys_write( 1, buf, len );
   set_fs(fs);
   return n;
}

static int __init wr_init( void ) {
   int n = kallsyms_on_each_symbol( symb_fn, (void*)"sys_write" );
   if( n != 0 ) {
      sprintf( buf, "адрес системного обработчика sys_write = %lx\n", waddr );
      len  = strlen( buf ) + 1;
      printk( "+ [%d]: %s", len, buf );
      n = do_write();
      printk( "+ write return : %d\n", n );
   }
   else
      printk( "+ %d: symbol not found\n", n );
   return -EPERM;
}

module_init( wr_init );
MODULE_LICENSE( "GPL" );
MODULE_AUTHOR( "Oleg Tsiliuric <olej@front.ru>" );
Вот такой модуль ядра.
Что он делает? А вот что он делает:

Код: Выделить всё

$ sudo insmod mod_wrc.ko
адрес системного обработчика sys_write = c04e12fc
insmod: error inserting 'mod_wrc.ko': -1 Operation not permitted
$ dmesg | tail -n30 | grep +
+ [77]: адрес системного обработчика sys_write = c04e12fc
+ write return : 77
Он делает то, то по теории и по всем пишущим по ядру делаться не может - он выводит текстовые строки диагностики, но не в системный журнал, а на графический терминал Х11!
Т.е. он делает вызов пользовательского системного вызова, то же, что делает и printf().
А значит подобным образом он сможет сделать и любой вызов стандарта POSIX.

А то, что он ещё и выводит в этот терминал русскоязычные UNICODE строки, так это уже совсем последнее из его умений на фоне остальных :lol:

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Экспорт символов ядра и таблица системных вызовов

Непрочитанное сообщение Olej » 31 дек 2011, 17:23

А вот полный архив примера модуля ядра, который после загрузки подменяет дефаултный обработчик системного вызова sys_write (write(2)).

Таким образом можно изменять стандартные системные вызовы Linux + добавлять свои (не место неиспользуемых в sys_call_table ... но там таких более, чем достаточно).

Об этом много-много-много пишут по интернетам, но в большинстве своём оно или не работоспособное, или мудрёно-перемудрёно. В этом примере всё достаточно просто.

Это, будем считать так, подарок от Деда Мороза к Новому Году :lol:
(при других обстоятельствах я бы, пожалуй, воздержался от его показа ;-) )
Вложения
mod_wrchg.tgz
(75.75 КБ) 581 скачивание

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Экспорт символов ядра и таблица системных вызовов

Непрочитанное сообщение Olej » 31 дек 2011, 17:41

Olej писал(а): Об этом много-много-много пишут по интернетам, но в большинстве своём оно или не работоспособное, или мудрёно-перемудрёно.
Во многих случаях неработоспособность связана с тем, что с некоторого ядра (я не могу сказать с какого, но это где-то с 2.6.2х или около того) таблица адресов системных вызовов sys_call_table находится в сегменте только для чтений, и попытка записи в неё приводит к ошибке защиты памяти (вот то R):

Код: Выделить всё

$ cat /proc/kallsyms | grep sys_call_table 
c07ab3d8 R sys_call_table
Обходят это или замещая сами начальные команды функции системного обработчика ... но это и мудрёно и грубо...

... или просто снимая защиту от записи на время изменения:
Olej писал(а): В этом примере всё достаточно просто.
Такого нельзя сделать в пользовательском процесс (кольцо защиты процессора 3), но в модуле мы в кольце 0, режим супервизора, здесь можно всё :!: :-o

Код: Выделить всё

//код выключения защиты записи:
#define rw_enable()              \
asm( "pushl %eax \n"             \
     "movl %cr0, %eax \n"        \
     "andl $0xfffeffff, %eax \n" \
     "movl %eax, %cr0 \n"        \
     "popl %eax" );

//код включения защиты записи:
#define rw_disable()             \
asm( "pushl %eax \n"             \
     "movl %cr0, %eax \n"        \
     "orl $0x00010000, %eax \n"  \
     "movl %eax, %cr0 \n"        \
     "popl %eax" );
Это только для 32-разрядного режима: 16-й бит WP в управляющем регистре процессора CR0.
Для 64-разрядного режима всё будет по-другому:
- должны использоваться 64-разрядные операции (суффикс q команд AT&T);
- вместо регистра %eax должен определяться регистр %rax;
- другой бит CR0 (64-разрядного!) ответственный за защиту записи, утверждается, что это должно быть (я это не проверял):

Код: Выделить всё

asm( "andq $0xfffffffffffeffff, %rax" ); 
...
asm( "orq $0x0000000000001000, %rax" );  

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Экспорт символов ядра и таблица системных вызовов

Непрочитанное сообщение Olej » 12 янв 2012, 20:04

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

В чём там сложность? В том, что:
- таблица системных вызовов sys_call_table имеет фиксированный размер;
- размерность этой таблицы 0 ... __NR_syscall_max меняется от версии ядра к версии;
- более того, __NR_syscall_max это defined константа периода компиляции, которая в исполняющейся системе неизвестна (по крайней мере, мне неизвестна - я не нашёл такого способа)...
- увеличивать размер таблицы нельзя.

Но смягчает эти ограничения то, что таблица sys_call_table неплотная, в ней достаточно много неиспользуемых позиций (устаревших, заменённых или резервированных на будущее вызовов). И во всех этих позициях будет записан адрес обработчика

Код: Выделить всё

$ cat /proc/kallsyms | grep sys_ni_syscall 
c045b9a8 T sys_ni_syscall 
В архиве прилагаемом 2 модуля:

Код: Выделить всё

[olej@notebook add_sys]$ ls
add-sys.c  add-sys.hist  Makefile  ni-test.c  syscall.c  syscall.h
- ni-test.c - который показывает неиспользуемые позиции sys_call_table;
- add-sys.c - который размещает обработчик нового системного вызова в одну из неиспользуемых позиций (по выбору);
+ там же программа syscall.c которая делает такие системные вызовы для тестирования.
Вложения
add_sys.tgz
(3.54 КБ) 576 скачиваний

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Экспорт символов ядра и таблица системных вызовов

Непрочитанное сообщение Olej » 12 янв 2012, 20:15

Olej писал(а): - ni-test.c - который показывает неиспользуемые позиции sys_call_table;
- add-sys.c - который размещает обработчик нового системного вызова в одну из неиспользуемых позиций (по выбору);
+ там же программа syscall.c которая делает такие системные вызовы для тестирования.
А вот как это в работе:

Код: Выделить всё

[olej@notebook add_sys]$ sudo insmod ni-test.ko
insmod: error inserting 'ni-test.ko': -1 Operation not permitted
[olej@notebook add_sys]$ dmesg | tail -n 18 | grep !
! найдено 26 входов: 017, 031, 032, 035, 044, 053, 056, 058, 098, 112, 127, 130, 137, 167, 188, 189, 222, 223, 251, 273, 274, 275, 276, 285, 294, 317, 
Вот они, сколько, неиспользуемых системных вызовов (до 10% от всех), в каждой установленной системе-дистрибутиве этот вывод будет отличаться (!).

А это добавленный системный вызов ... без комментариев ;-) :

Код: Выделить всё

[olej@notebook add_sys]$ ./syscall 
syscall return 38 : Function not implemented
[olej@notebook add_sys]$ sudo insmod add-sys.ko
[olej@notebook add_sys]$ lsmod | grep 'sys'
add_sys                 1432  0 
[olej@notebook add_sys]$ dmesg | tail -n 30 | grep !
! адрес sys_call_table = c07ab3d8
! адрес в позиции 223[__NR_own] = c045b9a8
! адрес sys_ni_syscall = c045b9a8
! адрес нового sys_call = fdd7c024
[olej@notebook add_sys]$ ./syscall новые аргументы
syscall return 0 : Success
syscall return 0 : Success
[olej@notebook add_sys]$ dmesg | tail -n 30 | grep !
! адрес sys_call_table = c07ab3d8
! адрес в позиции 223[__NR_own] = c045b9a8
! адрес sys_ni_syscall = c045b9a8
! адрес нового sys_call = fdd7c024
! передано 18 байт: аргументы
! передано 10 байт: новые
[olej@notebook add_sys]$ sudo rmmod add-sys 
[olej@notebook add_sys]$ dmesg | tail -n 50 | grep !
! адрес sys_call_table = c07ab3d8
! адрес в позиции 223[__NR_own] = c045b9a8
! адрес sys_ni_syscall = c045b9a8
! адрес нового sys_call = fdd7c024
! передано 18 байт: аргументы
! передано 10 байт: новые
! адрес sys_call при выгрузке = fdd7c024
[olej@notebook add_sys]$ ./syscall 1 2 3
syscall return 38 : Function not implemented
syscall return 38 : Function not implemented
syscall return 38 : Function not implemented
- как только модуль выгружается, программа выполняет вызов с ошибками: Function not implemented

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Экспорт символов ядра и таблица системных вызовов

Непрочитанное сообщение Olej » 12 янв 2012, 21:01

И ещё смешнее штука:

- Вопрос: можно ли изменить системный вызов (из модуля) так, чтобы система "не заметила"? своими средствами диагностики: lsmod, /proc etc. (мечта каждого вирусописателя).

- Ответ: можно.

И вот как это выглядит:

Код: Выделить всё

[olej@notebook hidden.1]$ ./syscall 123
syscall return 38 : Function not implemented
[olej@notebook hidden.1]$ sudo insmod hidden.ko
insmod: error inserting 'hidden.ko': -1 Operation not permitted
[olej@notebook hidden.1]$ ./syscall 123
syscall return 0 : Success
[olej@notebook hidden.1]$ lsmod | grep hidden
[olej@notebook hidden.1]$ sudo insmod restore.ko
insmod: error inserting 'restore.ko': -1 Operation not permitted
[olej@notebook hidden.1]$ ./syscall 123
syscall return 38 : Function not implemented
И не важно, что:
- в данном случае обработчик вызова №23 ничего не делает... там нет реального кода, только возврат кода нормального завершения...
- и что такой код сильно трудно написать, потому как к внешним именам (вызываемым функциям API) нельзя обращаться по именам - их смещения "поплыли"...
Важно то, что это принципиально возможно ... а значит следует ожидать, что такое вредительство наверняка появится :lol: .
Вложения
hidden.tgz
(81.84 КБ) 573 скачивания

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Экспорт символов ядра и таблица системных вызовов

Непрочитанное сообщение Olej » 18 янв 2012, 18:07

Olej писал(а):И ещё смешнее штука:

- Вопрос: можно ли изменить системный вызов (из модуля) так, чтобы система "не заметила"? своими средствами диагностики: lsmod, /proc etc. (мечта каждого вирусописателя).

- Ответ: можно.
Или вот: улучшенный ;-) вариант такого примера.
Там несколько разных обработчиков нового системного вызова ... показывающих, насколько сложно и изощрённо нужно писать такой код (фактически, это написание вручную, без gcc, PIC кода, который должен свободно перемещаться по памяти).
Но вот один из вариантов:

Код: Выделить всё

[olej@notebook hidden]$ sudo insmod hidden.ko
insmod: error inserting 'hidden.ko': -1 Operation not permitted
[olej@notebook hidden]$ lsmod | grep hid
[olej@notebook hidden]$ ./syscall 1 23 456 'новая строка'
новая строка
syscall return 24 [00000018], reason: Success
456
syscall return 4 [00000004], reason: Success
23
syscall return 3 [00000003], reason: Success
1
syscall return 2 [00000002], reason: Success
Как легко видеть, Linux ничего не знает и не подозревает о существовании ни модуля (2-я команда), ни обработчика системного с номером 223. Но тестовая программа ./syscall замечательным образом пользует этот системный вызов, а тот, более того, ещё и делает то, что модуль делать не должен: вывод не в системный журнал, а на терминал :-o (не извольте сомневаться, что нечётные строки в листинге выпечатаны прямо из ядра ;-) ).
Это уже прям как в известной истории:
Ты суслика видишь? И я не вижу. А он - есть!
:lol:
Вложения
hidden.tgz
(5.26 КБ) 570 скачиваний

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Экспорт символов ядра и таблица системных вызовов

Непрочитанное сообщение Olej » 24 июн 2015, 07:39

Olej писал(а):А вот полный архив примера модуля ядра, который после загрузки подменяет дефаултный обработчик системного вызова sys_write (write(2)).
Прошло 3 года ;-) ... и снова возникла на практике задача подмены системных вызовов ядра ;-) .
Теперь в связи с затеей Implementing a Distributed Firewall и необходимостью модифицировать системные вызовы для сетевых операция accept() и connect().
Задача оказалась не так проста, как кажется ... там есть несколько приятных нюансов ;-)
И есть о чём поговорить и что потестировать в связи с подменой системных вызовов.

P.S. тем более, что по старым примерам вижу по ~300 скачиваний ;-) ... т.е. теперь их самое время освежить и модифицировать.

Но не заводить же по этому поводу отдельную тему? ;-)

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Экспорт символов ядра и таблица системных вызовов

Непрочитанное сообщение Olej » 24 июн 2015, 08:41

Olej писал(а): Задача оказалась не так проста, как кажется ... там есть несколько приятных нюансов ;-)
Вот свеженький пример подмены всё того же системного вызова sys_wrte, который отвечает за wrte(2) и, в конечном итоге, за вывод на терминал printf(3):

Код: Выделить всё

#include <linux/module.h>
#include <linux/kallsyms.h>
#include <linux/uaccess.h>
#include <linux/unistd.h>

#include "./find.c"
#include "./CR0.c"

#define ERR(...) printk( KERN_ERR "! "__VA_ARGS__ )

asmlinkage long (*old_sys_write) ( unsigned int fd, const char __user *buf, size_t count );

asmlinkage long new_sys_write ( unsigned int fd, const char __user *buf, size_t count ) {
   if( 1 == fd ) {
      static char msg[ 160 ];
      int n = count < sizeof( msg ) ? count : sizeof( msg ) - 1,
          r = copy_from_user( msg, (void*)buf, n );
      if( '!' == msg[ 0 ] ) goto rec;
      msg[ n ] = '\0';
      if( '\n' == msg[ n - 1 ] ) msg[ n - 1 ] = '\0';
      if( strchr( msg, '!' ) != NULL ) goto rec; // to prevent recursion
      printk( "! {%04d} %s\n", count, msg );
   }
rec:
   return old_sys_write( fd, buf, count );
};
EXPORT_SYMBOL( new_sys_write );

static void **taddr;                             // address of sys_call_table 

static int __init wrchg_init( void ) {
   void *waddr; 
   if( NULL == ( taddr = find_sym( "sys_call_table" ) ) ) {
      ERR( "sys_call_table not found\n" ); return -EINVAL;
   }
   old_sys_write = (void*)taddr[ __NR_write ];
   if( NULL == ( waddr = find_sym( "sys_write" ) ) ) {
      ERR( "sys_write not found\n" ); return -EINVAL;
   }
   if( old_sys_write != waddr ) {
      ERR( "Oooops! : addresses not equal\n" ); return -EINVAL;
   }
   printk( "! set new sys_write syscall [%p]\n", &new_sys_write );
   show_cr0();
   rw_enable();
   taddr[ __NR_write ] = new_sys_write;
   show_cr0();
   rw_disable();
   show_cr0();
   return 0;
}

static void __exit wrchg_exit( void ) {
   rw_enable();
   taddr[ __NR_write ] = old_sys_write;
   rw_disable();
   printk( "! restore old sys_write syscall [%p]\n", (void*)taddr[ __NR_write ] );
   return;
}

module_init( wrchg_init );
module_exit( wrchg_exit );

MODULE_LICENSE( "GPL" );
MODULE_AUTHOR( "Oleg Tsiliuric <olej@front.ru>" );


Теперь всё, что выводится на терминал, параллельно пишется printk() в журнал ядра.
Шпионит... ;-)

Самое удивительное здесь место, что нужно избежать бесконечной (почти ;-) ) рекурсии, поскольку printk() каким-то образом тоже использует write() ... что и стоило ожидать, но разбираться глубже я не стал.

Но интересно то, что это делалось как практический пример для проверки возможности (корректности) перехвата и подмены системных вызовов не только в реальной инсталляции на железе, но и в виртуальной машине в VirtualBox ... а также в облачной виртуальной машине созданной средствами такого инстумента как Cisco Maestro.
Так вот, я вас поздравляю ;-) : в VirtualBox это всё происходит так же, как на реальном железе.

Это очень хорошая новость ... потому как подобные рисковые штучки можно тренировать в VirtualBox.

Вот это - VirtualBox:

Код: Выделить всё

olej@ubuntu:~/WORK_2015/FWall/drivers/wrlog$ dmesg | tail -n13
[ 6103.858156] ! set new sys_write syscall [e1a03030]
[ 6103.858775] ! CR0 = 8005003b
[ 6103.859252] ! CR0 = 8004003b
[ 6103.859345] ! CR0 = 8005003b
[ 6103.871976] ! {0041} /home/olej/WORK_2015/FWall/drivers/wrlog
[ 6103.875946] ! {0094} \x1b]0;olej@ubuntu: ~/WORK_2015/FWall/drivers/wrlog\x07olej@ubuntu:~/WORK_2015/FWall/drivers/wrlog$
[ 6104.523854] ! {0020} sudo insmod wrlog.ko
[ 6105.028481] ! {0027} \x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08make\x1b[K
[ 6107.230753] ! {0021} \x08\x08\x08\x08dmesg | tail -n33
[ 6108.470280] ! {0004} \x08\x0813
[ 6109.211730] ! {0036} \x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08sudo rmmod wrlog.ko
[ 6111.618226] ! {0002}
[ 6111.705243] ! restore old sys_write syscall [c1144d20]

Что за такие всякие удивительные штучки как \x08 ?
Я тоже на это в недоумении смотрел :-o ... А это те "стрелка вверх" которыми я прокручивал на терминале предыдущие команды в поисках rmmod...

А вот это - реальное железо:

Код: Выделить всё

olej@nvidia ~ $ lsb_release -ircd
Distributor ID: LinuxMint
Description:    Linux Mint 17.1 Rebecca
Release:        17.1
Codename:       rebecca

Код: Выделить всё

olej@nvidia ~/2015_WORK/in.WORK/FWall/drivers/wrlog $ sudo insmod wrlog.ko
olej@nvidia ~/2015_WORK/in.WORK/FWall/drivers/wrlog $ sudo rmmod wrlog
olej@nvidia ~/2015_WORK/in.WORK/FWall/drivers/wrlog $ dmesg | tail -n25
[ 1220.476585] device eth0 entered promiscuous mode
[ 7850.815396] ! set new sys_write syscall [f8bff000]
[ 7850.815399] ! CR0 = 8005003b
[ 7850.815401] ! CR0 = 8004003b
[ 7850.815402] ! CR0 = 8005003b
[ 7850.817121] ! {0049} /home/olej/2015_WORK/in.WORK/FWall/drivers/wrlog
[ 7850.817483] ! {0075} \x1b[01;32molej@nvidia\x1b[01;34m ~/2015_WORK/in.WORK/FWall/drivers/wrlog $\x1b[00m
[ 7853.997031] ! {0001} s
[ 7854.301131] ! {0001} u
[ 7854.541040] ! {0001} d
[ 7854.901050] ! {0001} o
[ 7857.934642] ! {0001}
[ 7858.317047] ! {0001} r
[ 7859.061051] ! {0001} m
[ 7859.284676] ! {0001} m
[ 7860.268919] ! {0001} o
[ 7860.884974] ! {0001} d
[ 7862.149085] ! {0001}
[ 7863.748656] ! {0001} w
[ 7864.005039] ! {0001} r
[ 7865.141581] ! {0001} l
[ 7865.453121] ! {0001} o
[ 7865.925047] ! {0001} g
[ 7866.910978] ! {0002}
[ 7866.917365] ! restore old sys_write syscall [c1179f70]
А вот здесь команда rmmod набиралась на терминале посимвольно.

NB Ещё раз повторю: экспериментировать с таким кодом можно только если вы хорошо понимаете что делаете на каждом щагу. Разнести при похожих действиях свою операционную систему - элементарно. ... Но вы предупреждены, значит вооружены! :lol:
Вложения
wrlog.tgz
(4.97 КБ) 286 скачиваний

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Экспорт символов ядра и таблица системных вызовов

Непрочитанное сообщение Olej » 24 июн 2015, 08:59

Olej писал(а): Вот свеженький пример подмены всё того же системного вызова sys_wrte, который отвечает за wrte(2) и, в конечном итоге, за вывод на терминал printf(3):
Вам пишут в книжках и статьях и рассказывают преподаватели, что в Linux после ядра 2.6 таблица системных вызовов не экспортируется, её нельзя подменять, и это ... якобы ... по мнению Линуса Торвальдса ... способствует большей защищённости системы?
Это неправда! :lol:

Логика здесь такая:

1. ищем адрес таблицы системных вызовов - фай find.c:

Код: Выделить всё

static void* find_sym( const char *sym ) {  // find address kernel symbol sym
   static unsigned long faddr = 0;          // static !!!
   // ----------- nested functions are a GCC extension ---------
   int symb_fn( void* data, const char* sym, struct module* mod, unsigned long addr ) {
      if( 0 == strcmp( (char*)data, sym ) ) {
         faddr = addr;
         return 1;
      }
      else return 0;
   };
   // --------------------------------------------------------
   kallsyms_on_each_symbol( symb_fn, (void*)sym );
   return (void*)faddr;
}
2. зная номер своего системного вызова (например __NR_write) отсчитываем его в массиве таблицы системных вызовов...

3. в архитектуре i686 / X86_64 они ещё начудили тем, что страницу RAM размещения таблицы системных вызовов сделали read-only средствами MMU...
Но мы в модуле находимся в режиме супервизора, кольцо защиты 0, и можемснимать и позже восстанавливать защиту записи - файл CR0.c :

Код: Выделить всё

// page write protect - on
#define rw_enable()              \
asm( "pushl %eax \n"             \
     "movl %cr0, %eax \n"        \
     "andl $0xfffeffff, %eax \n" \
     "movl %eax, %cr0 \n"        \
     "popl %eax" );

// page write protect - off
#define rw_disable()             \
asm( "pushl %eax \n"             \
     "movl %cr0, %eax \n"        \
     "orl $0x00010000, %eax \n"  \
     "movl %eax, %cr0 \n"        \
     "popl %eax" );
Это код для 32 бит! Для 64 бит он будет другой...
Это для "любителей" ассемблера - плата за эту любовь. :lol:

4. Вот это место - запись в аппаратные внутренние административные регистры процессора - и было для меня сомнительным местом в смысле выполнения в виртуальной машине...
Но VirtualBox успешно съел это место.
И это мест является отличной проверкой на вшивость других систем виртуализации.

Ответить

Вернуться в «Linux изнутри»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 13 гостей