https://retrocomputing.stackexchange.com/questions/19655/why-does-trying-to-break-into-the-nt-3-1-kernel-reboot-my-486dx4-machine Stack Exchange Network Stack Exchange network consists of 183 Q&A communities including Stack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers. Visit Stack Exchange [ ] Loading... 1. + Tour Start here for a quick overview of the site + Help Center Detailed answers to any questions you might have + Meta Discuss the workings and policies of this site + About Us Learn more about Stack Overflow the company, and our products. 2. 3. current community + Retrocomputing help chat + Retrocomputing Meta your communities Sign up or log in to customize your list. more stack exchange communities company blog 4. 5. Log in 6. Sign up Retrocomputing Stack Exchange is a question and answer site for vintage-computer hobbyists interested in restoring, preserving, and using the classic computer and gaming systems of yesteryear. It only takes a minute to sign up. Sign up to join this community [ano] Anybody can ask a question [ano] Anybody can answer [an] The best answers are voted up and rise to the top Retrocomputing 1. Home 2. 1. Public 2. Questions 3. Tags 4. Users 5. Companies 6. Unanswered 3. Teams Stack Overflow for Teams - Start collaborating and sharing organizational knowledge. [teams-illo-free-si] Create a free Team Why Teams? 4. Teams 5. Create free Team Teams Q&A for work Connect and share knowledge within a single location that is structured and easy to search. Learn more about Teams Why does trying to break into the NT 3.1 kernel reboot my 486DX4 machine? Ask Question Asked 2 years, 5 months ago Modified 2 years, 5 months ago Viewed 52k times 188 I installed Windows NT 3.1 on a Compaq ProSignia 3080 system, because of several reasons: I know that this machine was running Windows NT 3.1 when it was in productive use. And I think this machine was one of the machines Microsoft explicitly targeted with Windows NT. For improved performance, I maxed out the RAM at 128MB and swapped the socketed Intel 486DX-33 by an AMD enhanced 486DX4-SV8B (write-back cache and SMM) in a voltage adapter socket. I postponed dealing with BIOS support for 486DX4 processors, and jumpered the processor to a 2x multiplier. Without chipset support for L1 write-back and with a 2x multiplier, the processor is supposed to be software compatible to the Intel 80486DX2-66, which is a supported option for that system. While installing Windows NT 3.1 worked perfectly, I really like to tinker with my retro stuff. The Windows NT 3.1 CD comes with the full set of debugging symbols, I'm curious into investigating why NetDDE throws an error into the event log, and the system crashes with a specific EISA ethernet card (which might be due to faulty hardware), so I decided to dive into kernel debugging. Setting up kernel debugging is straight-forward, once you realize you should use the i386kd executable supplied with Windows NT 3.1 instead of kd/ntkd from the current Windows 10 develepmont kit. As soon as I want to break in (using Ctrl-C in i386kd), the target machine reboots instead of providing a kd> prompt. I already tested the following: * Memory in that system is OK * The system files are not corrupted * There is no hardware watchdog active that reboots the machine when the kernel is interrupted for debugging * The USB-to-serial adapter I use (which seems to be a counterfeit PL2301) in the host communicates properly. It's not mis-sending some debugger commands as "reboot system" command (the KD protocol provides one, though!) * It's not related to some remote management or alerting options provided by the mainboard. * compatibility * debugging * bugs * 80486 Share Improve this question Follow edited Apr 25, 2021 at 14:11 user3840170's user avatar user3840170 21k44 gold badges8686 silver badges140140 bronze badges asked Apr 19, 2021 at 19:00 Michael Karcher's user avatar Michael KarcherMichael Karcher 7,29633 gold badges2424 silver badges4646 bronze badges Add a comment | 1 Answer 1 Sorted by: Reset to default [Highest score (default) ] 270 Short explation The Windows NT 3.1 kernel is incompatible with enhanced 486 processors. Specifically, it is incompatible with 486 processors providing the CPUID instructions. Kernel debugging works fine with the 486DX-33 that was originally installed in the machine, and with the older non-enhanced core in a write-through Am486DX4-NV8T without SMM. If your goal is just toying around with NT 3.1 kernel debugging, you might want to use a processor that is compatible with Windows NT 3.1 out-of-the-box. If you are as curious as me, you might want to fix Windows NT. Keep reading in this case. The underlying issue The incompatibility is due to a bug in KiSaveProcessorControlState (and a similar bug in the counterpart KiRestoreProcessorControlState), which is called from three locations inside NTOSKRNL.EXE: 1. When an exception is reflected to the kernel debugger using KdpTrap (If I use Ctrl-C to break into the kernel debugger, a breakpoint exception is raised from the break-in polling functionality in the timer tick interrupt) 2. When KeBugCheckEx is called (i.e. the "blue screen") 3. When KiSaveProcessorState is invoked. This appears to never happen, as this function is neither exported nor called from inside NTOSKRNL if the control flow analysis by IDA in NTOSKRNL.EXE is exhaustive. This function is supposed to save the processor control registers into an extended CONTEXT structure. Its disassembly looks like this: .text:80106740 ; __stdcall KiSaveProcessorControlState(x) .text:80106740 public _KiSaveProcessorControlState@4 .text:80106740 _KiSaveProcessorControlState@4 proc near .text:80106740 .text:80106740 dest = dword ptr 4 .text:80106740 .text:80106740 mov edx, [esp+dest] .text:80106744 xor ecx, ecx .text:80106746 mov eax, cr0 .text:80106749 mov [edx+0CCh], eax .text:8010674F mov eax, cr2 .text:80106752 mov [edx+0D0h], eax .text:80106758 mov eax, cr3 .text:8010675B mov [edx+0D4h], eax .text:80106761 mov [edx+0D8h], ecx .text:80106767 cmp ds:word_FFDFF138, 5 .text:8010676F jb short @@before_pentium .text:80106771 mov eax, cr4 .text:80106774 mov [edx+0D8h], eax .text:8010677A @@before_pentium: .text:8010677A mov eax, dr0 .text:8010677D mov [edx+0DCh], eax .text:80106783 mov eax, dr1 .text:80106786 mov [edx+0E0h], eax .text:8010678C mov eax, dr2 .text:8010678F mov [edx+0E4h], eax .text:80106795 mov eax, dr3 .text:80106798 mov [edx+0E8h], eax .text:8010679E mov eax, dr6 .text:801067A1 mov [edx+0ECh], eax .text:801067A7 mov eax, dr7 .text:801067AA mov dr7, ecx .text:801067AD mov [edx+0F0h], eax .text:801067B3 sgdt fword ptr [edx+0F6h] .text:801067BA sidt fword ptr [edx+0FEh] .text:801067C1 str word ptr [edx+104h] .text:801067C8 sldt word ptr [edx+106h] .text:801067CF retn 4 .text:801067CF _KiSaveProcessorControlState@4 endp This function is supposed to save all control register (CR0, CR2, CR3, and CR4 on pentium and later processors), all debug registers (DR0-DR3, DR6, DR7) and various global protected mode settings (the address of the GDT, the address of the IDT, the selector of the active TSS and the selector of the LDT). To detect the processor type, it uses a value from the KPRCB (Kernel Processor Control Block). The KPRCB is part of the KPCR (Kernel Processor Control Region). The KPRCB for the boot processor (or the only processor on uniprocessor systems) is located at virtual address FFDFF120, which is hard-coded into this method. Geoff Chappell writes this about the relevant part of the KPRCB in NT 3.1: +018 CHAR CpuType; +019 CHAR CpuID; +01A UShort CpuStep; These members of the KPCRB are initialized by KiSetProcessorType, which identifies the relevant processors correctly (but be aware that it mistrusts processors that report a CPUID feature level above 3 and considers them as "generic non-CPUID capable 586 compatible processors". The byte at offset 18 is set to 4 for 486 processors, 5 for Pentium processors and 6 for Pentium Pro and Pentium II/III processors. The byte at offset 19 is a boolean flag that indicates whether the processor support CPUID and it behaves "reasonable". A very attentive reader might already have noticed the bug: The CMP instruction uses the word at address FFDFF138 (which is 18h bytes into the KPRCB), instead of the byte at that address. This means the byte at offset 19h in the KPRCB is considered part of the model number. If a processor supports CPUID, its model number is considered to be 256 bigger than it actually is. This means Windows NT 3.1 treats a CPUID capable 80-4-86 processor as 80-260-86 processor. And as 260 is way larger than 5 (Pentium), that processor better had CR4. The fix The fix is obvious once the bug is identified. The instruction cmp ds:word_FFDFF138, 5 only appears twice in NTOSKRNL.EXE, specifically in KiSaveProcessorControlState and KiRestoreProcessorControlState, and it needs to be patched to be a byte compare instead of a word compare. Use your favorite hex editor to patch 66 83 3D 38 F1 DF FF 05 to 90 80 3D 38 F1 DF FF 05, two times. This fix applies both the NTOSKRNL.EXE from the original NT 3.1 Advanced Server distribution as well as NT 3.1 SP3. Share Improve this answer Follow answered Apr 19, 2021 at 19:00 Michael Karcher's user avatar Michael KarcherMichael Karcher 7,29633 gold badges2424 silver badges4646 bronze badges 12 * 34 This is an great example of a self-answered question done right. - Criggie Apr 20, 2021 at 11:06 * 15 @Vilx- Free time built civilization. - J... Apr 20, 2021 at 14:10 * 35 I see your NOP (90h), and raise you an explicit DS prefix (3Eh). It's all about the style points! :-) Any instruction with a memory operand can have a segment prefix. In this case, the DS prefix is implicit/implied, but it can be explicitly specified without changing the meaning of the instruction. Both ways work to pad the extra leftover byte of space, but the explicit DS prefix does not change the instruction's execution speed, whereas the NOP actually takes 1 cycle of time to execute (plus possible decoding). - Cody Gray - on strike Apr 21, 2021 at 0:34 * 23 The really interesting question is, how on earth did you get the idea to look at _KiSaveProcessorControlState in the first place, when all you had was a rebooting PC without a usable debugger? - Guntram Blohm Apr 22, 2021 at 11:06 * 19 @GuntramBlohm NTOSKRNL.EXE + debug symbols + IDA helped me understand how the remote break-in is supposed to work. I knew that something in the remote break-in code path before the first debug packet is sent is going to reboot my machine. So I patched "JMP SHORT $" instructions into the relevant code-path. If I placed it before the crash point, the machine hangs. If I placed it after the crash point, the machine reboots. This allowed me to "bisect" where the crash is happening. BTW: Good question, but I don't think the debugging story fits the Q/A format well, so I left it out. - Michael Karcher Apr 22, 2021 at 20:23 | Show 7 more comments You must log in to answer this question. Not the answer you're looking for? Browse other questions tagged * compatibility * debugging * bugs * 80486 . * The Overflow Blog * Like Python++ for AI developers * Being creative with math: The immersive artist who traded a sketchpad for a... * Featured on Meta * Alpha test for short survey in banner ad slots starting on week of September... * What should be next for community events? * Should we avoid the low rep voting experiment? Related 43 Why does the kill-screen glitch occur in Pac-man? 9 Why does MS-DOS 5.0 EDIT hang on my XT-class machine with a German 102-key keyboard? 48 Why does the 80486 take longer to execute simple instructions than complex ones? 37 Why does Windows 1.01 crash at the splash screen? 76 Why does the infamous "ENGAGERIDLEYMOTHERFUCKER" Metroid password break NES emulators? 37 In the classic "Windows 98 crashes live on CNN" video, why does the BSOD appear so oddly? 13 Why does the FRE() function in CBM BASIC v2 return negative values? Hot Network Questions * What are some factually incorrect quantitative finance answers generated by AI? * Why does ranges::for_each return the function? * Blender Accessibility Features * Being asked to sign a release form after being terminated * How to move forward after microaggression allegations against my TA * Is it possible to work on your personal idea as PhD thesis? * Is there a resource for learning to read mathematical notation/ equations/formulae? * My husband (her father) jokes/plays in ways my daughter doesn't always find funny, he says he should be able to do it if he wants * What does "(which see)" means in various Emacs help docstrings? * Why is each transaction broadcast twice in the Bitcoin network? * When is "ct" silent? * Low-noise/Stable power source options * How were the signs for logical and arithmetic operators decided? * What does this sentence mean in Stephen King's IT? * What was the big pillar-shaped Beholder in 3.5? * What should I do if I am strongly burned out at work, but resigning now would cause problems for my coworkers and burn bridges? * Naive question: Origin of the Holy Ghost * Is there an algorithm to generate graphs with given order and diameter? * Daisy chaining APs or connect them into the central router? * How would you deal with an (actual) etymology that makes no sense in-game? * What happens when a sniper picks up a bigger gun in Mutants and Masterminds? * What do we know about Andy Kaufman's SNL audition? * story ID question: planets in interstellar space run on "slow speed" with people awaking for a few years, then sleeping for centuries * Does a company have to have your login information to verify your identity? more hot questions Question feed Subscribe to RSS Question feed To subscribe to this RSS feed, copy and paste this URL into your RSS reader. [https://retrocomputi] * Retrocomputing * Tour * Help * Chat * Contact * Feedback Company * Stack Overflow * Teams * Advertising * Collectives * Talent * About * Press * Legal * Privacy Policy * Terms of Service * Cookie Settings * Cookie Policy Stack Exchange Network * Technology * Culture & recreation * Life & arts * Science * Professional * Business * API * Data * Blog * Facebook * Twitter * LinkedIn * Instagram Site design / logo (c) 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA. rev 2023.9.28.43651 Your privacy By clicking "Accept all cookies", you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy. Accept all cookies Necessary cookies only Customize settings