Где находится сегмент% fs для настройки статических изображений эльфов? - PullRequest
0 голосов
/ 02 июня 2018

Я пытаюсь выяснить, как регистр% fs инициализируется при создании изображения эльфа вручную.

Простой фрагмент, который я хотел бы запустить:

        .text
        nop
        movq %fs:0x28, %rax;
1:      jmp 1b

Который должен читаться со смещением 0x28 в сегменте% fs.Обычно здесь хранится канарейка стека.Поскольку я вручную создаю образ эльфа, сегмент% fs вообще не настроен моим кодом, и это не получается (?).

Вот как я создаю образ эльфа:

0000000000000000 <.text>:
   0:   90                      nop
   1:   64 48 8b 04 25 28 00    mov    %fs:0x28,%rax
   8:   00 00 
   a:   eb fe                   jmp    0xa

Я создаю текстовый сегмент с помощью

echo 9064488b042528000000ebfe | xxd -r -p > r2.bin

Затем я преобразую в elf:

ld -b binary -r -o raw.elf r2.bin
objcopy  --rename-section .data=.text --set-section-flags .data=alloc,code,load raw.elf

В этот момент raw.elf содержит мои инструкции.Затем я связываюсь с ld -T raw.ld -o out.elf -M --verbose, где raw.ld:

OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_entry)
PHDRS {
phdr4000000 PT_LOAD;
}
SECTIONS
{
  _entry = 0x4000000;
  .text 0x4000000 : { raw.elf (.text) } :phdr4000000
}

Теперь я могу запустить .elf с помощью gdb:

gdb --args out.elf

и установить точку останова на 0x4000000:

(gdb)break *0x4000000
(gdb)run

Первый nop может быть пройден через stepi, однако канарейка стека читает mov %fs:0x28,%rax segfaults.

Я полагаю, что это ожидается, учитывая, что, возможно, ОС не настраивается% фс.Для простой программы mc: int main() { return 0; }, скомпилированной с gcc --static m.c -o m, я могу прочитать из% fs.Добавление:

long can()
{
        long v = 0;
        __asm__("movq %%fs:0x28, %0;"
                : "=r"(val)::);
        return v;
}

позволяет мне читать из% fs - хотя я сомневаюсь, что% fs: 28 настроен, потому что ld.so не запущен (это статический образ).

Вопрос:

Кто-нибудь может указать, где% fs настроен во время выполнения c для статических изображений?

1 Ответ

0 голосов
/ 03 июня 2018

Вам нужно вызвать arch_prctl с аргументом ARCH_SET_FS, прежде чем вы сможете использовать префикс сегмента %fs.Вам нужно будет где-то выделить резервное хранилище (brk, mmap или другую неиспользуемую часть стека).

glibc делает это в __libc_setup_tls в csu/libc-tls.c для статически связанных двоичных файлов,скрыт за макросом TLS_INIT_TP.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...