GNU/Linux >> Belajar Linux >  >> Linux

Mengapa kode ini mogok dengan pengacakan alamat aktif?

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.


Linux
  1. Mengapa Menambahkan Titik Dua Mematahkan Pola Grep Ini?

  2. Mengapa pipa shell ini keluar?

  3. Mengapa Tomcat bekerja dengan port 8080 tetapi tidak dengan 80?

  1. Mengapa delay-loop ini mulai berjalan lebih cepat setelah beberapa iterasi tanpa tidur?

  2. Saya tidak mengenali alamat server DNS saya:apakah ini berarti saya disusupi?

  3. Mengapa regex ini tidak berfungsi di linux?

  1. Mengapa Substitusi Proses Bash Tidak Bekerja Dengan Beberapa Perintah?

  2. Mengapa saya tidak dapat merusak sistem saya dengan fork bomb?

  3. Mengapa nama host saya muncul dengan alamat 127.0.1.1 daripada 127.0.0.1 di /etc/hosts?