LINUX.ORG.RU

Как положить функцию в отдельную страницу памяти

 ,


0

2

Есть функция sum:

int sum(int x, int y)
{
	return x + y;
}

Есть виртуальная память со страницами.

Хочу чтобы скомпилированая в машинный код функция лежала в своей отдельной сранице и кроме неё там были бы только нули.

Копировать байты в рантайме - не понятно сколько.

Вроде есть какая-то конфигурационная магия для gcc с запихиванием функции в отдельную секцию в elf и присваеванием секции адреса, но я пока не осилил и боюсь сломать хотелку #1.

Платформа - линукс, amd64. Портабельность не обязательна.

Хотелки:

  • не сломать ASLR, в новом процессе у функции должен быть новый адрес
  • разобраться с обоими вариантами: копировать с memcpy и заставить ld.so сразу грузить куда надо


Последнее исправление: suuaq (всего исправлений: 2)

-ffunction-sections ?

anonymous
()

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

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

Наверняка имеются /но мне известны/ библиотеки, которые позволяли в run-time скомпилировать /к примеру/ функцию, разместить ее бинарный код в памяти и выполнить?

vladimirmir2016
()

Можешь вот так попробовать:

void __dummy_start__() { asm(".align 0x1000"); }
int sum(int x, int y) {
	return x + y;
}
void __dummy_end__() { asm(".align 0x1000"); }

int main() {
    return 0;
}

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

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

Спасибо.

dll собственно для этого и используются. Имеются библиотеки, которые могут создавать dll и изменять их содержимое.

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

Можно /дело времени/ реализовать такую библиотеку, но не хочется изобретать велосипед.

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

vladimirmir2016
()

Хотелки:

  • не сломать ASLR, в новом процессе у функции должен быть новый адрес
  • разобраться с обоими вариантами: копировать с memcpy и заставить ld.so сразу грузить куда надо

Динамический линковщик так не умеет. Так что не ломая ASLR не выйдет.

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

Для начала нужно реализовать простейший загрузчик, который на входе имеет obj файл, поток, ... и он может в заданный участок памяти поместить binary код.

Так вот вопрос /не разбирался с этим вопросом/ как на это посмотрит операционная система?

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

Для разработчиков. Для прикладных программ вряд ли. Собственно некоторые /лишь некоторые/ скриптовые языки по всей видимости умеют это делать потому, как можно реализовать просто выполнение jit кода /но это другой подход/. Вопрос вообщем то мне интересен тем, что бинарный код будет работать быстрее jit.

vladimirmir2016
()

Это кулисао слегка выздоровел или нового пациента привезли с дробями? По сабжу, копировать памяти функций в другие памяти это разве не адское уб, за которое можно огрести кроссплатформенный атятяй?

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

Для начала нужно реализовать

Суть вопроса ТС в том, чтобы все работало с текущим загрузчиком.

Deleted
()

Всем спасибо

Почитал про linker script https://sourceware.org/binutils/docs/ld/, пришёл к выводу, что мне оно шибко геморройно. Скрипт этот надо писать от начала и до конца, нельзя взять и одной строчкой добавить чего-нибудь. Если что, скрипт можно заюзать передав gcc при компиляции -Wl,-Tfilename. Как базу можно взять дефолтные скрипты, их можно получить задав при компиляции с -Wl,--verbose. Дефолтных скриптов видимо несколько, берутся они в зависимости от того, что и с какими параметрами компилируется. -Wl - это параметры, которые gcc передаст в ld.

Ещё можно сделать так:

__attribute__((section(".foo")))
int sum(int x, int y)
{
	return x + y;
}

gcc -Wl,--section-start=.foo=0x500000 sum.c -o sum

Оно встанет ровно на заданный адрес. Ещё теперь можно распарсить section headers в elf-файле, длина секции .foo будет равна длине кода. Но section headers из готового эльфа могут быть выпилины.

В итоге заговнокодил так https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html https://sourceware.org/binutils/docs/as/Align.html

__attribute__((noinline, aligned(4096)))
int sum(int x, int y)
{
	asm(""); //see docs for noinline
	return x + y;
}
asm(".align 4096, 0");

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