LINUX.ORG.RU

Расширение количества сист вызовов


0

0

Здравствуйте !

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

Заранее благодарен

anonymous
Ответ на: комментарий от anonymous

> Может есть еще какие предложения ?

может для начала объяснить аудитории, что же конкретно имеется ввиду под "расширением количества системных вызовов"?

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от klalafuda

Ну это же очевидно)) ман хочет создать пару самописных сисколов, но не может придумать что они будут делать.

aton
()
Ответ на: комментарий от aton

> Ну это же очевидно)) ман хочет создать пару самописных сисколов, но не может придумать что они будут делать.

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

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от klalafuda

Да расслабся ты )) Суть вопроса -- какие простенькие задачи в качестве демонстрации можно оформить как сист вызов ядра. Каким образом это попадет в ядро не так важно.

aton
()
Ответ на: комментарий от klalafuda

>вставить дополнительный системный вызов в работающее ядро [допустим из моделя] уже не так то и просто и если эта проблема успешно решена, то вопроса "а шо бы он делал такого?" IMHO возникнуть не должно.

емнип, на ядрах 2.6 это не реализуется. таблица сисколлов просто не экспортируется.

generatorglukoff ★★
()
Ответ на: комментарий от klalafuda

>вставить дополнительный системный вызов в работающее ядро [допустим из моделя] уже не так то и просто и если эта проблема успешно решена, то вопроса "а шо бы он делал такого?" IMHO возникнуть не должно.

емнип, без на ядрах 2.6 это не реализуется. таблица сисколлов просто не экспортируется.

generatorglukoff ★★
()
Ответ на: комментарий от generatorglukoff

> емнип, на ядрах 2.6 это не реализуется. таблица сисколлов просто не экспортируется.

да, добавить новый системный вызов динамически не так просто.

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от klalafuda

Господа ! Извините что вызвал эти дебаты Действительно нужно просто показать на примере (ах) добавление и реализацию нового syscall. Если кто может посоветовать красивый пример, пожалуйста, подскажите.

anonymous
()
Ответ на: комментарий от anonymous

> Господа ! Извините что вызвал эти дебаты Действительно нужно просто показать на примере (ах) добавление и реализацию нового syscall. Если кто может посоветовать красивый пример, пожалуйста, подскажите.

IMHO sys_printk за глаза. чтобы транслировал передаваемые данные a'la printf(3) на printk. достаточно наглядно и отнюдь не так просто, как может показаться на первый взгляд :)

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от generatorglukoff

1. sys_call_table легко ищется через экспортируемую функцию sys_close 2. для того, чтобы добавить системный вызов необходимо: а) выделить память под N + 1 указателей, где N - количество системных вызовов б) скопировать содержимое найденной в п. 1 таблицы в область памяти, полученную в п. 2а в) продизассемблировать system_call для нахождения инструкции вызова системного сервиса типа call *sys_call_table(, %eax, 4) г) пропатчить смещение инструкции адресом участка памяти из п. 2а в случае, если system_call не экспортируется, его адрес можно найти из поля базы 128-го дескриптора в IDT

rei3er
()
Ответ на: комментарий от rei3er

1) sys_close может и не экспортироваться
2) o_O
3) а кто вам сказал что int 0x80 не пустышка?
а все системные вызовы идут например через
SYSCALL_PAGE

извините, не мог удержаться видя такие потрясающе грязные хаки ))

int_0dh
()
Ответ на: комментарий от int_0dh

int 0x80 не пустышка это официальный (наравне с sysenter) способ вызова системных сервисов для x86 про SYSCALL_PAGE не понял :( что это? если sys_close не экспортируется, то на шаге 2г перед модификацией кода сохраняем старое смещение инструкции, что и будет являться адресом таблицы насчет дизассемблера, берем бесплатный udcli и модифицируем его для внедрения в модуль

rei3er
()
Ответ на: комментарий от generatorglukoff

> ...и на последних моделях процов не используется SYSENTER ?... ради бога, берем адрес sysenter_entry из IA32_SYSENTER_EIP и производим те же операции, что и с system_call

rei3er
()
Ответ на: комментарий от rei3er

способ описанный вами - это тоже официальный способ добавления/замены системных вызовoв ? :)

по поводу VSYSCALL_PAGE - это фигня дающая libc возможность не заморачиваться с конкретным способом вызова ядра. - за подробностями например в linux/arch/i386/kernel/vsyscall*

int_0dh
()
Ответ на: комментарий от rei3er

> sys_call_table легко ищется через экспортируемую функцию sys_close

выровнять текущий eip/rip на страницу и просканировать память? в принципе работает. но я наблюдал случаи, когда один и тот-же код поиска таблицы на одном и том-же дистрибутиве/сборке но на разных машинах давал стабильно противоположный результат в плане поиска - на одной все 100% OK на другой - полный провал aka нет таблицы и все тут :-/ почему так происходит так и не понял. может конечно какие-то особенности с железом/кешем/etc может ещё что.

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

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от int_0dh

> 1) sys_close может и не экспортироваться

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

> 3) а кто вам сказал что int 0x80 не пустышка? а все системные вызовы идут например через SYSCALL_PAGE

есть прецеденты, когда int 80 был действительно пустышкой aka явным образом неработоспособен и все вызовы шли только через sysenter/sysexit посредством того-же vdso?

> извините, не мог удержаться видя такие потрясающе грязные хаки ))

что поделать, если вся работа с ядром через API, которого там не нет - это один большой хак. а бывает иногда что нужно.

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от int_0dh

ясно, сейчас посмотрел исходники
патчится крайне просто
1. __ioremap(virt_to_phys(VSYSCALL_ADDR(0)), VSYSCALL_MAPPED_PAGES << PAGE_SHIFT, _PAGE_PRESENT |_PAGE_RW | _PAGE_USER | _PAGE_ACCESSED);
2. выделяем VSYSCALL_MAPPED_PAGES + 1 физических страниц памяти
и копируем туда VSYSCALL_MAPPED_PAGES по адресу VSYSCALL_ADDR(0)
3. по адресам VSYSCALL_ADDR(0), VSYSCALL_ADDR(1), ... записываем
шеллкод {0xE9, X}, где X = P - (VSYSCALL_ADDR(N) + 5)
P - адрес пункта найденный в п. 2 + N * PAGE_SIZE
N - номер текущего виртуального сервиса

rei3er
()
Ответ на: комментарий от klalafuda

> может и не экспортироваться. да и маловато его одного будет для
> надёжного поиска таблицы.
для 100% нахождения таблицы не будет достаточно даже если все системные вызовы будут экспортироваться
> есть прецеденты, когда int 80 был действительно пустышкой aka явным
> образом неработоспособен и все вызовы шли только через
> sysenter/sysexit посредством того-же vdso?
ссылку на прецеденты можно?
где бинарная совместимость в рамках одной архитектуры?

rei3er
()
Ответ на: комментарий от rei3er

>> может и не экспортироваться. да и маловато его одного будет для
>> надёжного поиска таблицы.
> для 100% нахождения таблицы не будет достаточно даже если все системные вызовы будут экспортироваться

много ли в ядре структур данных, в которых а) последовательно хранятся адреса обработчиков системных вызовов [в пределе всех] б) тем более в заданном порядке? мне почему-то кажется, что только одна..

>> есть прецеденты, когда int 80 был действительно пустышкой aka явным
>> образом неработоспособен и все вызовы шли только через
>> sysenter/sysexit посредством того-же vdso?
> ссылку на прецеденты можно?

вообще-то это был вопрос. лично я таких прецедентов не встречал. хотя с другой стороны, целенаправленно статистику не собирал.

> где бинарная совместимость в рамках одной архитектуры?

ммм... не понял вопроса.

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от rei3er

очевидно что он неработоспособен
например что будет с потоками которые сделали syscall до модификации VSYSCALL_PAGE а возвращаются в user space после модификации ?

int_0dh
()
Ответ на: комментарий от rei3er

отличная бинарная совместимость - передача управления
строго по определенному адресу с аргументами подготовленными
определенным образом. код который там находится сам разберется как ему вызывать ядро.

int_0dh
()
Ответ на: комментарий от klalafuda

> много ли в ядре структур данных, в которых а) последовательно хранятся > адреса обработчиков системных вызовов [в пределе всех] б) тем более в > заданном порядке? мне почему-то кажется, что только одна..
есть вероятность (правда крайне маленькая), что произвольные данные могут образовывать такую последовательность
и это не дает нам 100% (будет 99.(9)%) ;)
> ммм... не понял вопроса.
ну есть Linux-приложение для x86, которое использует int 0x80, как официальный способ перехода в режим ядра
если в некоторой системе int 0x80 является пустышкой, то это приложение будет нерабочим

rei3er
()
Ответ на: комментарий от int_0dh

> например что будет с потоками которые сделали syscall до модификации
> VSYSCALL_PAGE а возвращаются в user space после модификации ?
ничего не будет
мы заменяем стандартный пролог каждой vsyscall-функции, а он не влияет на выход из нее
если нужна стопроцентная синхронизация
можно просканировать thread.eip каждого процесса на предмет его работы с VSYSCALL_PAGE (VSYSCALL_ADDR(0) <= thread.eip < VSYSCALL_ADDR(0) + VSYSCALL_MAPPED_PAGES << PAGE_SHIFT)
и заменить его на соответствующий адрес в новой выделенной области
естественно сканирование должно предусматривать запрещение преемтивности на текущем процессоре и (в случае SMP машины) временную остановку других процессоров

rei3er
()
Ответ на: комментарий от int_0dh

я говорил про другую бинарную совместимость

rei3er
()

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

Kage
()
Ответ на: комментарий от Kage

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

с написанием думаю проблем не возникнет. а вот с внесением патчей в основное дерево проблемы по всей видимости возникнут..

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от Kage

как вы себе это представляете?
где и как вы будете реализовывать системный вызов для его динамического добавления?

rei3er
()

Народ, ну вы загнались пипец! Хакеры респект вам! Вопрос: какие книги по кЁрнелу(ядру) надо почитать, чтобы так шпарить(С/C++ знаю, чуток gdb знаю, чуток gcc)?

anonymous
()
Ответ на: комментарий от rei3er

> как вы себе это представляете?

ну например так, как это сделано в *BSD.

> где и как вы будете реализовывать системный вызов для его динамического добавления?

ну например в подгружаемом модуле. допустим, захотелось мне реализовать свою собственную подсистему чего-то там. QNX SRR например. интерфейсу прямая дорога в системные вызовы, но вот в общее ядро его по всей очевидности никто включать не будет [зачем?]. а так, написал модуль, подгрузил, он зарегистрировал требуемые системные вызовы и вперёд и с песнею. есть модуль - работаем, нет модуля - ENOSYS.

ps: да, как разрешается проблема с номерами динамических системных вызовов в BSD я сейчас на вскидку не помню :)

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от anonymous

> Вопрос: какие книги по кЁрнелу(ядру) надо почитать, чтобы так шпарить

/usr/src/linux

iBliss
()
Ответ на: комментарий от klalafuda

> ps: да, как разрешается проблема с номерами динамических системных
> вызовов в BSD я сейчас на вскидку не помню :)
решается просто
выделяется память под новую таблицу с дополнительными ячейками
причем при каждом новом выделении число свободных ячеек увеличивается

rei3er
()
Ответ на: комментарий от rei3er

>> ps: да, как разрешается проблема с номерами динамических системных
>> вызовов в BSD я сейчас на вскидку не помню :)

> решается просто выделяется память под новую таблицу с дополнительными ячейками причем при каждом новом выделении число свободных ячеек увеличивается

khm, ну как сделать таблицу как раз очевидно, не вопрос.

вопрос скорее в другом - как приложение A узнает, что зарегистрированный модулем B динамический системный вызов sys_foo() имеет номер 1234? можно конечно прописать номера фиксировано, но это рано или поздно приведёт к конфликту [загружено одновременно два модуля с пересекающимися номерами вызовов]. можно номера вызовов генерировать динамически, но тогда должен быть какой-то интерфейс, через который приложение могло бы запросить ядро нечто на вроде "дай мне номер вызова для [domain1[<domain2]]:<sys_name>" или в этом духе. соотв. модули регистрировали бы свои имена и своё API. но это уже муторнее и так далее и тому подобное.

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от klalafuda

> но тогда должен быть какой-то интерфейс, через который приложение
> могло бы запросить ядро
чем /proc не устраивает?
создаем файл
через write() передаем символьную строку, которая представляет собой имя системного вызова, в качестве возвращаемого значения - его номер
при регистрации системного вызова создавать описывающую его структуру (имя, номер) и добавлять в список
через этот список будет работать /proc

rei3er
()
Ответ на: комментарий от rei3er

> но тогда должен быть какой-то интерфейс, через который приложение > могло бы запросить ядро

>чем /proc не устраивает?

IIRC, во фряхе нет procfs в том виде, как в linux.

anonymous
()
Ответ на: комментарий от anonymous

> IIRC, во фряхе нет procfs в том виде, как в linux.
причем тут BSD?
человек под Linux пишет

rei3er
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.