ОК, так что я углубился в это, так как я не получил большой ответ здесь и нашел некоторую полезную информацию.Первый, когда приложение запускается в linux, в дополнение к традиционным параметрам argc, argv, envp.Передан еще один массив с дополнительными данными, который называется auxv.Подробнее см. здесь .
Одна из этих пар ключ / значение имеет ключ, эквивалентный AT_SYSINFO
.Определяется либо в /usr/include/asm/auxvec.h
, либо в /usr/include/elf
.
. Значение, связанное с этим ключом, является точкой входа в функцию системного вызова (на странице "vdso" или "vsyscall", отображаемой в каждом процессе.
Вы можете просто заменить традиционные инструкции int 0x80
или syscall
вызовом по этому адресу, и он на самом деле сделает системный вызов. К сожалению, это уродливо. Так что ребята из libc придумали хорошее решение.Когда они выделяют TCB
и присваивают его сегменту gs
, они помещают значение AT_SYSINFO
в некоторое фиксированное смещение в TCB
(к сожалению, оно не фиксируется в разных версиях, поэтому нельзя полагаться насмещение всегда является одной и той же константой.) Поэтому вместо традиционного int 0x80
вы можете просто сказать call *%gs:0x10
, который вызовет подпрограмму системного вызова, найденную в разделе vdso
.
Я полагаю, цельЭто облегчает написание libc. Это позволяет ребятам libc написать один блок кода для обработки системных вызовов и больше не беспокоиться об этом. Ребята из ядра могутИзмените, как системные вызовы выполняются в любой момент времени, им просто нужно изменить содержимое страницы vdso
, чтобы использовать новый механизм, и это хорошо.На самом деле, вам не нужно даже перекомпилировать ваш libc!Тем не менее, для нас, людей, пишущих встроенную сборку и пытающихся поиграть с вещами под капотом, это делает боль в заднице.
К счастью, старый способ все еще работает, если вы действительно хочу сделать что-то вручную: -).
РЕДАКТИРОВАТЬ: одна вещь, которую я заметил своими экспериментами, это то, что AT_SYSINFO
, похоже, не передается программе на моем x86_64коробка (AT_SYSINFO_EHDR
есть, но я пока не знаю, как ее использовать).Поэтому я не уверен на 100%, как в этой ситуации определяется адрес функции системного вызова.