В настоящее время я пытаюсь реализовать рерандомизацию кода во время выполнения, чтобы повысить безопасность от атак повторного использования кода. Для этого мне нужен независимый от позиции код / исполняемые файлы (PIC / PIE).
Одна из вещей, которую я должен изменить в сгенерированном коде, это глобальные ссылки на данные. Используя флаг -fPIE, они генерируются как leaq относительно указателя инструкции, но, поскольку мне нужно изменить местоположение моих функций во время выполнения, мне нужно изменить это на абсолютную адресацию. Я делаю это, выполняя следующие изменения в выводе ассемблера:
leaq .LC7(%rip), %rsi
=>
leaq .LC7, %rsi
Это должно быть разрешено компилятором для загрузки с использованием абсолютной адресации. Проблема в том, что это больше не действительный код PIE, и компоновщик говорит, что это конкретное перемещение не может быть выполнено. Вот сообщение об ошибке, которое я получаю:
/usr/bin/ld: daugther.o: relocation R_X86_64_32S against `.rodata.str1.8' can not be used when making a shared object; recompile with -fPIC
daugther.o: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
Когда я использую флаг -fPIC (который предназначен для общих объектов — я хочу создать автономный исполняемый файл), мой инструментальный код преобразуется обратно в исходную форму.
Кто-нибудь знает, как я могу добиться абсолютной адресации для глобальных ссылок на данные, сохраняя при этом независимый от позиции исполняемый файл?
Все вызовы и шаги компилятора:
g++ -O2 std=c++1z -fPIE -o daughter.s daughter.cpp
<do the instrumentation step>
g++ -o daughter daughter.s -pie
Задача ещё не решена.
Других решений пока нет …