Saya bisa tahu mengapa itu gagal, meskipun saya sebenarnya tidak tahu bagian mana dari sistem yang bertanggung jawab. Sementara .dtors
ditandai dapat ditulis dalam biner, sepertinya (bersama dengan .ctors
, GOT, dan beberapa hal lainnya) sedang dipetakan ke halaman terpisah, tidak dapat ditulis dalam memori. Di sistem saya, .dtors
dimasukkan ke 0x8049f14
:
$ readelf -S test
[17] .ctors PROGBITS 08049f0c 000f0c 000008 00 WA 0 0 4
[18] .dtors PROGBITS 08049f14 000f14 000008 00 WA 0 0 4
[19] .jcr PROGBITS 08049f1c 000f1c 000004 00 WA 0 0 4
[20] .dynamic DYNAMIC 08049f20 000f20 0000d0 08 WA 6 0 4
[21] .got PROGBITS 08049ff0 000ff0 000004 04 WA 0 0 4
[22] .got.plt PROGBITS 08049ff4 000ff4 00001c 04 WA 0 0 4
[23] .data PROGBITS 0804a010 001010 000008 00 WA 0 0 4
[24] .bss NOBITS 0804a018 001018 000008 00 WA 0 0 4
Jika saya menjalankan executable dan memeriksa /proc/PID/maps
, saya melihat:
08048000-08049000 r-xp 00000000 08:02 163678 /tmp/test
08049000-0804a000 r--p 00000000 08:02 163678 /tmp/test
0804a000-0804b000 rw-p 00001000 08:02 163678 /tmp/test
.data
Saya .bss
masih dapat ditulis di halaman mereka sendiri, tetapi yang lain di 0x8049000-0x804a000
tidak. Saya berasumsi ini adalah fitur keamanan di kernel (seperti yang Anda katakan, "telah ada gerakan menuju readonly .dtors, plt, dapatkan belakangan ini"), tetapi saya tidak tahu secara spesifik apa namanya (OpenBSD memiliki sesuatu yang sangat mirip disebut W ^ X ; Linux memiliki PaX , tetapi tidak dibangun di sebagian besar kernel)
Anda dapat menyiasatinya mprotect
, yang memungkinkan Anda mengubah atribut di-memori dari sebuah halaman:
mprotect((void*)0x8049000, 4096, PROT_WRITE);
Dengan itu, program pengujian saya tidak macet, tetapi jika saya mencoba menimpa akhir sentinel dari .dtors
( 0x8049f18
) dengan alamat fungsi lain, fungsi itu masih tidak dijalankan; bagian yang saya tidak tahu.
Semoga orang lain tahu apa yang bertanggung jawab untuk membuat halaman dibaca hanya, dan mengapa memodifikasi .dtors
tampaknya tidak melakukan apa pun pada sistem saya