I remember not believing this was a real thing and sshd into a production server and ran the instruction. The connection dropped and I had to get on a bus to go reboot that machine. Lesson learned.
wait........a production machine! Why? You do this on a test machine just in case it's legit. "this program might fry your computer and delete all your data". "yes! lets try it right now on the most important machine I have!" lol With that said I was mad that my parents insisted I had to turn off my computer on 11/31/99 around 10pm or so. They bought into the whole "your computer will explode after y2k" bs. ok sure, but wouldn't it still explode even after keeping it off over night?
So how this works: 0F C7 is the prefix for "exchange two things". The next two bits say what to swap - three variants of a memory location, or two registers. So if you want to swap EAX with ECX, you encode that as either C8 (swap ecx and eax) or C1 (swap eax and ecx - which has the same meaning). If you want an instruction to keep the memory bus locked while it runs, you prefix it with F0. That should work like "lock memory bus, run whole operation, unlock memory bus". However, for the 0F C7 instruction, Intel implemented it as "lock memory bus, run operation, unlock memory bus if we accessed memory".... so it never unlocks the memory bus if you ever run a locked exchange between registers, and the instruction fetcher is unable to ever fetch any more instruction. No compiler will ever swap two registers with a memory bus lock, because it's not a meaningful or useful operation, but you can encode it, and it was very much untested & broken. And unlike many other bugs from the time, this is not fixable with any kind of OS workaround. The instruction has no enable bits you could leave off. I don't know if there is microcode in the CPU that could update around this, but that might be the only thing you could do - you know, or buy a different CPU.
The wikipedia article documents a workaround which relies on the fact that this instruction is invalid and the processor is blocked from raising an invalid instruction exception. The workaround involves making sure the processor generates a page fault _before_ it can fetch the exception handler, which is enough to make the processor release the bus lock.
Apparently disabling the cache prevents the bug from happening under DOS/Win98 according to R.Collins write up, far from the optimal solution but interesting nonetheless.
Thank you for providing this excellent explanation. I had a Pentium 133mhz (overclocked to 150mhz) in a Gateway 2000 machine that was impacted by this bug. I remember putting the values into an assembly compiler & linker to make the com file (tasm/tlink). I was interested in learning what the processor was attempting to do that resulted in the behavior, and at the time (pre-2000) my CompSci professors couldn't answer that question. Thank you for providing such a thorough explanation to satisfy curiosity and passion for learning.
Re: Microcode. This bug was the main impetus for Intel moving to microcode so they could patch issues with chips after fabrication and end user installation.
I was also not aware that you could do something like this to the main function. But it worked. However, trying it on a modern c compiler, you most likely get an error and it won't compile.
@@bitsundbolts Regular C does not have any sort of data types for symbols. The compiler and linker are just working as intended - the compiler creates a symbol called "main" with the array contents then the linker finds the symbol named "main" and sets it to the entry point.
ONE THING TO NOTE: All of these solutions would have good use of a RET instruction (0xC3, 00C3 and ALT+195 respectively) at the end as a fifth byte. This prevents the program from running into random memory, and rather gracefully exit in the case your CPU does /not/ have the F00F bug.
@@bitsundbolts Not having the RET, you would basically just keep executing random data left over from something else as code (DOS and early versions of Windows have no boundary-protection on memory allocations). This can also in many cases lead to a crash, and you potentially get situations where it would not have been possible to differentiate between a crash from the F00F-bug and a crash from executing garbage data.
@@TheMovieCreator This code would crash on my 13900K too most likely, because it is basically running the execution off a cliff. Of course since I run DOS either in an emulator or a VM, it doesn't require a full system reboot. However, F00F would crash a Windows NT system running NTVDM most likely on a P5, but on a later processor the NTVDM instance would either error out or the frozen instance would be able to be terminated like any other Windows process. Still, it would be best to add the RET instruction so an unaffected processor would cleanly exit the test program.
It's interesting to note that both the F00F bug and the FDIV bug arose from flawed implementations in the microcode of these CPUs. In the case of the F00F bug it was the edge case that one could encode a locked (atomic) compare-and-exchange instruction with only registers as an operand (which no compiler would do, for obvious reasons). It was a use case of the instruction Intel simply failed to account for. In the case of the FDIV bug it was something far more hilarious: the designers of the Pentium CPUs simply forgot to include half the lookup table for the floating point instruction in question, which resulted in the higher half of the lookup table containing invalid values. Both cases can ultimately be said to have arisen because of incomplete QA testing.
@@thewhitefalcon8539 That is actually not true. At least if most of the research that was done into it is to believed. The FDIV bug in particular has been reported multiple times as being the result of "half a lookup table missing in the microcode ROM". No x86 CPU designed by Intel has ever been truly solely hardwired or solely microcode based. The original Pentiums were no exception. In fact, the more advanced the CPUs became, the more reliant they became on exceedingly more modular design architecture that actually translated x86 instructions into more generic, RISC-like, u-ops, which in turn could be executed by the various units on the die. This process really took off with the Pentium Pro, but had already started with Intels 486es. Starting with the Pentium II, the microcode could even be updated by software running on it. Ken Shirrif has a nice blog in which he discusses various topics, including various CPU designs and in which he often zooms in on the CPU dies themselves and analyzes them.
I am not entirley sure anymore, but my university prof said something like they made an error when they copied the lookuptable, something/someone messed up and during copy paste not everyrhing was pasted correctly. I think it had something to do wit the size of the floppy disc or whatever.
What is really ironic is two things. 1. "FOOF" is one of the most potent and unstable oxidation agents ever created. It can make nearly anything explode on contact simply by providing oxidation (This is an awfully strange coincidence.) 2. The Pentium has a protection system that can be used to block instruction bugs preemptively, but by default it does so after attempt at execution.
Yeah, right!? All the compiler looks for is an "entry point" which all compilers agree is called main in the source code. It starts off at main and reads the bytes. I love seeing people really stretch the definition of what it means to be a C program
Educational though! I've been a casual C hacker for y-e-a-r-s and had no idea you could declare main as a character array and it would be run as raw ASM instructions. I wonder if that's unique to that particular C runtime? Gonna have to try that later ....
@@nickwallette6201should work on most compilers as ‘main’ is used the entry point but its just a label to an address so making a char array is the same as making a pointer, the content of the array are the instructions to execute. I jad never seen it done that way but it should work on most C versions.
@@nickwallette6201 It only works on old operating systems because modern ones would put the "main" byte array into a non-executable memory page as a security measure, so it will just crash, even if it contains valid machine mode.
I remember the f00f bug back in those days. It was a pretty big deal for a short time. I think there may have even been some talk of trying to intercept & block those instructions at the OS level in Windows, OS2 or Linux via a patch but I don't think any of that was ever implemented. Ultimately, with the release of the Pentium II months before the f00f bug was discovered and the relative popularity of AMD & Cyrix CPUs, all of which weren't affected by the bug, along with the internet still being in its infancy led to the bug being mostly forgotten about within a few months.
I read that the foof bug was addressed through operating system patches. However, I couldn't find any update just yet that would address the issue in Windows 98SE. As far as I know, no compiler would ever create such code, the sequence had to be deliberately created by the programmer like I show In this video. Congratulations btw, you found an unreleased video 😉
I remember seeing "checking for Intel Pentium f00f bug" when booting up Linux. No idea when it was inserted into the kernel, but probably in 2.0.x, 2.2.x or 2.4.x series. I think I was on a K6 by that point so never checked any further.
Had a machine with Pentium MMX as my "e-waste home server" in 2000s, and the bug was patched in Linux 2.4.30-ish already (can't remember which version it was running precisely). Tested it with a friend, and nothing bad happened, which made us "pleasantly disappointed".
@@bitsundbolts There was presumablly seen to be no point addressing the issue in windows 9x, because it's trivial for a bad program to take down 9x anyway. The issue only really matters in systems that actually try to provide isolation between programs/users.
Yes, it´s been ages since I saw someone using Alt+Numpad to enter characters. I used it always to make windows, menus, tables, borders, in Basic and Turbo Pascal. The codes that you entered are the decimal values of the hex code (F0=240, 0F=15, etc) As a curiosity, every notepad in Windows and most text editors in dos have that ability, to enter characters with Alt+Numpad. Yes, even Win10 notepad.
I remember using those in batch files in dos to build "graphical" menu's and later for the @ symbol. Also some azerty keyboards on the market didn't have the \ key.
@@renakunisaki I remember that in the manual for my first computer there was the ASCII table with the keyboard scan codes; that was for the user to be able to input characters from the keyboard if a key is broken. So, yes that was a thing from XT and DOS 3.3. Not sure if this was a DOS or BIOS feature.
As a well versed C programmer, I was impressed by the kludge over-complicated way this book showed how to do this. I'd be curious to know what book this was.
Yeah that made me look at my telly sideways and think "really? well OK, I can see that's valid but I'd never think to do that". I can see it being a way to inline assembly in C if you can't remember the "proper" arcane way of writing ASM in C with your particular compiler 😄
@@ncot_tech that's inline machine code more than inline assembly. There's nothing to assemble here lol Also, I doubt you could do this in assembly since this isn't a valid instruction. If I've understood correctly you can't put a register as the operand, which is precisely what is being done instead of a memory location. I would think most assemblers would validate this and throw an error.
It was created on Classic macOS, as the "cheap" alternative to the MPW workbench requiring a Mac II to develop a Mac application. MPW was the goto IDE, with the MacApp framework, used for Photoshop and Excel initial development, on macOS. And coming with the CodeWarrior IDE there was a framework named PowerPlant, an Object Oriented C framework, but with mixins instead of the inheritance from a unique Object root class. It is very like what is called traits, or protocols in modern frameworks.
Easier way to make a test executable file that triggers the bug, and also is basically the smallest possible file that does that: use a hex editor, make a new file with it and type the offending bytes at the beginning of the file (F0, 0F, C7, C8) and then save the file with a .COM extension. That gives you a 4-byte executable file that triggers the bug. (edit) the result is basically exactly the same as your 3rd method, but many people may find it easier to use a hex editor to make the file.
My very first computer had a Pentium 75 that was affected by this bug. I remember at least Linux (and possibly others) mentioning it in the dmesg as it booted, and in /proc/cpuinfo output, but I never did try to do this while I still had it. Interesting use of main-as-an-array-of-bytes. Maybe it exists somewhere, but it might be interesting to do it as inline asm. Thanks for the video, and the memories.
Method 3 is something I have never seen. Awesome programming method, and with the tightest coding size. Possibly you could do some other examples in the future using and explaining this method in greater depth?
I used to do this in Win XP. I'd use edit and write programs in asci characters up until I learned about the assembler in Debug utility program. I still have the notebooks full of conversion charts. It's basically a truncated Intel manual.
That batch file just mimics a sequence of commands in an interactive assembly language session by feeding the strings into the debugger program as if you had typed them interactively. "A" without parameters starts entering program instructors at the default program start address (xxxx:0100). "DW" stores the following double-word values in memory at the current program counter address (here: 0100), the full stop ends data input and return to command mode, and the final "G" runs it.
It's almost unbeliavable today to see that you can "write" an executable file directly with the keyboard or a text editor. No certificates, no security no checks no nothing. What great times.
C and C++ are still like this today. You can write the code in notepad, Word or IDE like Visual Studio, send it to the compiler and it will work. The user experience is obviously different, but the end result will be the same.
I find it surprising every time I run into an OS that tries to stop me from running an executable without chain of "mother-may-I" permissions. I know that's where we are today, and I know there's a reason why, but I still feel like Yosemite Sam yelling into my monitor, "I BOUGHT YOU. WHEN I SAY RUN, IIIII... MEEEAAAN... RUN!"
@@tabana_minamoto That's not the same thing. The original comment is talking about the ability of writing binary data for the CPU to execute in a file. This wouldn't work on a modern system because executable files have become a much more complex format, with headers and sections, and some platforms also require a valid digital signature for the code to run.
The reason it doesn't affect PII or newer is that, with the exception of the failed Netburst (Pentium 4) architecture, they are all based on the P6 (Pentium Pro) microarchitecture. Yes, even the latest and greatest (rotfl) intel CPUs are based on the P6 microarchitecture from 1995. Maybe that's part of their problem... I tried this on our P90 back in the day and it crashed. I don't think I used that command but I was reasonably fluent in C++ back then. More likely I edited doom.wad to trigger it somehow because I was into modding DOOM (and other games) before it was cool (and before there were modtools).
The cool thing is that CPUs have tons of small bugs, but I literally crashed my Haswell CPU with a virtualization instruction inside the VmWare, to make sure it was the CPU, VmWare crashed both on Windows hosts and on Linux hosts. But on Linux it took 2 minutes for the watchdog to kick in and kill the machine, Windows timeout was only 15sec (I was baffled by that, its usually the other way around, Windows is the one with ridiculous timeouts). It was a contention between core that caused a deadlock. Cool think it was fixable by upgrading the microcode.
To collect all debug commands or instruction from the echo output into a variable looks great. Most times i use a new temp file to collect the output and start debug with that file and then i delete the temp file at the end.
The reason to why main as an array does work is that being specified as an entry point on older linkers the byte array gets just dumped under "main" label. When the address of main gets called/jumped to, thanks to von Neumann everything past it is just treated as executable code, so the data is executed as "lock cmpxchg8b eax"
"Don't worry, we won't be doing a deep dive into machine code or assembly language." Awww... I would have enjoyed that! I remember an old instalment of The Bastard Operator From Hell having a hacked version of Doom that would trigger this bug when the player was killed and making the users play deathmatch to be able to save their work.
12:35 I wonder why is the cursor still blinking, if the cpu is locked up trying to fetch the next instruction? how does it execute instructions to blink the cursor? is it done with interrupts?
Others have pointed out that the cursor is rendered by the graphics card (text mode). So, even though the CPU is in a deadlock waiting for the next instruction that will never come, the screen looks like it's waiting for input.
This era had the last vestige of hardware accelerated video cards as they transitioned to just providing big arrays of pixels, and before modern GPUs. The cursor was implemented in hardware, on the video card.
There's a 3 byte way of locking Win9x and DOS, which works on any CPU: 0xFA 0xEB 0xFE. Save it as a COM file and run. It does: CLI ; lock interrupts loop: JMP loop ; infinite loop Yes, a DOS "program" running in Windows 9x will freeze the machine…
Win9x runs DOS programs by quickly switching between real 16-bit mode and protected 32-bit mode. It could be considered a form of assisted multitasking where the DOS part must pass control back to Windows. The way by which Microsoft implemented the switching to the 16-bit mode is quite hackish in its own right as you're not supposed to be able to get out of protected mode without rebooting.
to your batch file: yes, this is little endian encoding but you write 16-bit values, so the 2nd byte give you the two leading digits in your 16-bit value
The batch file seemed straightforward enough. It's creating a tempfile named t (no extension), and then writing stuff into the file using I/O redirection (> means open write, >> means open append). So you're creating a file with the contents: a dw 0x0ff0,0xc8c7 g And then running it in a program called debug. More specifically, the file is being used as the standard in. You should be able to replicate the same behavior without the shell script by just entering "debug" and then typing the above file contents out. You should expect to see the computer crash upon entering the "g" line, which seems to run the code. My guess for the meaning of the code is that "a" stands for append and "dw" for dword. The empty line is to stop writing stuff to memory and go back to the default command line mode of the debug program. So you're entering a line "dw 0x0ff0,0xc8c7" into memory and then executing it with g, where it gets, I'm guessing, assembled into a program and executed in-memory and because of the lack of entry point in the code and lack of memory protection against executing readwrite memory in user mode, what is supposed to be a dword variable ends up getting read by the program counter and executed as machine code, crashing the PC. Any DOS programmers in chat to tell me if that's accurate?
Just F00 in data can stop many programs. Example: ODBC and SQL can fail when see F00 in a CSV input file unless the field is quoted so treat that field as text.
Only ever heard of the FDIV bug - and that was through another YT video. Not sure how many people would be interested, but I would actually watch a video probing retro CPU for bugs - or straight up compatibility issues. Considering how many companies were making CPU in the 90's - even until the end.
What that "dos batch" is doing it is open "debug" program and "type" into it few lines "a" "dw 0ff0,c8c7" then "g" command for "GO" to run it. Thats kinda odd way of doing things would be more clear to just run "debug" command and type those commands into it manually to show what actually happens
Fun fact: this is how the original Xbox was modded. It can be used for arbitrary execution, but this originally wasn't a problem bc the Xbox switched from what was going to be either AMD's Athlon or Phenom CPUs to an Intel CPU that's a cross between the Pentium and Celeron. The AMD CPU didn't have this bug, the Intel one did.
I mean, this is the same company who thought that making slots for their processors, then designing their processors as boards for said slots, was a good idea.
Both editions of Windows 98 have a mitigation against this, which can be enabled via the Advanced button in msconfig. "Enable Pentium F0 (Lock CmpXchg) workaround". The help text for it is "Protects Intel Pentium and Intel Pentium MMX microprocessors against the malicious use of an instruction sequence that may interfere with the microprocessor's operation. This check box should be cleared when debugging programs."
Yes, the FDIV bug is more known. I just recently stumbled across this thing. Essentially, it is an illegal instruction and no compiler would trigger it - you have to specifically code the instruction for it to fail. The bug is that the processor should raise an exception and not dead-lock.
I remember there was a way to use icmp echo requests to cause a hang up a dialup modem and tell it to dial another number such as 911. It would be interesting to see if there was some way to make windows execute this instruction somehow remotely through the smb or iis.
I can tell you how this works: Hayes created a smart modem that uses the character sequence +++ followed by a delay as an escape sequence to switch between data and control mode, they patented it. Other manufacturers didn't want to pay royalties so they came up with using the character sequence +++ with no delay. The problem ocours when one of these modems tries to send data containing the sequence +++ which puts it into control mode. If you can find a way to make the victims modem send the character sequence +++ followed by a command, it will carry out the command. If you ping someone with a vulnerable modem with the character string +++ATH0DT911 it will make their modem hang up and then dial 911!
As the others said. You can also make the cursor not blink, make it larger or even disappear, if you use the 'prompt' command to output the correct ANSI escape sequences when you modify your command prompt. You can also set custom colours or inverse text as part of the command prompt using ANSI escape sequences.
@@LarsV62 The graphics card has hardware registers. Using ANSI codes relies on having a driver loaded which interprets the ANSI codes and converts them to register settings.
You have to stress the cpu w dosbox at very high cycles, you have to choose. When you start heretic, it will add a fpu driver that will reside in your cpu. After done, you have to do the same with duke3d, and just watch the intro. By oing it more times, duke can run good with higher cycles. You'll also get an audio acceleration, very good for youtube when using energy saving, netbook, tablet, etc. The fpu is off by default, you can just measure benchmark its performance, but can't benefit from it. When the fpu is on, you get an Intel autopilot, that's good for driving and shooter games, some games will become harder and mre challenging. Example is Dyna Blaster, the game will be logically harder, the opponents will be placed to harder positions. The Stunts will be corrected by the autopilot, to ensure you won't crash your car.
Fun fact: A boot sector with corrupted data, (not zeroed) regularly causes the dreaded blinking-cursor-on-top-left syndrome. That's how I know a drive wasn't wiped correctly.
@@RJARRRPCGP as far as I remember as long as it starts with the _magic bytes _ AA55 it will read the remaining 510 bytes as instructions, so my thinking was, what if you do AA55F00FC7C840
@@RJARRRPCGP IIRC you only need the two magic bytes for the PC to start reading instructions from the boot sector; i.e. AA55 So what if you wrote AA55F00FC7C8C3 at the beginning of the boot sector? It'd be more inconspicuous if for some reason the first few bytes were zeroed out to begin with, or maybe the boot code doesn't need the full 510 remaining bytes and you could slide/compress the useful data and inject those nasty instructions
How does the c version even work? Is the cpu trying to execute the array of chars because it’s called main? Could you hand write any machine code in that char array?
The last one is interesting because the cursor keep blinking despite the system being absolutely frozen (will be the graphics hardware managing the cursor, but I am used to software rather than hardware cursors)
I am not sure if microcode updates were already a thing back then. I read that an i486 had about 5000 lines of microcode. But I'm not sure if this bug could have been fixed by an update. The bug was discovered quite late and the Pentium II was already released. There was little incentive for Intel to fix this bug.
The Pentium Pro was apparently the first CPU to contain writable microcode, although a workaround was implemented at the Kernel level in Linux version 2.0.32-6 and presumably later Windows versions had one of some kind too.
Heh flashback... Used to know a 4 byte com file for clearing a byte of cmos memory to force it to be reset without having to access the inside of the case :D Although used edit and alt+numpad rather than echo console to file.
Since the fdiv bug i know that the mainboard bios can change the micro code of the CPU. But i never figure it out how to do it with an own program and if it is permanent or temporary. Maybe we can add some new instructions to the CPU or deleting some instruction that we don’t like to use.
I would love to see this bug executed in Windows with Media Player or the good old Winamp running in the background playing music to see if the music keeps playing, going in a loop, or just stops completely.
Ahh, Winamp 😌. I guess I should explore this bug further and see what happens on Pentium Pro systems (it shouldn't freeze - those CPUs should not suffer from this bug) - and also check my Pentium Overdrive (for 486 socket 3).
Presumably it would continue playing, similar to a skipping CD player. The exact mechanism for playing audio is dependent on the audio hardware and the driver for it, but in general, it involves a ring buffer that is filled with sample data at a regular interval. If the CPU stops working, the buffer just never gets updated with new data, and the audio hardware may continue to play the contents indefinitely. This happened in the old days when you assigned the wrong IRQ to the audio device. The sound card would set to work playing the buffer, and would raise an IRQ to let the driver know it was done playing a chunk -- generally it would do this before it got to the end of the buffer, to give the driver time to refill the first half while it continued playing the second half. However, the driver, having been configured with a different IRQ, would never see the request, and thus would never follow up to refill the buffer. Ergo, you would just get a continuous loop of a short phrase of audio until you reset the computer (or at least the sound card), because it wouldn't know the difference between an unfilled buffer and a buffer filled with exactly the same data that was already there. As far as it's concerned, it let the CPU know, and so its job is just to keep playing whatever's there now.
I may be completely wrong here, please correct me if I am. Cyrix CPUs aren't affected because they're all based off of i486 architecture instead of P5, and AMD went straight from i486-based K5 to K6, closer to the then-unreleased Pentium II than the original.
No. The CPU itself holds the bus locked that it needs to fetch instructions; sending an NMI is really just a high-priority interrupt, making it jump to a different location, that it then won't be able to fetch from since the CPU itself holds the bus locked. NMI is "Non-maskable interrupt". The name is slightly wrong since it has its own masking bits... Usually in the IRQ2 slot, as the original PC/AT could never trigger IRQ2 by design.
@@dascandy One of the workarounds is to break the interrupt table so the CPU raises a "broken interrupt table" interrupt after trying to raise the "invalid instruction" interrupt. Messing with the interrupt delivery sequence in any way seems to avoid the faulty state. It's plausible that raising an NMI could also break the CPU out of the faulty state. But if IRQ doesn't, and IRQ is not masked during this state, then NMI probably doesn't either.
What’s so complicated? I rly wanna know… I still have my copy of Borland C++ Builder 5 somewhere. Installing it, writing C program into editor and press the green arrow button on the top should be enough.
I did not code in C. I did have Borland Delphi 4 back then. It was difficult for me to find a compiler that allowed this one-liner. I tried it online with several tools, but it always failed to compile. Code warrior was the first Compiler I tried - and it worked. It was just the first thing that worked. Of course, there are better ways to get this done, I'm sure of that.
From intel 80386 i switched to AMD k5, k6, Tbred, but at last to intel core2quad CPU. I never used an intel Pentium CPU. Now i am back to 80386 using a DosBox emularor on an android tablet. The emulation works great. And now i am waiting for a mobile "quantum" CPU and another DosBox emulator for the quantum CPU android OS.😂
@@ezruy No, the CPU is not waiting like for an int, it can't load the next instruction so is completely halted and only a reset signal can unlock it. The blinking cursor is done by the VGA hardware.
I wouldn't expect an undocumented instruction to be reliable. It may do something. It may trigger an error. The point is, I wouldn't expect the results to be consistent across multiple implementations either.
True, however, the instruction is invalid and should raise an exception from the CPU, but it doesn't. It's interesting that this combination of instructions was found that locks up the CPU.
Exactly. Undefined instructions have, by definition, undefined behavior. Sometimes those instructions get assigned later in the architecture's life. Sometimes they do useful things. The 6502 mentioned above is known for having some useful undefined instructions that appear to combine functions of other, valid, instructions. The NES, for example, had some games that took advantage of undefined instructions. Emulator authors had to find this out the hard way, as they would've first built the emulator to support all the known valid instructions, and then would've run into ROMs that asked it to do something entirely different and unexpected -- which, of course, would've broken the game until the emulator was "fixed" to respond in the same way the hardware did.
@@nickwallette6201 yeah. It's kind of cool if you can find it useful, but it's also very dangerous. You never know if there will be an NES 2 that "fixes" the 6502 and now they are just NOPs or they create some kind of NMI or something.
Someone should try this and let everyone know. Somehow, I would be surprised if the emulated CPU follows the same behavior, but still interesting to know!
For the third method i have no number keys and no altgr key with a virtual keyboard app on a touch screen using DosBox emulator on an android tablet. Alt key + numbers is not working for output a character.
Hm, ok. Yes, you need to have those keys and the numbers must be entered using the NumPad. You could download the compiled file from my website and copy it to your emulator. But I don't know if that's possible.
@@bitsundbolts Thanks, but i don’t need it and i know how to use debug very well. I use a special version of debug that works and looks like the debug version from MS and it provide 16 bit and additional 32 bit instructions. I download it from the other alternative DOS. I put the link into the pinned comment of my videos. Thank you.
No, I haven't. It should work on unpatched versions since the F00F bug is hardware related. I believe there were patches for almost all operating systems to prevent this series of instructions from executing.
Oh, really? I thought all P5 CPUs were affected. I don't have access to a Tillamook. CPU Galaxy should check that, but I haven't seen a new video from Peter for a long time now.
On X86 box this crashes 486DX chips. Not sure if it would in real life but I could test it out on my 486 since its only supposed to affect pentium class systems.
I remember not believing this was a real thing and sshd into a production server and ran the instruction. The connection dropped and I had to get on a bus to go reboot that machine. Lesson learned.
Haha, I am sorry! That made me laugh! I can imagine how this must have felt!
F00F around and find out 😂
🤦🏻♂️
😂
wait........a production machine! Why? You do this on a test machine just in case it's legit. "this program might fry your computer and delete all your data". "yes! lets try it right now on the most important machine I have!" lol With that said I was mad that my parents insisted I had to turn off my computer on 11/31/99 around 10pm or so. They bought into the whole "your computer will explode after y2k" bs. ok sure, but wouldn't it still explode even after keeping it off over night?
So how this works:
0F C7 is the prefix for "exchange two things". The next two bits say what to swap - three variants of a memory location, or two registers. So if you want to swap EAX with ECX, you encode that as either C8 (swap ecx and eax) or C1 (swap eax and ecx - which has the same meaning).
If you want an instruction to keep the memory bus locked while it runs, you prefix it with F0. That should work like "lock memory bus, run whole operation, unlock memory bus". However, for the 0F C7 instruction, Intel implemented it as "lock memory bus, run operation, unlock memory bus if we accessed memory".... so it never unlocks the memory bus if you ever run a locked exchange between registers, and the instruction fetcher is unable to ever fetch any more instruction. No compiler will ever swap two registers with a memory bus lock, because it's not a meaningful or useful operation, but you can encode it, and it was very much untested & broken.
And unlike many other bugs from the time, this is not fixable with any kind of OS workaround. The instruction has no enable bits you could leave off. I don't know if there is microcode in the CPU that could update around this, but that might be the only thing you could do - you know, or buy a different CPU.
The wikipedia article documents a workaround which relies on the fact that this instruction is invalid and the processor is blocked from raising an invalid instruction exception. The workaround involves making sure the processor generates a page fault _before_ it can fetch the exception handler, which is enough to make the processor release the bus lock.
Apparently disabling the cache prevents the bug from happening under DOS/Win98 according to R.Collins write up, far from the optimal solution but interesting nonetheless.
NOP operation on x86 is realized in interesing way. Opcode 0x90 known as NOP is actually XCHG EAX, EAX.
Thank you for providing this excellent explanation. I had a Pentium 133mhz (overclocked to 150mhz) in a Gateway 2000 machine that was impacted by this bug. I remember putting the values into an assembly compiler & linker to make the com file (tasm/tlink). I was interested in learning what the processor was attempting to do that resulted in the behavior, and at the time (pre-2000) my CompSci professors couldn't answer that question. Thank you for providing such a thorough explanation to satisfy curiosity and passion for learning.
Re: Microcode. This bug was the main impetus for Intel moving to microcode so they could patch issues with chips after fabrication and end user installation.
I remember the hyperbole in the newspapers when this bug became official. "Hackers can turn your PC in to a bomb!", as headlines and such.
Drama! I should look into software that prevented the Y2K disaster...
@@bitsundbolts yes please
Maybe they mistook F00F for the chemical FOOF.
I've seen a lot of interesting ways to write programs in C, but defining main as an array is a new one.
I was also not aware that you could do something like this to the main function. But it worked. However, trying it on a modern c compiler, you most likely get an error and it won't compile.
@@bitsundbolts yeah that was something I was not aware of either.
@@bitsundboltsyou need to cast it on new comps. A function name is just a pointer to memory, like a label in assembly.
@@bitsundbolts Regular C does not have any sort of data types for symbols. The compiler and linker are just working as intended - the compiler creates a symbol called "main" with the array contents then the linker finds the symbol named "main" and sets it to the entry point.
I would assume in newer machines it wouldn't work because a data array would be allocated without execute permissions.
ONE THING TO NOTE:
All of these solutions would have good use of a RET instruction (0xC3, 00C3 and ALT+195 respectively) at the end as a fifth byte. This prevents the program from running into random memory, and rather gracefully exit in the case your CPU does /not/ have the F00F bug.
Good to know! I think I have seen some examples where this fifth byte was there. I wondered what it was for.
@@bitsundbolts Not having the RET, you would basically just keep executing random data left over from something else as code (DOS and early versions of Windows have no boundary-protection on memory allocations). This can also in many cases lead to a crash, and you potentially get situations where it would not have been possible to differentiate between a crash from the F00F-bug and a crash from executing garbage data.
@@TheMovieCreator This code would crash on my 13900K too most likely, because it is basically running the execution off a cliff. Of course since I run DOS either in an emulator or a VM, it doesn't require a full system reboot.
However, F00F would crash a Windows NT system running NTVDM most likely on a P5, but on a later processor the NTVDM instance would either error out or the frozen instance would be able to be terminated like any other Windows process.
Still, it would be best to add the RET instruction so an unaffected processor would cleanly exit the test program.
It's interesting to note that both the F00F bug and the FDIV bug arose from flawed implementations in the microcode of these CPUs. In the case of the F00F bug it was the edge case that one could encode a locked (atomic) compare-and-exchange instruction with only registers as an operand (which no compiler would do, for obvious reasons). It was a use case of the instruction Intel simply failed to account for.
In the case of the FDIV bug it was something far more hilarious: the designers of the Pentium CPUs simply forgot to include half the lookup table for the floating point instruction in question, which resulted in the higher half of the lookup table containing invalid values.
Both cases can ultimately be said to have arisen because of incomplete QA testing.
Thanks for sharing this information! I didn't know the FDIV bug was 'software' related.
@@bitsundbolts It's microcode-related, if you want to be technical about it!
Neither one of them is microcode. Both of these were most likely hardwired.
@@thewhitefalcon8539 That is actually not true. At least if most of the research that was done into it is to believed. The FDIV bug in particular has been reported multiple times as being the result of "half a lookup table missing in the microcode ROM".
No x86 CPU designed by Intel has ever been truly solely hardwired or solely microcode based. The original Pentiums were no exception. In fact, the more advanced the CPUs became, the more reliant they became on exceedingly more modular design architecture that actually translated x86 instructions into more generic, RISC-like, u-ops, which in turn could be executed by the various units on the die. This process really took off with the Pentium Pro, but had already started with Intels 486es. Starting with the Pentium II, the microcode could even be updated by software running on it.
Ken Shirrif has a nice blog in which he discusses various topics, including various CPU designs and in which he often zooms in on the CPU dies themselves and analyzes them.
I am not entirley sure anymore, but my university prof said something like they made an error when they copied the lookuptable, something/someone messed up and during copy paste not everyrhing was pasted correctly. I think it had something to do wit the size of the floppy disc or whatever.
So I just gained a newfound respect for DOS as I watched OP write raw machine code straight from the console. That is, frankly, beyond cool.
What is really ironic is two things.
1. "FOOF" is one of the most potent and unstable oxidation agents ever created. It can make nearly anything explode on contact simply by providing oxidation (This is an awfully strange coincidence.)
2. The Pentium has a protection system that can be used to block instruction bugs preemptively, but by default it does so after attempt at execution.
What protection system?
I never knew you could run machine code in C just by making the main function a character array of op codes and running it, that is wild!
Functions are just memory addresses, same as everything else.
Yeah, right!? All the compiler looks for is an "entry point" which all compilers agree is called main in the source code. It starts off at main and reads the bytes. I love seeing people really stretch the definition of what it means to be a C program
Not in newer operating systems and CPUs, because the compiler will put data arrays in a non-executable memory segment.
@@thewhitefalcon8539 Not the compiler, the program loader. But you can invoke a system call to change memory permissions on that page.
well that was the most arcane way you could have written a C program with the f00f instruction
I guess... I followed the instructions in a book. Btw, not all compilers will allow to compile those instructions in that order.
I mean it's on Windows 98, so not the most arcane. I haven't compiled C since Sun workstations were the go to, Unix, before any Windows 9x.
Educational though! I've been a casual C hacker for y-e-a-r-s and had no idea you could declare main as a character array and it would be run as raw ASM instructions. I wonder if that's unique to that particular C runtime? Gonna have to try that later ....
@@nickwallette6201should work on most compilers as ‘main’ is used the entry point but its just a label to an address so making a char array is the same as making a pointer, the content of the array are the instructions to execute. I jad never seen it done that way but it should work on most C versions.
@@nickwallette6201 It only works on old operating systems because modern ones would put the "main" byte array into a non-executable memory page as a security measure, so it will just crash, even if it contains valid machine mode.
I remember the f00f bug back in those days. It was a pretty big deal for a short time. I think there may have even been some talk of trying to intercept & block those instructions at the OS level in Windows, OS2 or Linux via a patch but I don't think any of that was ever implemented.
Ultimately, with the release of the Pentium II months before the f00f bug was discovered and the relative popularity of AMD & Cyrix CPUs, all of which weren't affected by the bug, along with the internet still being in its infancy led to the bug being mostly forgotten about within a few months.
I read that the foof bug was addressed through operating system patches. However, I couldn't find any update just yet that would address the issue in Windows 98SE. As far as I know, no compiler would ever create such code, the sequence had to be deliberately created by the programmer like I show In this video. Congratulations btw, you found an unreleased video 😉
I remember seeing "checking for Intel Pentium f00f bug" when booting up Linux. No idea when it was inserted into the kernel, but probably in 2.0.x, 2.2.x or 2.4.x series. I think I was on a K6 by that point so never checked any further.
Had a machine with Pentium MMX as my "e-waste home server" in 2000s, and the bug was patched in Linux 2.4.30-ish already (can't remember which version it was running precisely). Tested it with a friend, and nothing bad happened, which made us "pleasantly disappointed".
Cyrix had its own foof bug :) "Cyrix coma bug"
@@bitsundbolts There was presumablly seen to be no point addressing the issue in windows 9x, because it's trivial for a bad program to take down 9x anyway. The issue only really matters in systems that actually try to provide isolation between programs/users.
Yes, it´s been ages since I saw someone using Alt+Numpad to enter characters. I used it always to make windows, menus, tables, borders, in Basic and Turbo Pascal. The codes that you entered are the decimal values of the hex code (F0=240, 0F=15, etc)
As a curiosity, every notepad in Windows and most text editors in dos have that ability, to enter characters with Alt+Numpad. Yes, even Win10 notepad.
I remember using those in batch files in dos to build "graphical" menu's and later for the @ symbol. Also some azerty keyboards on the market didn't have the \ key.
I didn't even know that worked in DOS.
@@renakunisaki I remember that in the manual for my first computer there was the ASCII table with the keyboard scan codes; that was for the user to be able to input characters from the keyboard if a key is broken. So, yes that was a thing from XT and DOS 3.3. Not sure if this was a DOS or BIOS feature.
As a well versed C programmer, I was impressed by the kludge over-complicated way this book showed how to do this. I'd be curious to know what book this was.
Yeah that made me look at my telly sideways and think "really? well OK, I can see that's valid but I'd never think to do that". I can see it being a way to inline assembly in C if you can't remember the "proper" arcane way of writing ASM in C with your particular compiler 😄
@@ncot_tech that's inline machine code more than inline assembly.
There's nothing to assemble here lol
Also, I doubt you could do this in assembly since this isn't a valid instruction. If I've understood correctly you can't put a register as the operand, which is precisely what is being done instead of a memory location. I would think most assemblers would validate this and throw an error.
The book is called 'Learn C under Windows 95/NT' from Dave Mark
Fun fact: Code Warrior still exists today.
It's the default IDE that NXP provides now
It was created on Classic macOS, as the "cheap" alternative to the MPW workbench requiring a Mac II to develop a Mac application. MPW was the goto IDE, with the MacApp framework, used for Photoshop and Excel initial development, on macOS. And coming with the CodeWarrior IDE there was a framework named PowerPlant, an Object Oriented C framework, but with mixins instead of the inheritance from a unique Object root class. It is very like what is called traits, or protocols in modern frameworks.
@@jean-pierredesoza2340 that I did not know.
I only knew about CodeWarrior since I've been developing for FreeScale/NXP CPUs at work
Easier way to make a test executable file that triggers the bug, and also is basically the smallest possible file that does that: use a hex editor, make a new file with it and type the offending bytes at the beginning of the file (F0, 0F, C7, C8) and then save the file with a .COM extension. That gives you a 4-byte executable file that triggers the bug. (edit) the result is basically exactly the same as your 3rd method, but many people may find it easier to use a hex editor to make the file.
I should have opened the com file from the third method in a hex editor. I added it to the article on my website though.
There is something profoundly comfy in looking at programming done in C on Windows 98. I was too young to experience that... ;w;
My very first computer had a Pentium 75 that was affected by this bug. I remember at least Linux (and possibly others) mentioning it in the dmesg as it booted, and in /proc/cpuinfo output, but I never did try to do this while I still had it. Interesting use of main-as-an-array-of-bytes. Maybe it exists somewhere, but it might be interesting to do it as inline asm. Thanks for the video, and the memories.
So F00F is the x86 verision of a HCF (Halt and catch Fire) instruction
Pretty much, yes.
Coincidentally, foof! Is the sound of a fire igniting.
halt, but not catch fire. The intel 13th and 14th gen core CPUs are the ones that catch fire. lol
Halt without catching fire is just halt, which we already knew about. :-(
no that would be the hlt instruction. this is just a processor bug.
Method 3 is something I have never seen. Awesome programming method, and with the tightest coding size. Possibly you could do some other examples in the future using and explaining this method in greater depth?
You can even write text into the command line with this method. I'll come up with something else and explain more how this works.
I used to do this in Win XP. I'd use edit and write programs in asci characters up until I learned about the assembler in Debug utility program. I still have the notebooks full of conversion charts. It's basically a truncated Intel manual.
That batch file just mimics a sequence of commands in an interactive assembly language session by feeding the strings into the debugger program as if you had typed them interactively.
"A" without parameters starts entering program instructors at the default program start address (xxxx:0100). "DW" stores the following double-word values in memory at the current program counter address (here: 0100), the full stop ends data input and return to command mode, and the final "G" runs it.
It's almost unbeliavable today to see that you can "write" an executable file directly with the keyboard or a text editor. No certificates, no security no checks no nothing. What great times.
C and C++ are still like this today. You can write the code in notepad, Word or IDE like Visual Studio, send it to the compiler and it will work. The user experience is obviously different, but the end result will be the same.
I find it surprising every time I run into an OS that tries to stop me from running an executable without chain of "mother-may-I" permissions. I know that's where we are today, and I know there's a reason why, but I still feel like Yosemite Sam yelling into my monitor, "I BOUGHT YOU. WHEN I SAY RUN, IIIII... MEEEAAAN... RUN!"
@@nickwallette6201 Yeah, this is my computer, I'll run what I want. I hate being told what I can and cannot do with something I own.
@@nickwallette6201 use Linux then, it'll happily let you do whatever stupid things you want with 0 restrictions!
@@tabana_minamoto That's not the same thing. The original comment is talking about the ability of writing binary data for the CPU to execute in a file. This wouldn't work on a modern system because executable files have become a much more complex format, with headers and sections, and some platforms also require a valid digital signature for the code to run.
LOL, the SET BLASTER= variable... oh the days of old
That .bat is basically a little bit hacky way of scripting DEBUG command. You can also start DEBUG and input all these normally with a keyboard.
But a batch file is easy for copy&paste.
The reason it doesn't affect PII or newer is that, with the exception of the failed Netburst (Pentium 4) architecture, they are all based on the P6 (Pentium Pro) microarchitecture. Yes, even the latest and greatest (rotfl) intel CPUs are based on the P6 microarchitecture from 1995. Maybe that's part of their problem...
I tried this on our P90 back in the day and it crashed. I don't think I used that command but I was reasonably fluent in C++ back then. More likely I edited doom.wad to trigger it somehow because I was into modding DOOM (and other games) before it was cool (and before there were modtools).
The cool thing is that CPUs have tons of small bugs, but I literally crashed my Haswell CPU with a virtualization instruction inside the VmWare, to make sure it was the CPU, VmWare crashed both on Windows hosts and on Linux hosts. But on Linux it took 2 minutes for the watchdog to kick in and kill the machine, Windows timeout was only 15sec (I was baffled by that, its usually the other way around, Windows is the one with ridiculous timeouts). It was a contention between core that caused a deadlock.
Cool think it was fixable by upgrading the microcode.
I love how simple this bug was, and it had the potential for so much chaos. Luckily, it was an OS patch and the issue was solved.
Cyrix had its own FOOF like infinite loop bug called "Cyrix coma bug" discovered at the same time.
To collect all debug commands or instruction from the echo output into a variable looks great. Most times i use a new temp file to collect the output and start debug with that file and then i delete the temp file at the end.
hmm. what great name for a band, Foof Fighters.. lol
Haha. Foof Ighters.
lol that batch file doing the "dw 0ff0,c8c7" feels like they were being intentionally obscure.. just do
"db f0,0f,c7,c8"
so it's more obvious...
Or we can use the e command:
-e
f0 0f c7 c8
Your intro of Codewarrier made me feel so old. It's the IDE I first learned on...
The reason to why main as an array does work is that being specified as an entry point on older linkers the byte array gets just dumped under "main" label. When the address of main gets called/jumped to, thanks to von Neumann everything past it is just treated as executable code, so the data is executed as "lock cmpxchg8b eax"
The bug that also affected late-1990s' Pentiums, is what's known as a DoS vulnerability. Sadly, the Raptor Lake flaws are much worse than this!
"Don't worry, we won't be doing a deep dive into machine code or assembly language."
Awww... I would have enjoyed that!
I remember an old instalment of The Bastard Operator From Hell having a hacked version of Doom that would trigger this bug when the player was killed and making the users play deathmatch to be able to save their work.
12:35 I wonder why is the cursor still blinking, if the cpu is locked up trying to fetch the next instruction? how does it execute instructions to blink the cursor? is it done with interrupts?
Others have pointed out that the cursor is rendered by the graphics card (text mode). So, even though the CPU is in a deadlock waiting for the next instruction that will never come, the screen looks like it's waiting for input.
This era had the last vestige of hardware accelerated video cards as they transitioned to just providing big arrays of pixels, and before modern GPUs. The cursor was implemented in hardware, on the video card.
Powerstrip, 3dmark, utm those icons. Feels like I'm back in time
There's a 3 byte way of locking Win9x and DOS, which works on any CPU: 0xFA 0xEB 0xFE. Save it as a COM file and run. It does:
CLI ; lock interrupts
loop: JMP loop ; infinite loop
Yes, a DOS "program" running in Windows 9x will freeze the machine…
Win9x runs DOS programs by quickly switching between real 16-bit mode and protected 32-bit mode. It could be considered a form of assisted multitasking where the DOS part must pass control back to Windows.
The way by which Microsoft implemented the switching to the 16-bit mode is quite hackish in its own right as you're not supposed to be able to get out of protected mode without rebooting.
I did in fact not know about this bug! I only knew about the FDIV one! I'll have to recreate both of them on my P60@66 some time. 😊
Great video, good work.❤
to your batch file: yes, this is little endian encoding but you write 16-bit values, so the 2nd byte give you the two leading digits in your 16-bit value
Muito legal seu vídeo testando o bug do processador Intel 👍🏼👍🏼👍🏼👏🏼👏🏼👏🏼👏🏼
The batch file seemed straightforward enough. It's creating a tempfile named t (no extension), and then writing stuff into the file using I/O redirection (> means open write, >> means open append). So you're creating a file with the contents:
a
dw 0x0ff0,0xc8c7
g
And then running it in a program called debug. More specifically, the file is being used as the standard in. You should be able to replicate the same behavior without the shell script by just entering "debug" and then typing the above file contents out. You should expect to see the computer crash upon entering the "g" line, which seems to run the code.
My guess for the meaning of the code is that "a" stands for append and "dw" for dword. The empty line is to stop writing stuff to memory and go back to the default command line mode of the debug program. So you're entering a line "dw 0x0ff0,0xc8c7" into memory and then executing it with g, where it gets, I'm guessing, assembled into a program and executed in-memory and because of the lack of entry point in the code and lack of memory protection against executing readwrite memory in user mode, what is supposed to be a dword variable ends up getting read by the program counter and executed as machine code, crashing the PC.
Any DOS programmers in chat to tell me if that's accurate?
Just F00 in data can stop many programs. Example: ODBC and SQL can fail when see F00 in a CSV input file unless the field is quoted so treat that field as text.
That was a fun little video. 👍
Your videos are great :)
Thank you!
Only ever heard of the FDIV bug - and that was through another YT video.
Not sure how many people would be interested, but I would actually watch a video probing retro CPU for bugs - or straight up compatibility issues. Considering how many companies were making CPU in the 90's - even until the end.
I am sure that other CPU designs also suffer from bugs, but due to lower volume, those bugs may not or never surface.
Try running sandsifter on it
I heard this foof bug earlier when my bro brings his first computer on 1999.
I wasn’t aware :)
Here we go! Saturday, day to catch up woth Bits und Bolts! Let's freeze my toaster! :D
What that "dos batch" is doing it is open "debug" program and "type" into it few lines "a" "dw 0ff0,c8c7" then "g" command for "GO" to run it. Thats kinda odd way of doing things would be more clear to just run "debug" command and type those commands into it manually to show what actually happens
Fun fact: this is how the original Xbox was modded. It can be used for arbitrary execution, but this originally wasn't a problem bc the Xbox switched from what was going to be either AMD's Athlon or Phenom CPUs to an Intel CPU that's a cross between the Pentium and Celeron. The AMD CPU didn't have this bug, the Intel one did.
I mean, this is the same company who thought that making slots for their processors, then designing their processors as boards for said slots, was a good idea.
Both editions of Windows 98 have a mitigation against this, which can be enabled via the Advanced button in msconfig. "Enable Pentium F0 (Lock CmpXchg) workaround". The help text for it is "Protects Intel Pentium and Intel Pentium MMX microprocessors against the malicious use of an instruction sequence that may interfere with the microprocessor's operation. This check box should be cleared when debugging programs."
Oh nice! I wasn't aware of this detail. I wondered why Windows 98SE was still crashing. Now I know why. I'll check msconfig for this setting. Thanks 👍
I do not remember the f00f bug. I do remember FDIV, but I had an AMD K5 back then, so... 🤷♂
Yes, the FDIV bug is more known. I just recently stumbled across this thing. Essentially, it is an illegal instruction and no compiler would trigger it - you have to specifically code the instruction for it to fail. The bug is that the processor should raise an exception and not dead-lock.
Welp, that's new to me. Neat!
And super easy to test :)
I remember there was a way to use icmp echo requests to cause a hang up a dialup modem and tell it to dial another number such as 911. It would be interesting to see if there was some way to make windows execute this instruction somehow remotely through the smb or iis.
Uh, sounds like a lot of research and trial and error.
considering how broken SMB was found to be yeah i bet you could make a smb overflow FOOF packet
I can tell you how this works:
Hayes created a smart modem that uses the character sequence +++ followed by a delay as an escape sequence to switch between data and control mode, they patented it.
Other manufacturers didn't want to pay royalties so they came up with using the character sequence +++ with no delay.
The problem ocours when one of these modems tries to send data containing the sequence +++ which puts it into control mode. If you can find a way to make the victims modem send the character sequence +++ followed by a command, it will carry out the command. If you ping someone with a vulnerable modem with the character string +++ATH0DT911 it will make their modem hang up and then dial 911!
@BitsUndBolts
I think I heard about this BITD, but never saw a proof of concept until now. Very interesting! Thanks for showing this!
Thanks for watching! Glad to hear that you found it interesting!
how does the cursor still blink in dos?
Maybe cursor blinking is hardware accelerated and doesn't need the CPU
It doesn't rely on the CPU. This is a feature of text mode graphics from the video adapter.
The video circuitry is what makes the cursor blink ("hardware cursor"). It's independent of the CPU working.
As the others said.
You can also make the cursor not blink, make it larger or even disappear, if you use the 'prompt' command to output the correct ANSI escape sequences when you modify your command prompt. You can also set custom colours or inverse text as part of the command prompt using ANSI escape sequences.
@@LarsV62 The graphics card has hardware registers. Using ANSI codes relies on having a driver loaded which interprets the ANSI codes and converts them to register settings.
12:38 this seems like something I would pull on my friends if I was born 20 years earlier.
You have to stress the cpu w dosbox at very high cycles, you have to choose. When you start heretic, it will add a fpu driver that will reside in your cpu. After done, you have to do the same with duke3d, and just watch the intro. By oing it more times, duke can run good with higher cycles. You'll also get an audio acceleration, very good for youtube when using energy saving, netbook, tablet, etc. The fpu is off by default, you can just measure benchmark its performance, but can't benefit from it.
When the fpu is on, you get an Intel autopilot, that's good for driving and shooter games, some games will become harder and mre challenging. Example is Dyna Blaster, the game will be logically harder, the opponents will be placed to harder positions. The Stunts will be corrected by the autopilot, to ensure you won't crash your car.
Codewarrior, that takes me back to school days.
Welp...could MS-DOS or any windows games trigger this bug?
Are there updates to intel cpus of this period to fix this? 🤷♂️
Never happened to me ...I had a 166 mmx through late 90s
Mama said life is like a bunch of F00F.
I wonder if you could maliciously edit the first 6-8 bytes of the MBR using this principle to render a machine inoperable when loading from disk
Fun fact: A boot sector with corrupted data, (not zeroed) regularly causes the dreaded blinking-cursor-on-top-left syndrome. That's how I know a drive wasn't wiped correctly.
@@RJARRRPCGP as far as I remember as long as it starts with the _magic bytes _ AA55 it will read the remaining 510 bytes as instructions, so my thinking was, what if you do AA55F00FC7C840
@@RJARRRPCGP IIRC you only need the two magic bytes for the PC to start reading instructions from the boot sector; i.e. AA55
So what if you wrote AA55F00FC7C8C3 at the beginning of the boot sector?
It'd be more inconspicuous if for some reason the first few bytes were zeroed out to begin with, or maybe the boot code doesn't need the full 510 remaining bytes and you could slide/compress the useful data and inject those nasty instructions
yeah but you could also just write an infinite loop there instead. The AA55 marker goes at the end of the sector.
How does the c version even work? Is the cpu trying to execute the array of chars because it’s called main? Could you hand write any machine code in that char array?
yes and yes
I love assembly language! This is incredible
It's one of those "you FooF" things
Okay, I've been programming for over 40 years... How have i never heard of this?!
I guess the F00F bug isn't as famous as other other microprocessor bugs.
Imagine if instead of a computer crashing the processor released a Highly corosive oxidising agent and set the machine on fire. FOOF
these days intel just manufactures them with the corosion built in.
The last one is interesting because the cursor keep blinking despite the system being absolutely frozen (will be the graphics hardware managing the cursor, but I am used to software rather than hardware cursors)
Yes, that seems to be happening. The cursor is managed by the video card.
And this cannot be fixed by updating the BIOS? It seems to contain micro code
I am not sure if microcode updates were already a thing back then. I read that an i486 had about 5000 lines of microcode. But I'm not sure if this bug could have been fixed by an update.
The bug was discovered quite late and the Pentium II was already released. There was little incentive for Intel to fix this bug.
The Pentium Pro was apparently the first CPU to contain writable microcode, although a workaround was implemented at the Kernel level in Linux version 2.0.32-6 and presumably later Windows versions had one of some kind too.
Yes, P54 and P55 did not support microcode updates.
It would be an operating system update
Heh flashback... Used to know a 4 byte com file for clearing a byte of cmos memory to force it to be reset without having to access the inside of the case :D Although used edit and alt+numpad rather than echo console to file.
Since the fdiv bug i know that the mainboard bios can change the micro code of the CPU. But i never figure it out how to do it with an own program and if it is permanent or temporary. Maybe we can add some new instructions to the CPU or deleting some instruction that we don’t like to use.
I would love to see this bug executed in Windows with Media Player or the good old Winamp running in the background playing music to see if the music keeps playing, going in a loop, or just stops completely.
Ahh, Winamp 😌. I guess I should explore this bug further and see what happens on Pentium Pro systems (it shouldn't freeze - those CPUs should not suffer from this bug) - and also check my Pentium Overdrive (for 486 socket 3).
Presumably it would continue playing, similar to a skipping CD player.
The exact mechanism for playing audio is dependent on the audio hardware and the driver for it, but in general, it involves a ring buffer that is filled with sample data at a regular interval. If the CPU stops working, the buffer just never gets updated with new data, and the audio hardware may continue to play the contents indefinitely. This happened in the old days when you assigned the wrong IRQ to the audio device. The sound card would set to work playing the buffer, and would raise an IRQ to let the driver know it was done playing a chunk -- generally it would do this before it got to the end of the buffer, to give the driver time to refill the first half while it continued playing the second half. However, the driver, having been configured with a different IRQ, would never see the request, and thus would never follow up to refill the buffer. Ergo, you would just get a continuous loop of a short phrase of audio until you reset the computer (or at least the sound card), because it wouldn't know the difference between an unfilled buffer and a buffer filled with exactly the same data that was already there. As far as it's concerned, it let the CPU know, and so its job is just to keep playing whatever's there now.
8:47 I don't understand this either, but why would endianness cause this on the same CPU architecture?
because it's writing 2-byte numbers instead of individual bytes
I may be completely wrong here, please correct me if I am. Cyrix CPUs aren't affected because they're all based off of i486 architecture instead of P5, and AMD went straight from i486-based K5 to K6, closer to the then-unreleased Pentium II than the original.
They cant have the same bugs as Intel ones. They have different bugs.
can you abort the lock with an NMI ?
Sorry, what is an NMI?
No. The CPU itself holds the bus locked that it needs to fetch instructions; sending an NMI is really just a high-priority interrupt, making it jump to a different location, that it then won't be able to fetch from since the CPU itself holds the bus locked.
NMI is "Non-maskable interrupt". The name is slightly wrong since it has its own masking bits... Usually in the IRQ2 slot, as the original PC/AT could never trigger IRQ2 by design.
@@bitsundbolts Non-maskable interrupt
@@dascandy One of the workarounds is to break the interrupt table so the CPU raises a "broken interrupt table" interrupt after trying to raise the "invalid instruction" interrupt. Messing with the interrupt delivery sequence in any way seems to avoid the faulty state. It's plausible that raising an NMI could also break the CPU out of the faulty state. But if IRQ doesn't, and IRQ is not masked during this state, then NMI probably doesn't either.
Oh, I didn't realise FDIV and F00F were different things!!!
Yes, they totally are. Unfortunately, I don't have a CPU with the FDIV bug
Cyrix 6X68 had one as well, the Cyrix coma bug
Oh, yes - I came across this during my research as well. Maybe that would be another one that's worth making a video about.
What’s so complicated? I rly wanna know… I still have my copy of Borland C++ Builder 5 somewhere. Installing it, writing C program into editor and press the green arrow button on the top should be enough.
I did not code in C. I did have Borland Delphi 4 back then.
It was difficult for me to find a compiler that allowed this one-liner. I tried it online with several tools, but it always failed to compile. Code warrior was the first Compiler I tried - and it worked. It was just the first thing that worked. Of course, there are better ways to get this done, I'm sure of that.
No hang on my AMD K6-233ANR, num lock works :)
YTP enjoyers: YOU FOOF!
I do wonder why the cursor keeps blinking if the CPU is frozen
Maybe some portion of the CPU is still executing. Interesting observation!
In this case, the cursor is blinked by the display hardware.
This is what was called a "hardware cursor"; the GPU does this. CPU is not involved.
Video card does the blinking
@@dascandy GPU did not even exist back then. They where just 2D cards with some basic functionality to take away from instructions from CPU.
Need to try it on a dual socket 5/7 system with a SMP aware OS and see what happens.
You need to find a way to reset one CPU from the other
Nice!
From intel 80386 i switched to AMD k5, k6, Tbred, but at last to intel core2quad CPU. I never used an intel Pentium CPU. Now i am back to 80386 using a DosBox emularor on an android tablet. The emulation works great. And now i am waiting for a mobile "quantum" CPU and another DosBox emulator for the quantum CPU android OS.😂
At @12:35 why cursor still blinking if system froze?
The CPU is waiting for something that never comes. So, in that sense, it's not a system hang or crash but just unresponsive to any user input.
@@ezruy No, the CPU is not waiting like for an int, it can't load the next instruction so is completely halted and only a reset signal can unlock it. The blinking cursor is done by the VGA hardware.
It's generated by a timer in the GPU
5:30 this is still defining the main function, but now as opcodes
F00F, such a silly and whimsical creature.
intel just really likes to insert bugs into their processors 😂 all jokes aside, thanks for a great video, learned something new)
Thanks for watching!
I'm not a programmer at all but i just enjoy computer glitches heh. I understood like, 25% of this
Yeah, it was bit technical. But hey, the system froze three times :)
I wouldn't expect an undocumented instruction to be reliable. It may do something. It may trigger an error. The point is, I wouldn't expect the results to be consistent across multiple implementations either.
True, however, the instruction is invalid and should raise an exception from the CPU, but it doesn't. It's interesting that this combination of instructions was found that locks up the CPU.
@@bitsundbolts The 6502 for example doesn't raise an exception. It just does whatever. lol
Exactly. Undefined instructions have, by definition, undefined behavior. Sometimes those instructions get assigned later in the architecture's life. Sometimes they do useful things. The 6502 mentioned above is known for having some useful undefined instructions that appear to combine functions of other, valid, instructions. The NES, for example, had some games that took advantage of undefined instructions. Emulator authors had to find this out the hard way, as they would've first built the emulator to support all the known valid instructions, and then would've run into ROMs that asked it to do something entirely different and unexpected -- which, of course, would've broken the game until the emulator was "fixed" to respond in the same way the hardware did.
@@nickwallette6201 yeah. It's kind of cool if you can find it useful, but it's also very dangerous. You never know if there will be an NES 2 that "fixes" the 6502 and now they are just NOPs or they create some kind of NMI or something.
I wonder if this is emulated in 86Box.
Someone should try this and let everyone know. Somehow, I would be surprised if the emulated CPU follows the same behavior, but still interesting to know!
For the third method i have no number keys and no altgr key with a virtual keyboard app on a touch screen using DosBox emulator on an android tablet. Alt key + numbers is not working for output a character.
Hm, ok. Yes, you need to have those keys and the numbers must be entered using the NumPad. You could download the compiled file from my website and copy it to your emulator. But I don't know if that's possible.
@@bitsundbolts Thanks, but i don’t need it and i know how to use debug very well. I use a special version of debug that works and looks like the debug version from MS and it provide 16 bit and additional 32 bit instructions. I download it from the other alternative DOS. I put the link into the pinned comment of my videos. Thank you.
whats funny is, this doesnt lock up the computer at the last part, the blinkers still blinking.
In DOS, the blinker is generated by a dedicated circuit on the video card.
It’s so FOOFy!
Have you tried this in Linux or Unix?
No, I haven't. It should work on unpatched versions since the F00F bug is hardware related. I believe there were patches for almost all operating systems to prevent this series of instructions from executing.
I wonder if there have been any computer viruses exploiting this bug
That was the common concern. Malware could exploit this bug and freeze systems easily.
Pentium MMX Tillamook CPUs with the myB2 stepping are the only P5 CPUs, which have a fix for this bug.
Oh, really? I thought all P5 CPUs were affected. I don't have access to a Tillamook. CPU Galaxy should check that, but I haven't seen a new video from Peter for a long time now.
On X86 box this crashes 486DX chips. Not sure if it would in real life but I could test it out on my 486 since its only supposed to affect pentium class systems.
Oh, really? Interesting! That shouldn't happen. First, it's an emulator, second, you're using a 486 which doesn't have the bug.