3. Перехват и замена системных вызовов (syscall) Linux - это тема пройденная и известная.
Но хотелось бы это сделать ещё и не только на реальном железе, но и в среде виртуальной машины.
P.S. В чём здесь сложность и фишка?
В том, что сначала умельцы Линуса Торвальдса унесли адрес таблицы системных вызовов sys_call_table из числа экспортруемых символов ядра.
И решили что тем они сделали Linux сильно защищённым
Но этого показалось мало, и
позже они для страницы RAM размещения sys_call_table средствами диспетчера MMU установили правило доступа read-only. И если захочется модифицировать sys_call_table, то нужно сначала убрать флаг read-only, а потом вернуть его в зад.
![Подмигивает ;-)](./images/smilies/icon_e_wink.gif)
А для этого нужно писать в скрытые системные аппаратные регистры процессора x86 (на некоторых других платформах они пишут, что не применяется защита read-only).
Вот это нужно проверять.
Делаем тест, который
подменяет системный вызов sys_write (вывод на tty, printf(), __NR_write = 4) ... для проверки возможностей и так, чтобы не сильно навредить системе сразу
![Смеётся :lol:](./images/smilies/icon_lol.gif)
.
Этот тест только "шпионит" за вашим терминалом: всё что выводится на терминал, ещё и пишется параллельно в системный журнал ядра по printk():
Код: Выделить всё
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]
P.S. сам printk() работает тоже через системный вызов sys_write - там смешной код чтобы избежать бесконечной рекурсии ... в ядре
В итоге, я вас поздравляю ![Подмигивает ;-)](./images/smilies/icon_e_wink.gif)
: этот код одинаково хорошо работает как на реальном железе, так и в виртуально машине в VirtualBox.
Меня в этой задаче интересует конкретика - демонстрировать работу в
облачной виртуальной машине под управлением Cisco Maestro. Но всему своё время ... и, кроме того, я уже
предварительно (по-быстрому, по-верхам) уже проверил в такой
облачной виртуальной машине: а). закинуть туда wrog.tgz, б). собрать там
модуль ядра (могло не пойти сразу из-за хэдер-файлов ядра), в). выполнить тест ... Первое впечатление такое, что и там этот тест прошёл ОК.