Sistemin hangi kısmının sorumlu olduğunu bilmesem de neden başarısız olduğunu anlayabilirim. .dtors
İkilide yazılabilir olarak işaretlenmiş olsa da .ctors
, GOT ve diğer birkaç şeyle birlikte bellekte ayrı, yazılamaz bir sayfaya eşleştiriliyor gibi görünüyor . Benim sistemde, .dtors
en koymak oluyor 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
Yürütülebilir dosyayı çalıştırıp kontrol /proc/PID/maps
edersem şunu görürüm:
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
/ .bss
kendi sayfalarında hala yazılabilir, ancak diğer sayfalar yazılamaz 0x8049000-0x804a000
. Bunun çekirdekte bir güvenlik özelliği olduğunu varsayıyorum (dediğiniz gibi, "salt okunur .dtors, plt, son zamanlarda var" doğru bir hareket oldu), ama özellikle ne dediğini bilmiyorum (OpenBSD çok benzer bir şeye sahip W ^ X ; Linux'ta PaX var , ancak çoğu çekirdeğe yerleştirilmemiş)
mprotect
Bir sayfanın bellek içi özelliklerini değiştirmenize olanak tanıyan bununla başa çıkabilirsiniz :
mprotect((void*)0x8049000, 4096, PROT_WRITE);
Bununla birlikte, test programım çökmez, ancak başka bir işlevin adresiyle .dtors
( 0x8049f18
) ' nin son sentinelinin üzerine yazmaya çalışırsam , bu işlev hala yürütülmez; o kısmı anlayamıyorum.
Umarım başka biri sayfayı salt okunur yapmaktan neyin sorumlu olduğunu ve değiştirmenin neden .dtors
sistemimde hiçbir şey yapmadığını bilir.