Условное изменение перемещений во время выполнения

TL;DR

Я хочу переписать .got, .got.plt,..., чтобы он указывал на правильные адреса, потому что компоновщик принимает неправильные решения.


Мне нужно использовать в коде две разные функции динамического размещения (например, malloc(),...). Соответствующий будет выбран на основе некоторого условия во время выполнения программы. Поэтому я предоставил два экземпляра glibc и использовал прием LD_PRELOAD. Значение LD_PRELOAD примерно такое:

LD_PRELOAD=multiplexer_library.so:glibc1.so:glibc2.so

где multiplexer_library.so выбирает правильную библиотеку. Доступ к glibc1.so осуществляется с помощью dlsym(RTLD_NEXT, "malloc"), а к glibc2.so — с помощью dlopen(), за которым следует dlsym(). То же самое касается calloc(),...

Проблема в том, что второй malloc будет мешать первому. Это происходит потому, что все динамические перемещения последних будут сопоставляться с первой компоновщиком. Например, когда glibc2.so вызывает указатель глобальной функции morecore, он будет сопоставлен с morecore и его целью, которая является функцией __default_morecore() в glibc1.so. Запись перемещения для этой глобальной переменной в glibc2.so выглядит следующим образом:

0000003addc0  085600000006 R_X86_64_GLOB_DAT 00000000003af4d8 __morecore@@GLIBC_2.2.5 + 0

Я проследил казнь в Pin. 125 из более чем 1370 записей о перемещении были доступны в моем коде во время динамического распределения. Например, важной записью является глобальная переменная __curbrk, которая определяет границу brk для динамических распределений (ПРИМЕЧАНИЕ, ЧТО Я предоставил изолированную область brk для каждого > библиотека на уровне системного вызова). Это, очевидно, испортит распределение, потому что оба распределителя используют один и тот же __curbrk. Запись о перемещении для __curbrk в glibc1.so показана ниже:

0000003adeb8  044400000006 R_X86_64_GLOB_DAT 00000000003b10b8 __curbrk@@GLIBC_2.2.5 + 0

Я попытался переименовать эти конфликтующие имена, но 125 — это огромное число, а код сложно понять. Потому что он полон вложенных макросов, что делает ручное переименование практически невозможным.

IIUC, для каждой записи о перемещении существует адрес памяти (например, где-то в .got,...), куда компоновщик поместит целевой объект перемещенный адрес, и этот адрес является исключительным для каждой общей библиотеки. Я назову этот адрес TARGET HOLDER. Например, в случае __curbrk компоновщик поместил адрес времени выполнения для переменной __curbrk glibc1.so в держатель цели __curbrk в оба glibc1.so. и glibc2.so. Если это верно, то во время выполнения мне придется обновить значение в целевом держателе __curbrk в glibc2.so, чтобы сохранить время выполнения адрес __curbrk переменной glibc2.so. И чтобы полностью решить проблему, это необходимо сделать для всех из 125 записей о перемещении, доступных для malloc(),.... Является ли это возможным?

Любая помощь приветствуется!


person TheAhmad    schedule 04.12.2020    source источник
comment
Вместо того чтобы модифицировать glibc, вы должны модифицировать свою программу так, чтобы она вызывала пользовательские функции для выделения памяти.   -  person Lorinczy Zsigmond    schedule 04.12.2020
comment
Программы не поддаются изменению. Это реальные приложения, такие как evince и wireshark. Вы говорите, что я должен извлечь код распределения из glibc и использовать его в своем коде? К сожалению, знать точные границы для реализации glibc распределителя трудно. Это кажется сложнее, чем переименование перемещаемых символов.   -  person TheAhmad    schedule 05.12.2020
comment
Вы можете попытаться объяснить, какую настоящую проблему вы хотите решить (см. XY-задачу).   -  person Lorinczy Zsigmond    schedule 05.12.2020
comment
Программа вылетает из-за вышеупомянутого подхода на основе LD_PRELOAD. основная причина заключается в том, что две общие библиотеки используют одни и те же глобальные переменные. Например, __curbrk имеет один и тот же адрес и, следовательно, значение в оба библиотеки, в то время как необходимы две, полностью изолированные области памяти для динамического выделения фрагментов. Это связано с тем, что компоновщик сопоставляет все перемещения (т. е. перемещения в обе библиотеки) с первой библиотекой.   -  person TheAhmad    schedule 05.12.2020
comment
нужны две полностью изолированные области памяти для динамического выделения фрагментов Почему?   -  person Lorinczy Zsigmond    schedule 05.12.2020
comment
Причина выходит за рамки этого вопроса, но она необходима. Вкратце, причина в том, что мне нужно, чтобы динамические данные, выделенные каждой общей библиотекой, были помещены в отдельные 128KB непрерывные области физической памяти. Например, виртуальные адреса в диапазоне [0KB-128KB[ будут управляться первой библиотекой, диапазон [128KB-256KB[ — второй библиотекой, [256KB-384KB[ — первой библиотекой,...   -  person TheAhmad    schedule 05.12.2020
comment
Я не хотел углубляться в glibc динамический распределитель из-за его сложности и для улучшения переносимости я решил использовать два отдельных< /b> glibc библиотек и использовать каждую из них для выделенного региона. Регион изолирован в каждой библиотеке.   -  person TheAhmad    schedule 05.12.2020


Ответы (1)


Поэтому я предоставил два экземпляра glibc и использовал трюк LD_PRELOAD.

Эти ответы объясните, почему использование LD_PRELOAD=glibc.so не может работать (по крайней мере, ненадежно).

Я решил использовать две отдельные библиотеки glibc и использовать каждую из них для выделенного региона. Регион изолирован в каждой библиотеке.

Это не может работать, потому что разработчики GLIBC не поддерживают такой подход. Вам нужно будет сделать что-то еще.

person Employed Russian    schedule 05.12.2020
comment
Спасибо за отличную информацию. Я не хочу, чтобы все glibc было во втором glibc2.so. Мне нужно только все, прямо или косвенно вызываемое функциями динамического распределения (например, malloc(),...). Я перехватываю эти входные функции, используя LD_PRELOAD.... Я также вызываю внутреннюю функцию ptmalloc_init(), которая обычно вызывается компоновщиком для инициализации. Но перемещения кажутся неудачными. Поскольку выполняемый код ограничен, видите ли вы какие-либо другие причины сбоя? - person TheAhmad; 06.12.2020