Pull to refresh
58.25
Wunder Fund
Мы занимаемся высокочастотной торговлей на бирже

Где твои системные вызовы?

Level of difficultyMedium
Reading time3 min
Views3.1K
Original author: Ted Unangst

Ядро OpenBSD становится уже очень старым — ну просто очень — ему около сорока пяти лет. Оно, следовательно, не любит сюрпризов. Поэтому программы должны сообщать ему о том, где находятся их системные вызовы. В сегодняшнем выпуске «Вежливого программиста» мы поговорим о том, как это делать по всем правилам этикета.

Если вы программируете на C — всё это делается автоматически. Поэтому мы будем писать код только на языке, который совершенно нельзя назвать C, и при этом обойдёмся без линковки с libc.

Начало

Начнём с простой программы hello:

void
start()
{
        w("hello\n", 6);
        x();
}

typedef unsigned long size_t;
int
w(void *what, size_t len) {
        __asm(
"       mov x2, x1;"
"       mov x1, x0;"
"       mov w0, #1;"
"       mov x8, #4;"
"       svc #0;"
        );
        return 0;
}
void
x() {
        __asm(
"       mov x8, #1;"
"       svc #0;"
        );
}

В «совершенно не C» мы начинаем выполнение программы с функции start и выводим сообщения с помощью функции w (её исходный код включён в листинг). А после этого, в итоге, выходим из программы, вызывая функцию x, так как, если работа завершится в нижней части функции start — это будет настоящая жесть.

Вудуистика

Нам ещё понадобится немного магии вуду — чтобы сообщить ядру о том, что это — настоящая программа, а не плод бредовых фантазий Зимнего безмолвия.

__asm(" .section \".note.openbsd.ident\", \"a\"\n"
"       .p2align 2\n"
"       .long   8\n"
"       .long   4\n"
"       .long   1\n"
"       .ascii \"OpenBSD\\0\"\n"
"       .long   0\n"
"       .previous\n");

Системные вызовы

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

struct whats {
        unsigned int offset;
        unsigned int sysno;
} happening[] __attribute__((section(".openbsd.syscalls"))) = {
        { 0x104f4, 4 },
        { 0x10530, 1 },
};

Если вы изучали операционные системы — вы можете вспомнить, что write — это системный вызов #4, а exit — системный вызов #1. Что касается шестнадцатеричных смещений — ну — мы, всё же, пишем на языке, который нельзя безоговорочно назвать «совершенно не C», но разобраться с этим не так уж и сложно. Загляните в мануал.

Честно говоря, я не знаю, что ещё можно сделать, чтобы лучше раскрыть этот простой пример, разве что — скомпилировать код и запустить objdump. Указатели функций не являются константами времени компиляции,  они не дадут нам смещение секции elf без дополнительных беззаконных умственных упражнений. Но это — то, что может достаточно легко раскрыть используемый вами набор инструментов. Сложности добавляет лишь то, что эти инструменты пытаются запихать это всё в «одноразовую» демонстрацию. А libc просто использует немного больше «вудуистики» в asm-секциях, но всё это слишком мутно, чтобы тут воспроизводить.

Компиляция

Всё готово.

$ cc -c where.c
$ ld -e start --eh-frame-hdr -Bstatic -o where where.o
$ ./where
hello

Привет! Перед нами — согласованная работа программы и системных вызовов.


О, а приходите к нам работать? 🤗 💰

Мы в wunderfund.io занимаемся высокочастотной алготорговлей с 2014 года. Высокочастотная торговля — это непрерывное соревнование лучших программистов и математиков всего мира. Присоединившись к нам, вы станете частью этой увлекательной схватки.

Мы предлагаем интересные и сложные задачи по анализу данных и low latency разработке для увлеченных исследователей и программистов. Гибкий график и никакой бюрократии, решения быстро принимаются и воплощаются в жизнь.

Сейчас мы ищем плюсовиков, питонистов, дата-инженеров и мл-рисерчеров.

Присоединяйтесь к нашей команде

Tags:
Hubs:
Total votes 8: ↑7 and ↓1+15
Comments3

Articles

Information

Website
wunderfund.io
Registered
Founded
Employees
11–30 employees
Location
Россия
Representative
xopxe