Making ReactOS Great Again*, Part 1
Prologue If you don't want to read all this bullshit - skip and go to ROCALL chapter.
First time I encountered ReactOS in 2004 year when I was looking for declaration and definitions to the Windows Native API missing in Nebbett book. For that time it was probably one of the best sources for this kind of queries. In 2006 on a first hype train about this "Windows replacement" OS I tried it. Without any success. It wasn't ready for anything even for virtual machine installation. Approximately at the same time access to actual Windows code was acquired and ReactOS have lost any value for me. However I still encountered it pieces of source on various forums etc which actually was total frustration and failure because ReactOS developers in attempt to hide their copy-paste parts turned code into ridicuolus mess of trash. Microsoft code wasn't that extremelly good and they managed to make it even worse. Ok, but there is no Windows code in ReactOS. Remember this. Not a single byte. Sure.
Next encounter was almost ten years after in 2015 year. ReactOS was still alive and still in alpha where "it can but not today". This time it was evaluation of projects on import substitution infrastructure software, https://digital.gov.ru/ru/documents/4662/.
Since this was obviously low quality product at that time (and currently too - nothing changed) if they win it mean waste of Russian government budget funds. Or probably this was a main goal, because entire idea and competitors were merely a joke ;) Fortunately they didn't manage to go through.
Since it was considered as "alternative" on government level, that probably mean this product is ready for something, then I tried it again. Well, it was complete failure. Impossible to work and completely out-dated, uni-processor x86-32 configuration, bugged as hell failed Windows clone running on FAT32 (with broken/incomplete fs driver), clone which barely can support few devices in popular virtual machines. In 2015 year.
It is end of 2018 now and ReactOS is barely "stable" to install in virtual machine, start and do nothing. When you start doing something - it will crash and highly likely reinstall will be the only option after.
What is ReactOS today? Windows replacement - no and never will be. Students learning project? Maybe, but better not to learn anything from it as ReactOS is a perfect example of deep failure in design, positioning and implementation. If you want to learn something - use original Windows source as case of study.
So why this project still need some attention and support? Just a few small reasons why it still need to exist.
1) Wine as they share part of code base, including patches;
2) Good laugh when sometimes you are trying to use this OS;
3) Variability and opportunity to experiment with Windows like code for beginners and noobs;
4) It is free and doesn't demand anything in exchange of it existence.
There was also number 5 - opportunity to get your code signed with ReactOS code signing certificate. Some open-source projects used this opportunity in the past including some project which was initialy planned as malware. But since Windows 10 release this number 5 is gone at forever (https://reactos.org/wiki/Driver_Signing).
Looking on how it works and how it looks (https://github.com/reactos/reactos/) these guys obviously need some help. I mean some real help, not aggressive bullshit advertising attempts by some self-proclaimed evangelists. Instead of help and turning people to the project guys like this one is making a phun from project and turning people against because of total "evangelist" ignorance. However we are not going to do all the job for them. Our goal is give them a direction to move on and finally make their project a little bit more stable.
ROCALL
While looking ReactOS versions from 2006 till now I always noticed out-of-sudden Blue Screen Of Death from anywhere anytime. When I was briefly looking on fresh 0.4.10 "release" I got a BSOD from program I tried to launch on ReactOS. Nothing new, but this time I knew what caused this. Quick looking on ReactOS source confirmed the worse possible scenario.
Software pretending to be "Windows" compatible lacks of basic sanity/security checks implemented in it kernel mode services implementation - functions inside ntoskrnl and win32k syscall tables.
In my case it was NtDeleteValueKey routine, which was missing validation of input parameter. Basically it was derefencing user mode pointer without any error checking. Open-source environment I can trust, remember? Well I can, Windows programs cannot.
In Windows NT world this popular service available at least from Windows NT 3.51 (1995) and ReactOS (1998) for 20 years either doesn't bothered to do it correct implementation or it was messed up while "refactoring" / "audit".
To figure out the problem root I found and downloaded ReactOS code from 2007 year. Apparently it was broken even there (aside with multiple other things around). Well that is not what can surprise here.
Next I got 0.4.12 ReactOS build and to my surprise this issue was addressed. That mean ReactOS developers do not consider their system bugs as "features" as Microsoft often does with it crapware.
But what this bug mean. A very simple thing. They do not test or do not know how to test. Looking on various ReactOS tracker resolved/closed opened issues it seems that stability improvements can be fully described in a just few words:
"hey lets start this shit on reactos, omg it crash/BSOD, ummm lets take a look why, oh we miss some validation here, now fixed! wait, it is still not working?!".
For an average open source project this maybe somewhat ok, for operation system pretending on something - no.
I decided to provide some little help in this area. A simple syscall fuzzer, what every OS must have (do not worry MS also don't know how to use similar tests or some devs from MS suffers from amnesia each Windows 10 "FailWeRollbackUpdate"). Since ReactOS is a very simplified this program was a really easy to write. This is my first program specially designed to run on ReactOS. I swear I didn't copy-pasted anything from ReactOS just like it never copy-pasted anything from Windows.
This program is open-source and link to it you can find in the end of this post. It is bind to ReactOS and do nothing on Windows.
Important note: this will be very superficial fuzzing but it is enough to find a lot of bugs in case if software is weak.
As base for our experiments with ReactOS we need virtual machine, in my case it is VirtualBox running on Linux host since I do not use Windows except in VM.
Virtual machine settings:
CPU 1
RAM 512
Chipset PIIX3
Audio Controller Disabled
COM1 Enabled, Port Mode RawFile (path to existing log file on your physical machine, will be overwritten each ReactOS test relaunch)
Ethernet Adapter PCnet-PCI II (Am79C970A), the only one I got to work with ReactOS, yeah 2018 year that's how we support hardware, even virtual
Everything else default.
Additionally you can log directly to Linux terminal, set Port Mode to TCP and use "screen" utility. Just like on my screenshot above.
We need to do syscall fuzzing and save every syscall name, it parameters and make sure things are saved. What usually happened with ReactOS after BSOD? Unbootable device and reinstall in most cases because of their FAT32. Even more, both 0.4.10 and 0.4.12 install and start with FAT32 volume that already has dirty bit set and various structure errors, facepalm. For note, ReactOS now support BTRFS as main filesystem so you can try it, it must be much more stable because it wasn't made by ReactOS devs.
This is why we use COM1 for logging as we can't rely on bugged fastfat ReactOS driver which corrupts volume as it wants.
Since ROCALL won't be really different to either our NTCALL64 or original Gloomy NTCALL from 1999 (it will even somewhat simpler), so we can skip it implementation details and just in short - it brute-force system services by calling them multiple times with parameters taken randomly from predefined "bad" arguments. Arguments here are not just random junk, they set up that way so we can catch not only bad pointers but also overflows. ROCALL also support system service filtering by blacklist like NTCALL64/NTCALL. Timeout for each service will be set to 30 sec.
Take a note that some system services may crash fuzzer or prevent it from displaying results, so we need to ban them.
Our default blacklist looks like this:
Spoiler: 0.4.10 from current "Release" also will be tested for cross-reference.
Copy ROCALL.exe somewhere on ReactOS volume, for example in C:\Tests, place blacklist.ini in the same directory.
ROCALL supports the following parameters:
Save VM state to snapshot.
Open command line in the ROCALL directory and execute it.
Try 1.
I use:
ROCALL -logn
Almost instantly the our first BSOD appears.
BSOD on: NtAllocateUuids
Source: https://github.com/reactos/reactos/blob ... uid.c#L314
Service marked as "unimplemented" however it does some things and do not return STATUS_NOT_IMPLEMENTED.
It completely miss any parameters validation and just a BSOD-generator.
Rolling back VM snapshot, updating blacklist with this "unimplemented" implemented BSOD-generator.
Try 2.
BSOD on NtDisplayString
Source: https://github.com/reactos/reactos/blob ... nbv.c#L772
Indeed, what could go possible wrong here. Note service not marked as "unimplemented". Implemented and working as expected? BSODing as expected?
Wtf this mean in ReactOS world is unknown. As for me it is not implemented even for alpha state.
Rolling back and updating blacklist.
Try 3.
BSOD on NtRaiseException
Source: https://github.com/reactos/reactos/blob ... ept.c#L172
Calling this function with invalid parameters result in blue screen because of intentionally set debug breakpoint.
How about log exception, check build type and only then break to the debugger? Nah why bother, suffer bitch.
Rollback etc.
Try 4.
BSOD on NtUnloadDriver
Source:https://github.com/reactos/reactos/blob ... er.c#L2107
Finally something marked as "implemented"! Oh well, better not.
It calls IopUnloadDriver with unchecked pointer and then IopUnloadDriver does wcsrchr with it. Nice. I feel strong Windows competitor here.
And I noticed cute todo here
Try 5.
BSOD on NtSetUuidSeed
Source: https://github.com/reactos/reactos/blob ... uid.c#L378
Implemented! Whatever this mean.
0.4.10 additions
The following routines will blue screen on 0.4.10 if called with invalid parameters due to insufficient parameters validations or validations complete absence.
NtLoadKey
NtLoadKey2
NtLoadKeyEx
NtDeleteValueKey
NtQueryValueKey
This is somewhat fixed in 0.4.12
Rollback and go next.
When this fuzzing finished with no more BSOD's but then I got suddenly this:
Entire video mode collapsed and I got resolution like 100x100 4 bit. Must be an easter egg from developers.
2. TEST, Win32k User/Gdi Service Table
Where the most fun begin. In Windows world the win32k component is a exploit factory and effective built-in OS BSOD-generator.
As expected here is the same level of quality.
Save VM state to snapshot.
Open command line in the ROCALL directory and execute it.
I use:
ROCALL -win32k -logn
Try 1.
BSOD on NtGdiClearBrushAttributes
Source: https://github.com/reactos/reactos/blob ... h.cpp#L553
Unimplemented syscall stub breaking into debugger. In 0.4.10 "release" too. Best design practices everywhere. Keep doing the same way.
As you can see from source link NtGdiSetBrushAttributes does the same.
How about set last error "not implemented" and don't suddenly break into debugger if there is no one.
Rollback, update blacklist section "[win32k]" with failing service name.
Try 2.
Stop on NtGdiCreateDIBBrush
Source: https://github.com/reactos/reactos/blob ... h.cpp#L412
Insufficient parameters validation.
Rollback, update blacklist.
Try 3.
BSOD on NtGdiCreateDIBitmapInternal
Source: https://github.com/reactos/reactos/blob ... bj.c#L1457
BSOD located in GreCreateDIBitmapInternal.
What is wrong here. Need more detailed explanation because this service bug is a common for ReactOS, maybe because all the bugged code written by one author.
This routine has the following declarations (key fields in bold)
cjMaxInitInfo = 0x0000000
pbmi = 0x00000001
so it passes "if (pbmi)" and enters ProbeForRead(0x00000001, 0x00000000, 1);
Now look on ReactOS ProbeForRead
https://github.com/reactos/reactos/blob ... rin.c#L102
Next invalid pointer dereferenced. Blue Screen.
Rollback, update blacklist.
Try 4.
BSOD on NtGdiDdCreateSurface
This routine passes all it parameters to Dxg.sys->intDdCreateSurfaceOrBuffer.
Source: https://github.com/reactos/reactos/blob ... /d3d.c#L43
Nor Win32k nor Dxg.sys are not validating input parameters. The whole Dxg.sys completely trust everything from Win32k. Best design practicies in work. Learn from this. Copy this.
Rollback etc
Try 5.
BSOD on NtGdiDdCreateD3DBuffer
Same as above.
Call Chain NtGdiDdCreateD3DBuffer -> DxDdCreateD3DBuffer -> intDdCreateSurfaceOrBuffer
Try 6 and 7.
BSOD on NtGdiDdLock
BSOD on NtGdiDdUnlock
See DxDdLock
See DxDdUnLock
Same as above, win32k/dxg not validating anything.
Try 8.
BSOD on NtGdiExtCreateRegion
Source: https://github.com/reactos/reactos/blob ... on.c#L3802
Insufficient parameters validation, case similar to NtGdiCreateDIBitmapInternal BSOD.
Try 9, 10, 11
Stop on NtGdiGetCharABCWidthsW
Stop on NtGdiGetCharWidthW
Stop on NtGdiGetFontResourceInfoInternalW
Source: https://github.com/reactos/reactos/blob ... pe.c#L6443
Source: https://github.com/reactos/reactos/blob ... pe.c#L6647
Source: https://github.com/reactos/reactos/blob ... ont.c#L952
Insufficient parameters validation. System hang.
Try 12.
BSOD on NtGdiPolyPolyDraw
Source: https://github.com/reactos/reactos/blob ... hap.c#L376
Insufficient parameters validation, overflow. Similar to NtGdiCreateDIBitmapInternal
Try 13.
Stop on NtGdiSetDIBitsToDeviceInternal
Source: https://github.com/reactos/reactos/blob ... obj.c#L455
Insufficient parameters validation. System hang.
Try 14.
BSOD on NtUserBuildHwndList
Source: https://github.com/reactos/reactos/blob ... ow.c#L1338
Insufficient parameters validation.
Try 15.
BSOD on NtUserConvertMemHandle
Source: https://github.com/reactos/reactos/blob ... rd.c#L1159
Insufficient parameters validation.
Try 16.
BSOD on NtUserCreateAcceleratorTable
Source: https://github.com/reactos/reactos/blob ... tor.c#L229
Insufficient parameters validation, incorrect comparisons.
Try 17 & 18.
Stop on NtUserCreateWindowEx
Stop on NtUserEnumDisplayMonitors
Source: https://github.com/reactos/reactos/blob ... ow.c#L2466
Source: https://github.com/reactos/reactos/blob ... tor.c#L543
Insufficient parameters validation. System hang.
Try 19.
BSOD on NtUserGetAsyncKeyState
Source: https://github.com/reactos/reactos/blob ... ard.c#L632
Insufficient parameters validation, integer overflow.
Try 20.
BSOD on NtUserGetCursorInfo
Source: https://github.com/reactos/reactos/blob ... con.c#L645
Incomplete parameter validation. Input parameter not checked before read access but checked before write access, rofl.
Try 21.
BSOD on NtUserGetDCEx
Source: https://github.com/reactos/reactos/blob ... ndc.c#L973
Insufficient parameters validation.
Try 22.
BSOD on NtUserGetKeyboardLayoutList
Source: https://github.com/reactos/reactos/blob ... out.c#L496
Insufficient parameters validation, overflow.
Try 23.
BSOD on NtUserSBGetParms
Source: https://github.com/reactos/reactos/blob ... ar.c#L1218
Input parameters not validated.
Try 24.
Stop on NtGdiEngUnlockSurface
Source: https://github.com/reactos/reactos/blob ... ace.c#L615
Best design practices. RtlAssert wait for debug input.
There are few more but I tired copy-pasting from logs.
Note another fun bug from ReactOS ntoskrnl. When fuzzing win32k with logging call parameters I experienced multiple BSOD's from ntoskrnl KeBugCheck(CRITICAL_PROCESS_DIED). The last one thing I want to do is debug ReactOS, so it is up to developers figure out what is wrong here. For ROCALL this behavior resulted in adding "-sc" switch to start from given service index and not from beginning.
3. TEST complete
When our fuzzer with help of blacklist finished working, ReactOS was alive, but barely unusable, just like if it was at death's door. Impossible to do anything, the reset (and reinstall for sure on fat32) was the only option. Reset confirmed quality of ReactOS FS driver with unbootable state and this fun message
Even if ReactOS syscalls passed this superficial test - it doesn't mean they are not bugged as hell. More deep and smart fuzzing will for sure find more bugs ;)
For example
BSOD on NtQuerySecurityObject
Source: https://github.com/reactos/reactos/blob ... ure.c#L803
This service is a BSOD generator in case of simple race condition.
RC attack of this type is something I used 12 years ago against some Chinese antirootkits and some crapware mainstream antiviruses. For more recent info's you may refer to j00ru series of blogposts where he multiple times crashed Windows using the same principle. Idea is simple, two threads access same memory simultaneously, first thread does read/write while second thread running in loop making changes to memory region protection.
4. Win32k, CSRSS
There is also small amount of Win32k services that are unaccessible for programs except CSRSS.
You can find them by this code (or similar)
Conclusions.
Overall, my impressions after looking on how ReactOS works and how it implemented can be described by this picture. Quite obvious.
Not each syscall is properly covered by tests. Besides obvious BSOD's there is a hell and mess in ReactOS source code. Dropped, incomplete code, useless junk, copy-pasting Microsoft style of early 90x-00x (wow wtf who told you it is good?). No usage of static analyzers or their results ignoring. Some of the above bugs can be detected by simple static code analyzer at compilation.
What I can suggest to ReactOS developers. Concentrate exceptionally on fixing bugs and refactoring code, especially this one dropped by authors 10-12 years ago. Reconsider your great idea "lets break to the debugger" from syscalls that's are not implemented. It is very cool to watch your system completely not responsive at any time. I may somehow understand why you did this, but such trash should not present in "release". Even if you "alpha". You alpha for 20 years and nothing changes. This is not a excuse anymore. ReactOS is out-dated code base trash that screams about attention to it bugs.
Q: Does ReactOS can replace Windows (in perspective) on desktops?
A: No it can't. There is giant gap between this project and actual Windows 10 or Windows 7. When ReactOS will come closer to Windows 7 (2030-2040? I'm joking - never) MS product will be completely outdated and unused by major audience.
Q: Why this isn't reported directly to ReactOS devs?
A: Because I don't value this project as worth for any kind of official reports. Twenty years of unworkable alpha. Pff. This is my report. Part 1. You either fix your ridiculous bugs or GTFO. This is how I work.
This is first part end. I do believe that while some people tried to use this project for their own selfish goals (like these clowns from prologue part) most part of ReactOS dev involved actually loved what they do and put their best effort in this project. As for now ReactOS need some love from experienced and professional developers so if you can and want - why not to waste some of your time. There is big surface for various tests and fixes to make this OS at least somewhat stable (I'm not even talking here about "usable").
The only possible good scenario for ReactOS future is to become a VM bind-only OS.
Collection of ReactOS Blue Screens
Some of the above BSOD's, I was doing screenshots until got finally bored.
ROCALL project
https://github.com/hfiref0x/ROCALL
*well it actually never was and highly likely never will be
Imagine running your favorite Windows applications and drivers in an open-source environment you can trust. That's ReactOS.
There is no Windows code in ReactOS. There never was. There was never such an accusation in the first place.(c) ReactOS frontpage and reactos.org/wiki/Audit.
Prologue If you don't want to read all this bullshit - skip and go to ROCALL chapter.
First time I encountered ReactOS in 2004 year when I was looking for declaration and definitions to the Windows Native API missing in Nebbett book. For that time it was probably one of the best sources for this kind of queries. In 2006 on a first hype train about this "Windows replacement" OS I tried it. Without any success. It wasn't ready for anything even for virtual machine installation. Approximately at the same time access to actual Windows code was acquired and ReactOS have lost any value for me. However I still encountered it pieces of source on various forums etc which actually was total frustration and failure because ReactOS developers in attempt to hide their copy-paste parts turned code into ridicuolus mess of trash. Microsoft code wasn't that extremelly good and they managed to make it even worse. Ok, but there is no Windows code in ReactOS. Remember this. Not a single byte. Sure.
Next encounter was almost ten years after in 2015 year. ReactOS was still alive and still in alpha where "it can but not today". This time it was evaluation of projects on import substitution infrastructure software, https://digital.gov.ru/ru/documents/4662/.
“Creating an open source operating system based on ReactOS for PCs, laptops and other mobile devices”, “Creating an open source operating system based on ReactOS for servers”.So ReactOS was considered as candidate for client OS for replacing MS Windows products. More info here https://www.reactos.org/project-news/re ... om-effort/
Since this was obviously low quality product at that time (and currently too - nothing changed) if they win it mean waste of Russian government budget funds. Or probably this was a main goal, because entire idea and competitors were merely a joke ;) Fortunately they didn't manage to go through.
Since it was considered as "alternative" on government level, that probably mean this product is ready for something, then I tried it again. Well, it was complete failure. Impossible to work and completely out-dated, uni-processor x86-32 configuration, bugged as hell failed Windows clone running on FAT32 (with broken/incomplete fs driver), clone which barely can support few devices in popular virtual machines. In 2015 year.
It is end of 2018 now and ReactOS is barely "stable" to install in virtual machine, start and do nothing. When you start doing something - it will crash and highly likely reinstall will be the only option after.
What is ReactOS today? Windows replacement - no and never will be. Students learning project? Maybe, but better not to learn anything from it as ReactOS is a perfect example of deep failure in design, positioning and implementation. If you want to learn something - use original Windows source as case of study.
So why this project still need some attention and support? Just a few small reasons why it still need to exist.
1) Wine as they share part of code base, including patches;
2) Good laugh when sometimes you are trying to use this OS;
3) Variability and opportunity to experiment with Windows like code for beginners and noobs;
4) It is free and doesn't demand anything in exchange of it existence.
There was also number 5 - opportunity to get your code signed with ReactOS code signing certificate. Some open-source projects used this opportunity in the past including some project which was initialy planned as malware. But since Windows 10 release this number 5 is gone at forever (https://reactos.org/wiki/Driver_Signing).
Looking on how it works and how it looks (https://github.com/reactos/reactos/) these guys obviously need some help. I mean some real help, not aggressive bullshit advertising attempts by some self-proclaimed evangelists. Instead of help and turning people to the project guys like this one is making a phun from project and turning people against because of total "evangelist" ignorance. However we are not going to do all the job for them. Our goal is give them a direction to move on and finally make their project a little bit more stable.
ROCALL
While looking ReactOS versions from 2006 till now I always noticed out-of-sudden Blue Screen Of Death from anywhere anytime. When I was briefly looking on fresh 0.4.10 "release" I got a BSOD from program I tried to launch on ReactOS. Nothing new, but this time I knew what caused this. Quick looking on ReactOS source confirmed the worse possible scenario.
Software pretending to be "Windows" compatible lacks of basic sanity/security checks implemented in it kernel mode services implementation - functions inside ntoskrnl and win32k syscall tables.
In my case it was NtDeleteValueKey routine, which was missing validation of input parameter. Basically it was derefencing user mode pointer without any error checking. Open-source environment I can trust, remember? Well I can, Windows programs cannot.
In Windows NT world this popular service available at least from Windows NT 3.51 (1995) and ReactOS (1998) for 20 years either doesn't bothered to do it correct implementation or it was messed up while "refactoring" / "audit".
To figure out the problem root I found and downloaded ReactOS code from 2007 year. Apparently it was broken even there (aside with multiple other things around). Well that is not what can surprise here.
Next I got 0.4.12 ReactOS build and to my surprise this issue was addressed. That mean ReactOS developers do not consider their system bugs as "features" as Microsoft often does with it crapware.
But what this bug mean. A very simple thing. They do not test or do not know how to test. Looking on various ReactOS tracker resolved/closed opened issues it seems that stability improvements can be fully described in a just few words:
"hey lets start this shit on reactos, omg it crash/BSOD, ummm lets take a look why, oh we miss some validation here, now fixed! wait, it is still not working?!".
For an average open source project this maybe somewhat ok, for operation system pretending on something - no.
I decided to provide some little help in this area. A simple syscall fuzzer, what every OS must have (do not worry MS also don't know how to use similar tests or some devs from MS suffers from amnesia each Windows 10 "FailWeRollbackUpdate"). Since ReactOS is a very simplified this program was a really easy to write. This is my first program specially designed to run on ReactOS. I swear I didn't copy-pasted anything from ReactOS just like it never copy-pasted anything from Windows.
This program is open-source and link to it you can find in the end of this post. It is bind to ReactOS and do nothing on Windows.
Important note: this will be very superficial fuzzing but it is enough to find a lot of bugs in case if software is weak.
As base for our experiments with ReactOS we need virtual machine, in my case it is VirtualBox running on Linux host since I do not use Windows except in VM.
Virtual machine settings:
CPU 1
RAM 512
Chipset PIIX3
Audio Controller Disabled
COM1 Enabled, Port Mode RawFile (path to existing log file on your physical machine, will be overwritten each ReactOS test relaunch)
Ethernet Adapter PCnet-PCI II (Am79C970A), the only one I got to work with ReactOS, yeah 2018 year that's how we support hardware, even virtual
Everything else default.
Additionally you can log directly to Linux terminal, set Port Mode to TCP and use "screen" utility. Just like on my screenshot above.
We need to do syscall fuzzing and save every syscall name, it parameters and make sure things are saved. What usually happened with ReactOS after BSOD? Unbootable device and reinstall in most cases because of their FAT32. Even more, both 0.4.10 and 0.4.12 install and start with FAT32 volume that already has dirty bit set and various structure errors, facepalm. For note, ReactOS now support BTRFS as main filesystem so you can try it, it must be much more stable because it wasn't made by ReactOS devs.
This is why we use COM1 for logging as we can't rely on bugged fastfat ReactOS driver which corrupts volume as it wants.
Since ROCALL won't be really different to either our NTCALL64 or original Gloomy NTCALL from 1999 (it will even somewhat simpler), so we can skip it implementation details and just in short - it brute-force system services by calling them multiple times with parameters taken randomly from predefined "bad" arguments. Arguments here are not just random junk, they set up that way so we can catch not only bad pointers but also overflows. ROCALL also support system service filtering by blacklist like NTCALL64/NTCALL. Timeout for each service will be set to 30 sec.
Take a note that some system services may crash fuzzer or prevent it from displaying results, so we need to ban them.
Our default blacklist looks like this:
Code: Select all
As target ReactOS we take 0.4.12 Nightly Build because [ntos]
NtClose
NtShutdownSystem
NtSuspendProcess
NtSuspendThread
NtTerminateProcess
NtTerminateThread
[win32k]
NtUserSwitchDesktop
NtUserLockWorkStation
ReactOS Site wrote:You can expect ReactOS to work better but there may also be regressions.I always expect ReactOS to work better, so this definitely is our choice.
Spoiler: 0.4.10 from current "Release" also will be tested for cross-reference.
Copy ROCALL.exe somewhere on ReactOS volume, for example in C:\Tests, place blacklist.ini in the same directory.
ROCALL supports the following parameters:
Code: Select all
1. TEST, System Service TableROCALL [-win32k] [-logn | logv ] [-pc value] [-sc value]
* -logn - enable logging via COM1 port, service name will logged, default disabled;
* -logv - enable logging via COM1 port, service name and call parameters will be logged( slow), default disabled;
* -win32k - launch win32k service table fuzzing, default ntoskrnl service table fuzzing;
* -pc value - number of passes for each service (default value 1024);
* -sc value - start fuzzing from service entry number (index from 0), default 0.
Save VM state to snapshot.
Open command line in the ROCALL directory and execute it.
Try 1.
I use:
ROCALL -logn
Almost instantly the our first BSOD appears.
BSOD on: NtAllocateUuids
Source: https://github.com/reactos/reactos/blob ... uid.c#L314
Service marked as "unimplemented" however it does some things and do not return STATUS_NOT_IMPLEMENTED.
It completely miss any parameters validation and just a BSOD-generator.
Rolling back VM snapshot, updating blacklist with this "unimplemented" implemented BSOD-generator.
Try 2.
BSOD on NtDisplayString
Source: https://github.com/reactos/reactos/blob ... nbv.c#L772
Indeed, what could go possible wrong here. Note service not marked as "unimplemented". Implemented and working as expected? BSODing as expected?
Wtf this mean in ReactOS world is unknown. As for me it is not implemented even for alpha state.
Rolling back and updating blacklist.
Try 3.
BSOD on NtRaiseException
Source: https://github.com/reactos/reactos/blob ... ept.c#L172
Calling this function with invalid parameters result in blue screen because of intentionally set debug breakpoint.
How about log exception, check build type and only then break to the debugger? Nah why bother, suffer bitch.
Rollback etc.
Try 4.
BSOD on NtUnloadDriver
Source:https://github.com/reactos/reactos/blob ... er.c#L2107
Finally something marked as "implemented"! Oh well, better not.
It calls IopUnloadDriver with unchecked pointer and then IopUnloadDriver does wcsrchr with it. Nice. I feel strong Windows competitor here.
And I noticed cute todo here
* To doRollback.
* Guard the whole function by SEH.
*/
Try 5.
BSOD on NtSetUuidSeed
Source: https://github.com/reactos/reactos/blob ... uid.c#L378
Implemented! Whatever this mean.
0.4.10 additions
The following routines will blue screen on 0.4.10 if called with invalid parameters due to insufficient parameters validations or validations complete absence.
NtLoadKey
NtLoadKey2
NtLoadKeyEx
NtDeleteValueKey
NtQueryValueKey
This is somewhat fixed in 0.4.12
Rollback and go next.
When this fuzzing finished with no more BSOD's but then I got suddenly this:
Entire video mode collapsed and I got resolution like 100x100 4 bit. Must be an easter egg from developers.
2. TEST, Win32k User/Gdi Service Table
Where the most fun begin. In Windows world the win32k component is a exploit factory and effective built-in OS BSOD-generator.
As expected here is the same level of quality.
Save VM state to snapshot.
Open command line in the ROCALL directory and execute it.
I use:
ROCALL -win32k -logn
Try 1.
BSOD on NtGdiClearBrushAttributes
Source: https://github.com/reactos/reactos/blob ... h.cpp#L553
Unimplemented syscall stub breaking into debugger. In 0.4.10 "release" too. Best design practices everywhere. Keep doing the same way.
As you can see from source link NtGdiSetBrushAttributes does the same.
How about set last error "not implemented" and don't suddenly break into debugger if there is no one.
Rollback, update blacklist section "[win32k]" with failing service name.
Try 2.
Stop on NtGdiCreateDIBBrush
Source: https://github.com/reactos/reactos/blob ... h.cpp#L412
Insufficient parameters validation.
Rollback, update blacklist.
Try 3.
BSOD on NtGdiCreateDIBitmapInternal
Source: https://github.com/reactos/reactos/blob ... bj.c#L1457
BSOD located in GreCreateDIBitmapInternal.
What is wrong here. Need more detailed explanation because this service bug is a common for ReactOS, maybe because all the bugged code written by one author.
This routine has the following declarations (key fields in bold)
NtGdiCreateDIBitmapInternal(Now lets look how they are validated.
IN HDC hDc,
IN INT cx,
IN INT cy,
IN DWORD fInit,
IN OPTIONAL LPBYTE pjInit,
IN OPTIONAL LPBITMAPINFO pbmi,
IN DWORD iUsage,
IN UINT cjMaxInitInfo,
IN UINT cjMaxBits,
IN FLONG fl,
IN HANDLE hcmXform)
_SEH2_TRYRe-running ROCALL with -logv parameter (ROCALL -win32k -logv) generated BSOD parameters.
{
if(pbmi) ProbeForRead(pbmi, cjMaxInitInfo, 1);
cjMaxInitInfo = 0x0000000
pbmi = 0x00000001
so it passes "if (pbmi)" and enters ProbeForRead(0x00000001, 0x00000000, 1);
Now look on ReactOS ProbeForRead
https://github.com/reactos/reactos/blob ... rin.c#L102
Code: Select all
So this check is bypassed and no validation take place.ProbeForRead(IN CONST VOID *Address,
IN SIZE_T Length,
IN ULONG Alignment)
{
ULONG_PTR Last, Current = (ULONG_PTR)Address;
PAGED_CODE();
/* Only probe if we have a valid length */
if (Length != 0) {
....
}
}
Next invalid pointer dereferenced. Blue Screen.
Rollback, update blacklist.
Try 4.
BSOD on NtGdiDdCreateSurface
This routine passes all it parameters to Dxg.sys->intDdCreateSurfaceOrBuffer.
Source: https://github.com/reactos/reactos/blob ... /d3d.c#L43
Nor Win32k nor Dxg.sys are not validating input parameters. The whole Dxg.sys completely trust everything from Win32k. Best design practicies in work. Learn from this. Copy this.
Rollback etc
Try 5.
BSOD on NtGdiDdCreateD3DBuffer
Same as above.
Call Chain NtGdiDdCreateD3DBuffer -> DxDdCreateD3DBuffer -> intDdCreateSurfaceOrBuffer
Try 6 and 7.
BSOD on NtGdiDdLock
BSOD on NtGdiDdUnlock
See DxDdLock
See DxDdUnLock
Same as above, win32k/dxg not validating anything.
Try 8.
BSOD on NtGdiExtCreateRegion
Source: https://github.com/reactos/reactos/blob ... on.c#L3802
Insufficient parameters validation, case similar to NtGdiCreateDIBitmapInternal BSOD.
Try 9, 10, 11
Stop on NtGdiGetCharABCWidthsW
Stop on NtGdiGetCharWidthW
Stop on NtGdiGetFontResourceInfoInternalW
Source: https://github.com/reactos/reactos/blob ... pe.c#L6443
Source: https://github.com/reactos/reactos/blob ... pe.c#L6647
Source: https://github.com/reactos/reactos/blob ... ont.c#L952
Insufficient parameters validation. System hang.
Try 12.
BSOD on NtGdiPolyPolyDraw
Source: https://github.com/reactos/reactos/blob ... hap.c#L376
Insufficient parameters validation, overflow. Similar to NtGdiCreateDIBitmapInternal
Try 13.
Stop on NtGdiSetDIBitsToDeviceInternal
Source: https://github.com/reactos/reactos/blob ... obj.c#L455
Insufficient parameters validation. System hang.
Try 14.
BSOD on NtUserBuildHwndList
Source: https://github.com/reactos/reactos/blob ... ow.c#L1338
Insufficient parameters validation.
Try 15.
BSOD on NtUserConvertMemHandle
Source: https://github.com/reactos/reactos/blob ... rd.c#L1159
Insufficient parameters validation.
Try 16.
BSOD on NtUserCreateAcceleratorTable
Source: https://github.com/reactos/reactos/blob ... tor.c#L229
Insufficient parameters validation, incorrect comparisons.
Code: Select all
Cool story, bro!NtUserCreateAcceleratorTable(
LPACCEL Entries,
ULONG EntriesCount)
....
if (!Entries || EntriesCount <= 0)
{
SetLastNtError(STATUS_INVALID_PARAMETER);
RETURN( (HACCEL) NULL );
}
Try 17 & 18.
Stop on NtUserCreateWindowEx
Stop on NtUserEnumDisplayMonitors
Source: https://github.com/reactos/reactos/blob ... ow.c#L2466
Source: https://github.com/reactos/reactos/blob ... tor.c#L543
Insufficient parameters validation. System hang.
Try 19.
BSOD on NtUserGetAsyncKeyState
Source: https://github.com/reactos/reactos/blob ... ard.c#L632
Insufficient parameters validation, integer overflow.
Try 20.
BSOD on NtUserGetCursorInfo
Source: https://github.com/reactos/reactos/blob ... con.c#L645
Incomplete parameter validation. Input parameter not checked before read access but checked before write access, rofl.
Try 21.
BSOD on NtUserGetDCEx
Source: https://github.com/reactos/reactos/blob ... ndc.c#L973
Insufficient parameters validation.
Try 22.
BSOD on NtUserGetKeyboardLayoutList
Source: https://github.com/reactos/reactos/blob ... out.c#L496
Insufficient parameters validation, overflow.
Try 23.
BSOD on NtUserSBGetParms
Source: https://github.com/reactos/reactos/blob ... ar.c#L1218
Input parameters not validated.
Try 24.
Stop on NtGdiEngUnlockSurface
Source: https://github.com/reactos/reactos/blob ... ace.c#L615
Best design practices. RtlAssert wait for debug input.
There are few more but I tired copy-pasting from logs.
Note another fun bug from ReactOS ntoskrnl. When fuzzing win32k with logging call parameters I experienced multiple BSOD's from ntoskrnl KeBugCheck(CRITICAL_PROCESS_DIED). The last one thing I want to do is debug ReactOS, so it is up to developers figure out what is wrong here. For ROCALL this behavior resulted in adding "-sc" switch to start from given service index and not from beginning.
3. TEST complete
When our fuzzer with help of blacklist finished working, ReactOS was alive, but barely unusable, just like if it was at death's door. Impossible to do anything, the reset (and reinstall for sure on fat32) was the only option. Reset confirmed quality of ReactOS FS driver with unbootable state and this fun message
Even if ReactOS syscalls passed this superficial test - it doesn't mean they are not bugged as hell. More deep and smart fuzzing will for sure find more bugs ;)
For example
BSOD on NtQuerySecurityObject
Source: https://github.com/reactos/reactos/blob ... ure.c#L803
This service is a BSOD generator in case of simple race condition.
RC attack of this type is something I used 12 years ago against some Chinese antirootkits and some crapware mainstream antiviruses. For more recent info's you may refer to j00ru series of blogposts where he multiple times crashed Windows using the same principle. Idea is simple, two threads access same memory simultaneously, first thread does read/write while second thread running in loop making changes to memory region protection.
Code: Select all
Run a few seconds and voila. g_sdBuffer = VirtualAlloc(NULL, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (g_sdBuffer) {
hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFunc, NULL, 0, &threadId);
if (hThread) {
SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST);
do {
NtQuerySecurityObject(hFile,
OWNER_SECURITY_INFORMATION,
(PSECURITY_DESCRIPTOR)g_sdBuffer,
0x1000,
&returnLength);
} while (1);
CloseHandle(hThread);
}
}
4. Win32k, CSRSS
There is also small amount of Win32k services that are unaccessible for programs except CSRSS.
You can find them by this code (or similar)
Code: Select all
Obviously ROCALL can't fuzz such services without ROCALL modification and injecting it to the csrss. However this is not implemented in current version and judging on services available with such csrss bind - it is not worth it.if (PsGetCurrentProcess() != gpepCSRSS)
return STATUS_ACCESS_DENIED;
Conclusions.
Overall, my impressions after looking on how ReactOS works and how it implemented can be described by this picture. Quite obvious.
Not each syscall is properly covered by tests. Besides obvious BSOD's there is a hell and mess in ReactOS source code. Dropped, incomplete code, useless junk, copy-pasting Microsoft style of early 90x-00x (wow wtf who told you it is good?). No usage of static analyzers or their results ignoring. Some of the above bugs can be detected by simple static code analyzer at compilation.
What I can suggest to ReactOS developers. Concentrate exceptionally on fixing bugs and refactoring code, especially this one dropped by authors 10-12 years ago. Reconsider your great idea "lets break to the debugger" from syscalls that's are not implemented. It is very cool to watch your system completely not responsive at any time. I may somehow understand why you did this, but such trash should not present in "release". Even if you "alpha". You alpha for 20 years and nothing changes. This is not a excuse anymore. ReactOS is out-dated code base trash that screams about attention to it bugs.
Q: Does ReactOS can replace Windows (in perspective) on desktops?
A: No it can't. There is giant gap between this project and actual Windows 10 or Windows 7. When ReactOS will come closer to Windows 7 (2030-2040? I'm joking - never) MS product will be completely outdated and unused by major audience.
Q: Why this isn't reported directly to ReactOS devs?
A: Because I don't value this project as worth for any kind of official reports. Twenty years of unworkable alpha. Pff. This is my report. Part 1. You either fix your ridiculous bugs or GTFO. This is how I work.
This is first part end. I do believe that while some people tried to use this project for their own selfish goals (like these clowns from prologue part) most part of ReactOS dev involved actually loved what they do and put their best effort in this project. As for now ReactOS need some love from experienced and professional developers so if you can and want - why not to waste some of your time. There is big surface for various tests and fixes to make this OS at least somewhat stable (I'm not even talking here about "usable").
The only possible good scenario for ReactOS future is to become a VM bind-only OS.
Collection of ReactOS Blue Screens
Some of the above BSOD's, I was doing screenshots until got finally bored.
ROCALL project
https://github.com/hfiref0x/ROCALL
*well it actually never was and highly likely never will be
Ring0 - the source of inspiration