ฉันสามารถบอกได้ว่าทำไมมันถึงล้มเหลวถึงแม้ว่าฉันไม่รู้จริง ๆ ว่าส่วนใดของระบบที่รับผิดชอบ ในขณะที่.dtors
ถูกทำเครื่องหมายว่าสามารถเขียนได้ในไบนารีดูเหมือนว่า (พร้อมกับ.ctors
GOT และอีกสองสามอย่าง) กำลังถูกแมปไปยังหน้าแยกต่างหากที่ไม่สามารถเขียนได้ในหน่วยความจำ ในระบบของฉัน.dtors
กำลังติดตั้งที่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
ถ้าฉันเรียกใช้ปฏิบัติการและตรวจสอบ/proc/PID/maps
ฉันเห็น:
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
ยังสามารถเขียนได้ในหน้าของตัวเอง แต่คนอื่น ๆ ใน0x8049000-0x804a000
นั้นไม่ได้ ฉันคิดว่านี่เป็นคุณลักษณะด้านความปลอดภัยในเคอร์เนล (อย่างที่คุณพูดว่า "มีการเคลื่อนไหวไปสู่. docers, plt, ได้เมื่อเร็ว ๆ นี้") แต่ฉันไม่รู้ว่ามันเรียกว่าอะไรโดยเฉพาะ (OpenBSD มีบางสิ่งที่คล้ายกันมากW ^ X ; Linux มีPaXแต่ไม่ได้สร้างอยู่ในเมล็ดส่วนใหญ่)
คุณสามารถแก้ไขได้ด้วยmprotect
ซึ่งจะช่วยให้คุณสามารถเปลี่ยนแอตทริบิวต์ในหน่วยความจำของหน้า:
mprotect((void*)0x8049000, 4096, PROT_WRITE);
ด้วยสิ่งนั้นโปรแกรมทดสอบของฉันจะไม่ผิดพลาด แต่ถ้าฉันพยายามเขียนทับจุดสิ้นสุดของ.dtors
( 0x8049f18
) ด้วยที่อยู่ของฟังก์ชันอื่นฟังก์ชันนั้นก็ยังไม่ทำงาน ส่วนนั้นฉันไม่สามารถเข้าใจได้
หวังว่าคนอื่นจะรู้ว่าสิ่งใดที่ทำให้หน้าเว็บอ่านได้อย่างเดียวและทำไมการแก้ไข.dtors
ไม่ดูเหมือนจะทำอะไรในระบบของฉัน