- PROJEKT: OVERFLOW adalah game pembelajaran yang mengubah assembly RISC-V dan buffer overflow menjadi aturan board game, sehingga pemain bisa langsung menelusuri manipulasi memori, stack, dan return address
- Para pemain berbagi memori dan program yang sama, lalu bersaing dengan model penjadwalan preemptif yang mengeksekusi hanya 10 instruksi per giliran tanpa memori virtual
- Penentuan menang-kalah bercabang dari alur membuat shellcode dengan menyalin instruksi yang ada, lalu menimpa return address lawan untuk mengarahkannya ke
game_over() - Akses memori yang salah, baca/tulis tak selaras, dan instruksi ilegal akan menyebabkan crash dan menjalankan exception handler; perubahan alamat trap dan monkeypatch
nopmenjadi variabel strategi utama - Tersedia versi web, papan untuk dicetak, serta game helper untuk ESP32 dan mobile, tetapi sebagian aturan masih disesuaikan sehingga rasanya lebih mirip puzzle peretasan eksperimental
Tujuan game dan model eksekusi
- PROJEKT: OVERFLOW adalah proyek yang membahas assembly RISC-V dan buffer overflow dalam bentuk board game meja
- Tujuan utamanya adalah menyalin instruksi yang ada untuk membuat shellcode kecil di dalam memori, melompat ke kode itu melalui buffer overflow, lalu menimpa return address lawan agar memanggil fungsi
game_over() - Strateginya melampaui eksekusi kode sederhana dan juga mencakup pengaturan exception handler serta monkeypatch
- Semua pemain berbagi memori dan program yang sama, serta memakai prosesor yang sama secara time-sharing
- Dalam satu giliran, 10 instruksi dijalankan
stack pointertiap pemain dimulai dari posisi yang berbeda- Tidak ada memori virtual
Alur build dan pembuatan papan
- Kode dikompilasi dengan
riscv64-unknown-elf-gccuntuk target RV32- Opsi utama mencakup
-march=rv32g,-mabi=ilp32,-ffreestanding,-nostdlib,-nostartfiles,-O0, dan lainnya - Berkat
-O0, machine code menjadi verbose tetapi lebih mudah diikuti
- Opsi utama mencakup
- Materi untuk papan dibuat dengan mem-parsing output
riscv64-unknown-elf-objdump -S -l -fd game- Instruksi
▲dan✎dimodifikasi - Offset lompatan diubah dari heksadesimal ke desimal
- Assembly dirapikan dan dicocokkan dengan source code
- SVG dibuat lalu dikonversi ke PDF dengan Inkscape
- Instruksi
Pencetakan dan perlengkapan
- Papan digunakan dengan mencetak PDF bagian kiri dan kanan
- Ukuran cetak yang disarankan adalah A3; A4 juga bisa tetapi kecil
- Perlengkapannya adalah 1 penanda untuk instruksi
nop, 1 penanda untuk alamat trap, 2 penanda per pemain untuk program counter dan stack pointer, serta pensil dan penghapus - Versi web mendukung permainan solo dan bermain bersama teman, dan juga tersedia game helper untuk ESP32 dan mobile
Aturan dasar dan jalannya giliran
- Kondisi awalnya sebagai berikut
- Semua register dimulai dari 0, tetapi register return address
radimulai dari 1000 spPlayer 1 diinisialisasi ke 2244, danspPlayer 2 ke 3844pckedua pemain dimulai dari alamat awal fungsimain, yaitu 1000- Penanda trap diletakkan di alamat 1000
- Semua alamat memori bernilai 0 kecuali program yang telah dimuat sebelumnya
- Penanda instruksi
noppada awalnya tidak diletakkan di papan
- Semua register dimulai dari 0, tetapi register return address
- Dalam satu giliran, 10 instruksi harus dijalankan, dan lompatan seperti
jal,beqjuga harus diikuti sebagaimana adanya - Pemain boleh menghentikan gilirannya setelah menjalankan setidaknya 1 instruksi, lalu membawa sisa jumlah instruksi ke giliran berikutnya
- Batas maksimum instruksi yang bisa diakumulasikan adalah 20
Monkeypatch dan kondisi kemenangan
- Pada awal tiap giliran, setelah menjalankan tepat 1 instruksi, pemain boleh memindahkan penanda instruksi
nopke alamat mana pun dalam fungsi yang saat itu tidak sedang dijalankan oleh para pemain - Saat
pcmencapai alamat tersebut, instruksi itu akan berfungsi sebagai no-operation - Jika memindahkan penanda
nop, pemain kehilangan giliran saat ini dan giliran berikutnya, dan lawan dapat mengeksekusi hingga 20 instruksi pada giliran berikutnya - Aturan monkeypatch ini masih belum seimbang dan terus sedikit berubah tiap beberapa hari
- Dalam hard mode, game berakhir jika Anda meretas lawan sehingga memanggil fungsi
game_over() - Jika tidak ada pihak yang bisa lagi mengarahkan lawannya ke
game_over(), hasilnya seri - Dalam easy mode, pemain pertama yang mengeksekusi
retdimaindan keluar dari loop utama menjadi pemenang
Simbol khusus dan penanganan pengecualian
✎memungkinkan pemilihan angka 12-bit sebarang dari 0 sampai 4095 sebagai nilai immediate untuk instruksili▲memungkinkan pemilihan nilai dalam rentang ±128 byte dari stack pointer milik sendiri pada instruksi load- Misalnya jika
spadalah 2180, maka yang dapat dipilih adalah 2052 hingga 2308
- Misalnya jika
- Tindakan terlarang akan menyebabkan program crash
- Menimpa alamat memori di bawah 1192
- Membaca atau menulis tak selaras pada alamat yang bukan kelipatan 4
- Menjalankan instruksi ilegal
- Jika crash terjadi, exception handler akan dijalankan dan melompat ke alamat trap
- Alamat trap awalnya 1000, tetapi bisa ditimpa di fungsi
set_trap() - Saat exception terjadi, program counter disetel ke nilai tertentu lalu eksekusi berlanjut
- Alamat trap awalnya 1000, tetapi bisa ditimpa di fungsi
- Jika kecurangan atau kesalahan terdeteksi, status program, memori, dan register pemain tersebut akan di-reset
Aturan ekspansi 3–4 pemain
spPlayer 3 disetel ke 2116spPlayer 4 disetel ke 3716- Jika ada 3 pemain atau lebih, simbol
▲hanya bisa dipakai pada rentang -128 byte dari stack pointer - Jika dimainkan dengan lebih dari 2 pemain, game menjadi cukup tidak stabil dan cepat rusak
- Mencapai kondisi kemenangan menjadi lebih sulit, tetapi permainan jadi lebih seru dan kacau
Contoh strategi peretasan
- Crash bisa digunakan sebagai strategi menyerang untuk menghambat progres lawan
- Jika trap handler diubah ke fungsi
game_over, pemain pertama yang crash akan kalah- Dalam kondisi ini, penanda
nopmenjadi sangat kuat - Jika lawan menaruh
nopdi atasretdari fungsi yang sedang Anda jalankan, Anda bisa kalah
- Dalam kondisi ini, penanda
- Di fungsi
bug(), jika index dioverflow menjadi 400 atau -400, Anda bisa mengakses stack lawan dan menimpa return address-nya- Sebagai contoh, untuk berpindah dari alamat 3784 ke 2184,
(3784 - 2184) / 4 = 400, jadi dibutuhkan index-400
- Sebagai contoh, untuk berpindah dari alamat 3784 ke 2184,
- Dengan fungsi
copy(), instruksi tertentu bisa disalin untuk membuat shellcode pendek di memori- Contoh shellcode adalah kombinasi
li a4, ✎,li a5, ✎,sw a4, 0(a5),retuntuk melakukan penulisan sebarang - Jika instruksi
retdisalin, return address akan disetel ke titik awal shellcode sehingga menjadi loop tak berujung
- Contoh shellcode adalah kombinasi
- Di fungsi
bug(), jika index disetel ke 6, variabelvaluebisa ditulis ke atas saved return address stack di28(sp)- Saat
bug()mengembalikan kontrol, nilai28(sp)akan disalin ke register return address - Jika alamat shellcode yang Anda buat dimasukkan ke sana, maka eksekusi bisa melompat ke memori
- Saat
Interpretasi instruksi dan perubahan
- Semua lompatan bersifat relatif terhadap program counter saat ini, walaupun di disassembler terlihat seperti alamat absolut
- Misalnya, machine code 1903 untuk
jal a4, 0akan menjadi loop tak berujung saat dijalankan
- Misalnya, machine code 1903 untuk
- Daftar instruksi game yang valid dirangkum dari instruksi RV32 JRI dengan machine code 0 sampai 4095, dalam bentuk yang menggunakan
a0,a4,a5,sp,ra, dan sebagainya - Log perubahan 0.0.6 mencakup perubahan dari
while(run)menjadiwhile(*prun)- Lawan kini bisa memaksa crash dengan memicu dereferensi tak selaras
- Aturan NOP telah diubah sehingga hanya bisa ditempatkan pada fungsi yang tidak sedang dijalankan
Desain dan materi pembelajaran
- Persegi di sisi kiri dan kanan papan adalah pesan biner yang dienkode dalam ASCII
- Persegi putih berarti 1, persegi hitam berarti 0
- Warna yang digunakan hanya merah, biru, hitam, dan putih agar cocok untuk cetak murah dan tetap terbaca di printer hitam-putih
- Tidak ada syntax highlighting
- Ini dipilih agar tidak ada bagian kode yang tampak lebih penting hanya karena tema, dan supaya pemain fokus serta menilai sendiri
- Materi belajar assembly RISC-V mencakup riscv-programming.org, cs3410 risc-v interpreter, rvcodecjs dari luplab, dan lainnya
- Untuk belajar C, bagian awal Beej's Guide to C Programming digunakan
- Tersedia PDF latihan assembly siap cetak yang membahas variabel, pemanggilan fungsi, pointer, string, struct, array, rekursi, dan lainnya, serta versi “assembly hangman” model isi-kosong
1 komentar
Opini Hacker News
Benar-benar mengesankan. Yang paling hebat terutama adalah ia berhasil membuat putrinya yang berusia 12 tahun ikut memainkannya
Kapan kira-kira kita bisa mengharapkan versi CHERI? :-D
Core War adalah gim yang dimainkan di arena memori sebuah virtual machine yang mendukung bahasa assembly simulasi sederhana. Saya pertama kali melihatnya di Scientific American pada 1984, dan karena saat itu saya sudah sekitar 15 tahun memprogram, saya mengenali bahwa gim itu terinspirasi oleh gim yang lebih tua dari Bell Labs, Darwin
Darwin dibuat pada 1961 dan berjalan di IBM 7090. Program-program bersaing memperebutkan sumber daya, dan program yang menyalin diri untuk menguasai seluruh ruang yang dialokasikan akan menang. Gim itu tidak bertahan lama setelah Robert Morris Sr. membuat program yang tak terkalahkan. Lihat [2]
Pada pertengahan 1970-an, Software Practice and Experience adalah salah satu jurnal ilmu komputer favorit saya, dan sering memuat kolom Computer Recreations yang ditulis dengan nama pena Aleph-Null. Saat kuliah pascasarjana, saya menikmati mengimplementasikan beberapa gim dari kolom itu. Jurnalnya mahal, tetapi jika Anda mahasiswa, kemungkinan besar bisa menemukannya di perpustakaan kampus seperti saya dulu. Edisi-edisi tahun 1970-an memuat topik seperti compiler Pascal, Algol 68, dan pemrograman konkuren, sehingga mudah dan menarik dibaca; lewat tulisan N. Wirth saya mengenal Module[3,4] dan kemudian Oberon[5]
[1] https://en.wikipedia.org/wiki/Core_War
[2] https://en.wikipedia.org/wiki/Darwin_(programming_game)
[3] https://onlinelibrary.wiley.com/doi/abs/10.1002/spe.43800701...
[4] https://onlinelibrary.wiley.com/doi/abs/10.1002/spe.43800701...
[5] https://onlinelibrary.wiley.com/doi/abs/10.1002/spe.43801909...
Saya punya teman yang bilang ia suka gim tetapi tidak punya otak untuk coding; lewat Human Resource Machine, ia pada dasarnya jadi melakukan coding, dan beberapa solusinya lebih baik daripada solusi saya yang sudah berpengalaman bertahun-tahun
Anak saya yang berusia 12 tahun tidak suka matematika, tetapi ia luar biasa jago di Human Resource Machine dan SpaceChem. Saya jadi bertanya-tanya apakah matematika SMA dan matematika dalam pemrograman pada dasarnya memang berbeda
Sangat menarik. Kalau memikirkan ukuran memori komputer saat ini, saya selalu merasa mnemonic pendek adalah pilihan engineering yang kurang baik
Di sini pun, hal pertama yang harus dilakukan adalah mempelajari dan mengingat apa yang dilakukan instruksi. Jika namanya dibuat lebih deskriptif, akan jauh lebih mudah dipelajari, diingat, dan dibaca kodenya. Mencurigakan bahwa orang-orang tidak sering melakukannya
Fakta bahwa kerentanan jenis ini mungkin terjadi juga menurut saya menunjukkan kegagalan desain sistem secara keseluruhan. Bukan berarti ini bukan gim yang menyenangkan atau bukan cara belajar yang baik, tetapi dalam engineering, masalah struktural terlalu mudah diterima. Kebanyakan orang bahkan tidak sampai melihat cacat struktural itu
Menurut saya anak-anak benar-benar merespons dengan baik ketika tidak diremehkan. Setidaknya begitu dengan anak saya
Anda pikir ada orang yang tidak menganggap arbitrary read dan write sebagai cacat struktural? Ribuan orang menangani masalah itu dan sudah membuat kemajuan yang cukup besar. Pada saat yang sama, menurut saya peek dan poke tetap menyenangkan
Ini benar-benar keren. Saya ingin mencobanya di kantor
Kelihatannya cukup seru. Menurut Anda cocok untuk usia berapa?
bug(), menurut saya bisa dilakukan anak usia 10–15 tahunPutri saya berusia 12 tahun dan kami bersenang-senang memainkannya bersama. Kondisi menang yang sulit, yaitu membuat lawan melompat ke fungsi
game_over(), lebih sulit, tetapi sepertinya bisa dicapai dalam 5–6 bulanUntuk orang dewasa, saya kurang tahu. Sebagian orang begitu takut pada assembly seolah-olah itu ciptaan iblis, jadi mungkin lebih sulit membuat mereka bermain daripada anak-anak
Yang menarik adalah kita cenderung melihat dunia sebagai cermin diri kita sendiri
Seberapa besar kemungkinannya bahwa karena saya tertarik pada buffer overflow dan pemrograman, putri saya juga tentu akan sangat tertarik? Jika ditambah fakta bahwa ia anak pertama dan anak kedua perempuan, peluangnya tampak makin kecil, tetapi saya tetap melihat banyak ayah yang mendorongnya
Saat membuat proyek seperti ini, saya penasaran apakah ia setidaknya sadar sampai taraf tertentu bahwa ini adalah proyek vanity. Bagaimanapun, saya tertarik pada hal semacam ini, jadi saya senang ia membukanya untuk publik
Anda menyiratkan bahwa pembuat proyek memaksakan ini kepada putrinya karena kesombongannya sendiri, tetapi apa dasar Anda? Saya melihat-lihat beberapa halaman situsnya dan sama sekali tidak menemukan hal yang mengisyaratkan itu; justru ada beberapa ungkapan lembut bahwa putrinya menikmatinya dan sangat tertarik
Mengapa Anda menyingkirkan kemungkinan bahwa putrinya sendiri yang awalnya terus penasaran tentang apa yang dilakukan ayahnya di komputer? Bisa saja dimulai kecil, lalu berkembang menjadi proses dua arah antara seseorang yang berbagi minat dan rekan penjelajah cilik
Saya juga tidak tahu kenyataannya seperti apa, tetapi Anda pun tidak. Dari pengalaman saya beberapa tahun terlibat dalam pendidikan, anak-anak adalah pembelajar yang jauh lebih hebat daripada yang umumnya dipercaya. Struktur sekolah mungkin salah satu alasannya, tetapi di intinya mungkin ada keyakinan yang membatasi seperti ini. Saya ingin memberi tepuk tangan kepada ayah ini karena mencoba berbagi minat dan semangatnya dengan putrinya dan dunia
Sebagian dari itu akan bernilai, sebagian tidak. Peluangnya selalu tidak menguntungkan. Begitulah hidup
Kalau jalur kode RISC-V 64-bit sudah stabil, bekerja cukup baik, dan bahkan “buffer overflow” hilang, bagaimana rencana mereka menghadapi keusangan terencana ketika C/C++ tidak selalu mengubah sintaksnya untuk mereka? Jiwa-jiwa malang…
Tunggu dulu.
Board game tabletop yang melibatkan coding assembly? Kenapa saya tidak memikirkan ini sebelumnya? :D
PL/I melakukan hal-hal dengan benar seperti pemeriksaan batas string/array dan stack yang tumbuh ke atas, bukan ke bawah
https://www.acsac.org/2002/papers/classic-multics.pdf