Дополню свой собственный фикс, потому что у варианта 1 есть подвох, который я пропустил.
Он убирает загрузку через %fs, но канарейка теперь равна константе из исходника, так что она одинакова при каждом запуске и в каждом бинарнике. Для хексдампера это безвредно, но защитой это назвать трудно. Если хотите, чтобы было по-настоящему, ядро отдаёт 16 случайных байт по AT_RANDOM в auxiliary vector. В _start пропустите argv и NULL в конце envp, идите по парам auxv, пока не встретите тип 25, и скопируйте 8 байт по этому указателю в __stack_chk_guard перед вызовом hexd_main. _start должен остаться незащищённым, как и в варианте 2, а копирование должно произойти до входа в любую защищённую функцию, иначе пролог сохранит старое значение, а эпилог сравнит с новым, и проверка провалится.
Чтобы проверить, что компилятор действительно перестал трогать FS:
objdump -d hexd | grep '%fs'
Вывод должен быть пустым. Если что-то всё же находится, обычно это объектник, собранный без флагов guard, так что проверьте, что все файлы в линковке собираются с одинаковыми CFLAGS.
Про вариант 2: номер сисколла для FS base на x86-64 — 158.
Переведено с английского·Показать оригиналFollowing up on my own fix, since there's a catch with option 1 that I skipped over.
It stops the %fs load, but the canary is now whatever constant sits in the source, so it's identical on every run and in every binary. For a hex dumper that's harmless, but it isn't much of a protector. If you want it to be real, the kernel hands you 16 random bytes at AT_RANDOM in the auxiliary vector. In _start, step past argv and the envp NULL, walk the auxv pairs until you hit type 25, and copy 8 bytes from that pointer into __stack_chk_guard before calling hexd_main. _start has to stay unprotected, as with option 2, and the copy must happen before any protected function is entered, otherwise the prologue stores the old value and the epilogue compares against the new one, which fails.
To check the compiler has really stopped touching FS:
objdump -d hexd | grep '%fs'
That should come back empty. If something still shows up, it's usually an object built without the guard flags, so check that every file in the link gets the same CFLAGS.
On option 2, the syscall number you want for the FS base is 158 on x86-64.