NT 3.1 kernel में break-in करने की कोशिश पर मेरी 486DX4 मशीन reboot क्यों हो जाती है?
(retrocomputing.stackexchange.com)- Windows NT 3.1 में
i386kdसे Ctrl-C break-in करने परkd>prompt आने के बजाय target 486DX4 system reboot हो जाता है, और इसका कारण enhanced 486 compatibility की समस्या निकला - NTOSKRNL.EXE के
KiSaveProcessorControlStateऔरKiRestoreProcessorControlStateCPU type जाँचते समय word compare का उपयोग करते हैं, जिससे CPUID support वाले 486 को गलती से Pentium या उससे ऊपर समझ लिया जाता है - KPRCB के
CpuTypeऔरCpuIDसाथ में पढ़े जाने से CPUID support वाले 486 का model number 256 ज़्यादा समझा जाता है, और उसके परिणामस्वरूप 486 में मौजूद न होने वाले CR4 register को access किया जाता है - मूल 486DX-33 और SMM के बिना write-through Am486DX4-NV8T पर kernel debugging सामान्य रूप से काम करती है, जिससे समस्या CPUID instruction देने वाले enhanced 486 तक सीमित हो जाती है
- NTOSKRNL.EXE के भीतर दो
cmp ds:word_FFDFF138, 5स्थानों को byte compare में patch करने पर मूल NT 3.1 Advanced Server और NT 3.1 SP3 दोनों में यह ठीक किया जा सकता है
पुनरुत्पादन वातावरण और लक्षण
- Compaq ProSignia 3080 पर Windows NT 3.1 install करने के बाद kernel debugging की कोशिश की गई
- यह system वास्तविक उपयोग में Windows NT 3.1 चलाता था, और लगता है कि यह उन मशीनों में से एक था जिन्हें Windows NT ने स्पष्ट रूप से target किया था
- RAM को 128MB तक बढ़ाया गया, और socketed Intel 486DX-33 को AMD enhanced 486DX4-SV8B से बदल दिया गया
- यह CPU write-back cache और SMM support करता है तथा voltage adapter socket में लगाया गया है
- BIOS में 486DX4 support का प्रबंध बाद के लिए छोड़कर CPU को 2x multiplier पर jumper से set किया गया
- chipset में L1 write-back support के बिना 2x multiplier पर set करने से इसके Intel 80486DX2-66 के साथ software-compatible होने की अपेक्षा थी
- Intel 80486DX2-66 इस system का एक supported option है
- Windows NT 3.1 installation स्वयं सामान्य रूप से पूरी हो गई
- Windows NT 3.1 CD में पूर्ण debugging symbols शामिल हैं, इसलिए kernel debugging आज़माई गई
- उद्देश्य यह जाँचना था कि NetDDE event log में errors क्यों छोड़ रहा है
- एक खास EISA Ethernet card के साथ system crash होने की समस्या भी थी, और hardware fault की संभावना बनी हुई थी
- आधुनिक Windows 10 development kit के
kdयाntkdकी जगह Windows NT 3.1 के साथ शामिलi386kdका उपयोग करना पड़ता है ताकि kernel debugging configuration सही रहे i386kdमें Ctrl-C break-in की कोशिश करने पर target machinekd>prompt देने के बजाय reboot हो जाती है
जिन कारणों को खारिज किया गया
- memory सही पाई गई
- यह system file corruption नहीं था
- kernel के debugging के लिए रुकने पर system को reboot करने वाला hardware watchdog सक्रिय नहीं था
- host side का USB-serial adapter सामान्य रूप से communicate कर रहा था
- वह नकली PL2301 जैसा device दिखता है, लेकिन debugger command गलत भेजकर “reboot system” command transmit नहीं की गई थी
- KD protocol में वास्तव में reboot system command मौजूद है
- यह motherboard के remote management या alert options से भी संबंधित नहीं था
वास्तविक कारण: enhanced 486 और NT 3.1 kernel की असंगति
- Windows NT 3.1 kernel enhanced 486 processors के साथ compatible नहीं है
- और अधिक सटीक रूप से, समस्या उन 486 processors पर आती है जो
CPUIDinstruction प्रदान करते हैं - kernel debugging निम्न CPUs पर सामान्य रूप से काम करती है
- मूल रूप से लगा हुआ 486DX-33
- SMM के बिना older non-enhanced core वाला write-through Am486DX4-NV8T
- यदि उद्देश्य सिर्फ NT 3.1 kernel debugging को आज़माना है, तो Windows NT 3.1 के साथ मूल रूप से compatible CPU का उपयोग करना अधिक उपयुक्त है
- यदि NT को ही ठीक करना है, तो NTOSKRNL.EXE में CPU type detection bug को patch करना होगा
वह kernel code path जहाँ समस्या फटती है
- असंगति का सीधा कारण
KiSaveProcessorControlStateमें bug है- इसकी counterpart function
KiRestoreProcessorControlStateमें भी ऐसा ही bug है
- इसकी counterpart function
KiSaveProcessorControlStateको NTOSKRNL.EXE के भीतर तीन स्थानों से call किया जाता है- जब कोई exception
KdpTrapके जरिए kernel debugger तक reflect होती है- Ctrl-C break-in में timer tick interrupt के अंदर break-in polling feature के दौरान breakpoint exception होती है
- जब
KeBugCheckExcall होता है, यानी “blue screen” की स्थिति में - जब
KiSaveProcessorStatecall होता है- यदि IDA का NTOSKRNL.EXE control-flow analysis पूरा है, तो यह function export नहीं होती और NTOSKRNL के भीतर भी call नहीं की जाती, इसलिए व्यवहार में यह path संभवतः आता ही नहीं
- जब कोई exception
KiSaveProcessorControlStateविस्तारितCONTEXTstructure में processor control state save करता है- यह CR0, CR2, CR3 save करता है
- Pentium या उससे ऊपर पर CR4 भी save करता है
- DR0~DR3, DR6, DR7 debug registers save करता है
- और GDT address, IDT address, active TSS selector, LDT selector जैसी global protected-mode settings भी save करता है
KPRCB fields की गलत व्याख्या
- processor type detection के लिए KPRCB की values का उपयोग होता है
- KPRCB, KPCR का हिस्सा है
- boot processor या single-processor system की KPRCB virtual address
FFDFF120पर होती है, और इस method में इसे hardcode किया गया है
- Geoff Chappell के अनुसार NT 3.1 KPRCB के संबंधित fields इस प्रकार हैं
+018 CHAR CpuType+019 CHAR CpuID+01A UShort CpuStep
- इन fields को
KiSetProcessorTypeमें initialize किया जाता है- 486 processor के लिए offset 18 byte को 4 पर set किया जाता है
- Pentium processor को 5 पर set किया जाता है
- Pentium Pro और Pentium II/III processors को 6 पर set किया जाता है
- offset 19 byte एक boolean flag है, जो बताता है कि processor CPUID support करता है और “reasonable” तरीके से काम करता है या नहीं
- समस्या वाला compare instruction
FFDFF138address के byte को नहीं बल्कि word को पढ़ता हैFFDFF138, KPRCB की शुरुआत से 18h byte दूर स्थित है- इसलिए
CpuTypeके साथ उसके ठीक बाद वाला byteCpuIDभी model number के हिस्से की तरह पढ़ लिया जाता है
- जो processors CPUID support करते हैं, उनका model number वास्तविक से 256 अधिक माना जाता है
- CPUID support वाला 80-4-86, Windows NT 3.1 में 80-260-86 की तरह treat किया जाता है
- 260, Pentium के मानक 5 से बहुत बड़ा है, इसलिए kernel मान लेता है कि उस processor में CR4 होना चाहिए
- enhanced 486 में CR4 नहीं होता, इसलिए break-in path में समस्या आती है
patch करने का तरीका
- bug की पुष्टि हो जाने पर fix सरल है
- NTOSKRNL.EXE में
cmp ds:word_FFDFF138, 5instruction केवल दो बार दिखाई देता हैKiSaveProcessorControlStateKiRestoreProcessorControlState
- दोनों स्थानों पर word compare को byte compare में बदलना होगा
- hex editor से निम्न byte sequence को दो बार patch करें
- पहले:
66 83 3D 38 F1 DF FF 05 - बाद में:
90 80 3D 38 F1 DF FF 05
- पहले:
- यह fix मूल NT 3.1 Advanced Server distribution के NTOSKRNL.EXE और NT 3.1 SP3 दोनों पर लागू होती है
1 टिप्पणियां
Hacker News टिप्पणियाँ
बहुत पहले मैंने यह देखने के लिए कि कोई service चालू है या नहीं, एक port check बनाया था, और सिर्फ machines पर कुछ TCP ports खोलने भर से कंपनी का आधा हिस्सा ठप कर दिया था
वे सचमुच अजीब दिन थे
हम सच में बहुत आगे आ चुके हैं
https://en.wikipedia.org/wiki/Ping_of_death
कुछ machines में सालों तक patch न की गई SMB vulnerability भी थी। वह दौर ऐसा था जब Metasploit पहले से मौजूद था, इसलिए कुछ commands से local network के ज्यादातर Windows hosts में VNC inject किया जा सकता था। आजकल कम से कम patching की रफ्तार बहुत तेज है
आह, retro computing का rabbit hole। real world के परिणामों से नुकसान-रहित तरीके से अलग, फिर भी बेहद संतोषजनक
geeks के लिए असली honeypot है। आखिरकार मैंने “6 और comments देखें” वाला expand button दबा ही दिया
शायद आज कुछ काम हो पाए
लेकिन 486? blue screens की और memory संभाल न पाने के कारण disk swapping में अंतहीन इंतजार की बहुत सारी यादें ताजा हो जाती हैं। लगता है मेरे लिए अभी भी बहुत जल्दी है
“समाधान तो साफ है” सचमुच सही बात है
शायद trap code की disassembly लगातार पढ़ते-पढ़ते problem मिली होगी। लगता नहीं कि QEMU या कोई दूसरा debugging तरीका इस्तेमाल कर पाए होंगे
अंत में hidden comment के अंदर दबे हुए तरीके को भी जरूर पढ़ना चाहिए
यह lowest-voted comments भी नहीं छिपाता, न ही newest या oldest comments। random जैसा लगता है और unnecessary है
अगर space की समस्या है, तो छिपाने के बजाय pagination डालना बेहतर होगा
पुराने Abit, Asus, और शायद MSI boards पर compatibility के लिए इस्तेमाल होने वाले slotket adapters जैसी चीजों में सचमुच overclocking की क्षमता थी
सवाल यह था कि RAM speed कितनी है, और motherboard multiplier settings में किस clock तक टिक सकता है। वह Celeron और Pentium II वाला, overclocking का अपेक्षाकृत शुरुआती दौर था
एक समय compatibility की वजह से मैंने Celeron 600 को adapter में लगाया, फिर उसे Slot II to Socket 370 adapter में लगाकर [1] जैसी configuration में 1.2GHz पर अच्छी तरह चलाया। शायद Windows ME पर उसे 1.4GHz तक भी ले गया था, और आखिरकार उस CPU को जला बैठा
[1]http://krick.3feetunder.com/370mod/
सवाल पर दिया गया जवाब सचमुच शानदार था
topic भी अच्छा था और जवाब भी बहुत अच्छा था
यह बढ़िया है कि सवाल पूछने वाले ने खुद जवाब भी दिया
मुझे ऐसी चीजें पसंद हैं। यह देखकर सच में खुशी होती है कि लोग retro computing में दिलचस्पी लेते हैं
ऐसी problems और solutions को सबके लिए document करना अच्छी बात है
मुझे पता था कि यह CPUID वाली चीज अच्छी idea नहीं है
सवाल और जवाब के timestamps एक जैसे क्यों थे?
शायद उन्होंने सोचा होगा कि यह जानकारी SO के Q&A format में डालना, किसी ऐसे blog post से ज्यादा लंबे समय तक बचेगा जिसे कोई ढूंढ ही न पाए
क्या यह बुरी बात है कि खोले बिना ही समझ गया कि यह क्या है?
खैर, अब मुझे आजकल के बच्चों पर चिल्लाने जाना है कि मेरे lawn से दूर रहें
भरोसा करने को बस अपनी सूझबूझ थी, और जरूरत पड़ने पर landline से बुलाए जा सकने वाले experts। ऐसा शानदार internet नहीं था जो अलग-अलग उपयोगिता वाले जवाबों से भरा हो