sub rsp, <size>
untuk mencadangkan ruang tumpukan sebelum menyentuhnya, jika Anda menggunakan lebih dari 128 byte di bawah RSP.
Saat macet, lihat peta memori proses Anda. Anda mungkin menggunakan memori sejauh ini di bawah RSP sehingga kernel tidak menumbuhkan pemetaan tumpukan dan oleh karena itu hanya akses biasa ke halaman yang belum dipetakan =kesalahan halaman tidak valid => kernel mengirimkan SIGSEGV.
(ABI hanya mendefinisikan zona merah 128-byte, tetapi dalam praktiknya satu-satunya hal yang dapat menghancurkan memori itu adalah penangan sinyal (yang tidak Anda instal) atau GDB yang menjalankan print some_func()
menggunakan tumpukan program Anda untuk memanggil fungsi dalam program Anda.)
Biasanya Linux cukup bersedia untuk menumbuhkan pemetaan tumpukan tanpa menyentuh halaman intervensi, tetapi tampaknya memeriksa nilai RSP. Biasanya Anda memindahkan RSP alih-alih hanya menggunakan memori jauh di bawah penunjuk tumpukan (karena tidak ada jaminan keamanannya). Lihat Bagaimana memori Stack dialokasikan saat menggunakan instruksi 'push' atau 'sub' x86?
Duplikat lainnya:Pengecualian mana yang dapat dihasilkan saat mengurangkan register ESP atau RSP? (penumpukan tumpukan) di mana menggunakan sub rsp, 5555555
sebelum menyentuh memori tumpukan baru sudah cukup.
Stack ASLR mungkin memulai RSP di tempat yang berbeda relatif terhadap batas halaman , jadi kadang-kadang Anda mungkin nyaris lolos begitu saja. Linux awalnya memetakan 132kiB ruang tumpukan , dan itu termasuk ruang untuk lingkungan dan arg pada tumpukan saat masuk ke _start
. 128kiB Anda sangat dekat dengan itu, jadi sangat masuk akal bahwa kadang-kadang berfungsi secara acak.
Dan BTW, tidak ada alasan untuk benar-benar menyalin memori di ruang pengguna, terutama 1 byte dalam satu waktu. Cukup berikan alamat yang sama ke write
.
Atau setidaknya filter di tempat jika memungkinkan, sehingga jejak cache Anda lebih kecil.
Juga, cara normal untuk memuat byte adalah movzx eax, byte [mem]
. Hanya gunakan mov al, [mem]
jika Anda secara khusus ingin menggabungkan dengan nilai lama RAX. Pada beberapa CPU, mov
ke al
memiliki ketergantungan palsu pada nilai lama yang dapat Anda hancurkan dengan menulis register lengkap.
Dan BTW, jika program Anda selalu menggunakan ruang ini, Anda mungkin juga mengalokasikannya secara statis di BSS. Hal itu memungkinkan pengalamatan terindeks yang lebih efisien jika Anda memilih untuk menyusun executable yang bergantung pada posisi (non-PIE).
Zona merah di amd64 hanya sepanjang 128 byte, tetapi Anda menggunakan 131072 byte di bawah rsp. Gerakkan penunjuk tumpukan ke bawah untuk menyertakan buffer yang ingin Anda simpan di tumpukan.