Mengapa mesin 486DX4 saya reboot saat mencoba break-in ke kernel NT 3.1?
(retrocomputing.stackexchange.com)- Saat melakukan Ctrl-C break-in dengan
i386kddi Windows NT 3.1, sistem target 486DX4 reboot alih-alih menampilkan promptkd>; penyebabnya adalah masalah kompatibilitas enhanced 486 KiSaveProcessorControlStatedanKiRestoreProcessorControlStatedi NTOSKRNL.EXE memakai perbandingan word saat memeriksa tipe CPU, sehingga salah mengira 486 yang mendukung CPUID sebagai Pentium atau yang lebih baru- Karena
CpuTypedanCpuIDdi KPRCB terbaca bersama, nomor model 486 yang mendukung CPUID ditafsirkan lebih besar 256, sehingga terjadi akses ke register CR4 yang tidak ada pada 486 - Debugging kernel berjalan normal pada 486DX-33 bawaan dan Am486DX4-NV8T write-through tanpa SMM, sehingga masalahnya dipersempit ke enhanced 486 yang menyediakan instruksi CPUID
- Dengan menambal dua lokasi
cmp ds:word_FFDFF138, 5di NTOSKRNL.EXE menjadi byte compare, masalah dapat diperbaiki baik pada NT 3.1 Advanced Server asli maupun NT 3.1 SP3
Lingkungan reproduksi dan gejala
- Windows NT 3.1 dipasang pada Compaq ProSignia 3080, lalu dicoba debugging kernel
- Sistem ini pernah menjalankan Windows NT 3.1 dalam penggunaan nyata, dan tampaknya merupakan salah satu mesin yang secara eksplisit ditargetkan oleh Windows NT
- RAM diperluas menjadi 128MB, dan Intel 486DX-33 bersoket diganti dengan AMD enhanced 486DX4-SV8B
- CPU tersebut mendukung write-back cache dan SMM, serta dipasang pada soket adaptor tegangan
- Penanganan dukungan 486DX4 di BIOS ditunda, dan CPU diatur dengan jumper ke pengali 2x
- Tanpa dukungan L1 write-back dari chipset, pengaturan pengali 2x diharapkan kompatibel secara perangkat lunak dengan Intel 80486DX2-66
- Intel 80486DX2-66 adalah opsi yang didukung sistem ini
- Instalasi Windows NT 3.1 sendiri selesai dengan normal
- CD Windows NT 3.1 menyertakan simbol debugging lengkap, sehingga debugging kernel dicoba
- Tujuannya adalah menyelidiki mengapa NetDDE meninggalkan error di event log
- Ada juga masalah sistem crash pada kartu Ethernet EISA tertentu, dan kemungkinan cacat hardware masih tersisa
- Alih-alih
kdatauntkddari Windows 10 development kit terbaru, perlu menggunakani386kdyang disertakan dalam Windows NT 3.1 agar konfigurasi debugging kernel sesuai - Saat mencoba Ctrl-C break-in dari
i386kd, mesin target tidak memberikan promptkd>, melainkan reboot
Hal-hal yang disingkirkan sebagai penyebab
- Memori dipastikan normal
- Bukan kerusakan file sistem
- Watchdog hardware yang me-reboot sistem saat kernel dihentikan untuk debugging tidak aktif
- Adaptor USB-serial di sisi host berkomunikasi normal
- Perangkat itu tampak seperti PL2301 palsu, tetapi bukan karena mengirim perintah debugger yang salah berupa perintah “reboot system”
- Protokol KD memang memiliki perintah reboot system
- Tidak terkait dengan opsi manajemen jarak jauh atau peringatan pada motherboard
Penyebab sebenarnya: ketidakcocokan enhanced 486 dengan kernel NT 3.1
- Kernel Windows NT 3.1 tidak kompatibel dengan prosesor enhanced 486
- Lebih spesifiknya, masalah muncul pada prosesor 486 yang menyediakan instruksi
CPUID - Debugging kernel berjalan normal pada CPU berikut
- 486DX-33 yang semula terpasang
- Am486DX4-NV8T write-through dengan older non-enhanced core tanpa SMM
- Jika tujuannya hanya menguji debugging kernel NT 3.1, lebih cocok menggunakan CPU yang memang kompatibel secara bawaan dengan Windows NT 3.1
- Untuk memperbaiki NT itu sendiri, bug penentuan tipe CPU di NTOSKRNL.EXE harus ditambal
Jalur kode kernel tempat masalah muncul
- Penyebab langsung ketidakcocokan adalah bug di
KiSaveProcessorControlState- Fungsi pasangannya,
KiRestoreProcessorControlState, juga memiliki bug serupa
- Fungsi pasangannya,
KiSaveProcessorControlStatedipanggil dari tiga lokasi di dalam NTOSKRNL.EXE- Saat exception dipantulkan ke kernel debugger melalui
KdpTrap- Pada Ctrl-C break-in, breakpoint exception terjadi dari fungsi break-in polling di dalam timer tick interrupt
- Saat
KeBugCheckExdipanggil, yaitu dalam situasi “blue screen” - Saat
KiSaveProcessorStatedipanggil- Jika analisis control flow NTOSKRNL.EXE oleh IDA lengkap, fungsi ini tidak diekspor dan juga tidak dipanggil di dalam NTOSKRNL, sehingga tampaknya tidak benar-benar terjadi
- Saat exception dipantulkan ke kernel debugger melalui
KiSaveProcessorControlStatemenyimpan status kontrol prosesor ke strukturCONTEXTyang diperluas- Menyimpan CR0, CR2, CR3
- Pada Pentium atau yang lebih baru, juga menyimpan CR4
- Menyimpan register debug DR0~DR3, DR6, DR7
- Juga menyimpan pengaturan protected mode global seperti alamat GDT, alamat IDT, selector TSS aktif, dan selector LDT
Kesalahan interpretasi field KPRCB
- Nilai di KPRCB digunakan untuk menentukan tipe prosesor
- KPRCB adalah bagian dari KPCR
- KPRCB untuk boot processor atau sistem uniprocessor berada di alamat virtual
FFDFF120, dan alamat itu di-hardcode dalam metode terkait
- Field terkait KPRCB NT 3.1 yang dirangkum oleh Geoff Chappell adalah sebagai berikut
+018 CHAR CpuType+019 CHAR CpuID+01A UShort CpuStep
- Field-field ini diinisialisasi di
KiSetProcessorType- Offset byte 18 pada prosesor 486 diatur ke 4
- Prosesor Pentium diatur ke 5
- Prosesor Pentium Pro serta Pentium II/III diatur ke 6
- Offset byte 19 adalah boolean flag yang menunjukkan apakah prosesor mendukung CPUID dan berperilaku secara “reasonable”
- Instruksi pembanding yang bermasalah membaca word, bukan byte, pada alamat
FFDFF138FFDFF138adalah lokasi yang berjarak 18h byte dari awal KPRCB- Karena itu, bukan hanya
CpuType, tetapi juga byte berikutnya, yaituCpuID, ikut ditafsirkan sebagai bagian dari nomor model
- Prosesor yang mendukung CPUID diperlakukan seolah nomor modelnya 256 lebih besar dari nilai sebenarnya
- 80-4-86 yang mendukung CPUID diperlakukan oleh Windows NT 3.1 seperti 80-260-86
- Karena 260 jauh lebih besar daripada batas Pentium yaitu 5, kernel menilai bahwa prosesor tersebut seharusnya memiliki CR4
- Karena enhanced 486 tidak memiliki CR4, masalah terjadi pada jalur break-in
Cara menambal
- Setelah bug dipastikan, perbaikannya sederhana
- Di NTOSKRNL.EXE, instruksi
cmp ds:word_FFDFF138, 5hanya muncul dua kaliKiSaveProcessorControlStateKiRestoreProcessorControlState
- Kedua lokasi harus diubah dari word compare menjadi byte compare
- Dengan hex editor, tambal rangkaian byte berikut sebanyak dua kali
- Lama:
66 83 3D 38 F1 DF FF 05 - Baru:
90 80 3D 38 F1 DF FF 05
- Lama:
- Perbaikan ini berlaku untuk NTOSKRNL.EXE dari distribusi NT 3.1 Advanced Server asli maupun NT 3.1 SP3
1 komentar
Komentar Hacker News
Dulu saya pernah membuat pemeriksaan port untuk memastikan apakah sebuah layanan masih hidup, dan hanya dengan membuka beberapa port TCP di mesin-mesin itu, saya pernah menjatuhkan separuh perusahaan
Masa-masa yang absurd
Kita sudah melangkah sangat jauh
https://en.wikipedia.org/wiki/Ping_of_death
Di sebagian mesin juga ada kerentanan SMB yang tidak dipatch selama bertahun-tahun. Saat itu Metasploit sudah ada, jadi hanya dengan beberapa perintah, VNC bisa diinjeksi ke sebagian besar host Windows di jaringan lokal. Sekarang setidaknya kecepatan patching sangat cepat
Ah, lubang kelinci retro computing. Terpisah secara aman dari konsekuensi dunia nyata, tetapi tetap sangat memuaskan
Benar-benar jebakan madu untuk para geek. Pada akhirnya saya menekan tombol perluasan “lihat 6 komentar lagi”
Mungkin hari ini saya masih bisa menyelesaikan sedikit pekerjaan
Tapi 486? Terlalu banyak kenangan tentang blue screen dan penantian tanpa akhir saat disk swapping karena memorinya tidak sanggup. Sepertinya masih terlalu dini bagi saya
“Solusinya sudah jelas” memang benar-benar tepat
Mungkin mereka terus membaca disassembly kode trap sampai menemukan masalahnya. Sepertinya tidak mungkin mereka bisa memakai QEMU atau sarana debugging lain
Wajib juga membaca metode yang terkubur di dalam komentar tersembunyi di bagian akhir
Bukan komentar dengan vote terendah yang disembunyikan, juga bukan yang terbaru atau terlama. Rasanya acak dan tidak perlu
Kalau masalahnya ruang, menurut saya lebih baik diberi pagination daripada disembunyikan
Hal-hal seperti adapter slotket yang dulu dipakai untuk kompatibilitas di board Abit, Asus, mungkin juga MSI lama benar-benar punya kemampuan overclocking
Kuncinya adalah berapa kecepatan RAM-nya, dan sampai clock berapa motherboard bisa bertahan pada pengaturan multiplier. Itu masa overclocking yang relatif awal, saat ada Celeron dan Pentium II
Suatu waktu, demi kompatibilitas, saya memasang Celeron 600 ke adapter, lalu memasangnya lagi ke adapter Slot II to Socket 370 dalam konfigurasi seperti [1], dan berjalan baik di 1,2GHz. Bahkan seingat saya pernah menaikkannya sampai 1,4GHz di Windows ME, dan akhirnya CPU itu hangus
[1]http://krick.3feetunder.com/370mod/
Jawaban pada pertanyaan itu benar-benar luar biasa
Topiknya bagus dan jawabannya juga sangat bagus
Keren bahwa orang yang bertanya juga memberi jawabannya sendiri
Saya suka hal seperti ini. Senang sekali orang-orang tertarik pada retro computing
Mendokumentasikan masalah dan solusinya seperti ini untuk semua orang adalah hal yang baik
Saya sudah tahu bahwa CPUID ini ide yang buruk
Kenapa timestamp pertanyaan dan jawabannya sama?
Mungkin dia menilai bahwa mengunggah informasi ini dalam bentuk tanya-jawab SO akan lebih bertahan lama daripada posting blog yang tidak akan ditemukan siapa pun
Apakah buruk kalau saya sudah tahu ini tentang apa tanpa membukanya?
Sudahlah, saya harus pergi meneriaki anak-anak zaman sekarang agar keluar dari halaman rumah saya
Yang bisa diandalkan hanya kecerdikan, dan kalau perlu para jagoan yang bisa dipanggil lewat telepon rumah. Tidak ada internet hebat yang penuh jawaban dengan tingkat kegunaan yang berbeda-beda