Since I was a die hard fan of Windows 98, I delayed the upgrade to XP as long as I could. There were some reasons, most has something to do with the common joke (originating from the times before SP2) - "how many seconds does it take for a newly installed XP to be infected after connecting it to the Internet?". But then, the SP2 came, and I finally decided to move to the NT family. After installing Windows I've setup my .BAT script (that always starts after starting a console - it setups some env variables and displays a colorful "WIND" logo), I've run cmd.exe, and... instead of my lovely colorful "WIND" logo I've saw "bushes". Sadly, I had to REM-out the logo (and all other colors from my script), and continue setting up the system...
I got back to this topic a year later, after figuring out (one again) that a two-color console just isn't the thing I want (I use the console frequently - I have at least a few console windows opened all the time), I decided to do something about it.
After a few hours, I had a cmd.exe patch ready. I allowed to use ANSI Escape Codes in the internal cmd.exe commands (ECHO, TYPE, PROMPT, etc). I have even put the patch on my techblog (not this one, it was a few years ago). But then, the hosting with my old techblog was shutdown, and the patch vanished into the mists of history.
Until today, when I decided to repost it again ;>

OK, how does it all work (offtopic: sources + binaries are, as always, at the end of this post... GPL this time).
The interpreted, aka cmd.exe, outputs the text on the console using API function WriteConsoleW. So, creating a hook on this function in the context of cmd.exe will make every text written out by cmd.exe to be transfered into our function. The function will just implement ANSI Escape Codes - it will detect the escape code (ASCII no. 27), parse the command, and react to it accordingly. My implementation (placed in AnsiSupport.c) is mostly compatible with the original ANSI Escape Codes, however there are a few changes (well, I've made it for myself, so I figured that functionality is more important than compatibility). I have implemented the following ANSI "commands":
Original ANSI:
m - color change
H or f - cursor position change
A - move the cursor one line up
B - move the cursor one line down
C - move the cursor one line right
D - move the cursor one line left
s - save the cursor position
u - recall the cursor position
2J - clear screen
K - clear line
My "extensions":
X - push the current color on the color stack
x - pop the color from the stack
Y - save the color at the given index in the color table (table != stack)
y - recall the color from the table
t - start of the console title (window title, I use it to output the current directory in the prompt to the window title)
T - end of title
Offtopic: hehe this is a good place to include the OpenGL implementation ;D (see my previous post)
I won't describe here the ANSI implementation, since it's very easy imho. One should consider looking into the sources anyway, to know how to use each escape code, and how do they work ;>
As for the patching process, it works this way:
1. After executing ansihack.exe (the patcher) it will make a copy of cmd.exe (from the system32 directory) to the current working directory as _cmd.exe, and it will open it for writing
2. It checks for existence of DllSpoof.dll and AnsiSupport.dll files (one needs to copy these files to the system32 directory later)
3. It finds the OEP of cmd.exe
4. It sets the IMAGE_FILE_RELOCS_STRIPPED flag (important: setting this flag under Vista and later will cause the address space randomization (aka ASRL) to be turned off for cmd.exe image - it will be loaded ALWAYS on the same address... which really changes nothing ;p, but makes things easier for debugging and patching)
5. It increases the size of the last section, and sets it Read/Write/Execute flags (it's not to beautiful, but it's sufficient)
6. It copies a short code to the last section - the code will load the AnsiSupport.dll library. It also changes the EP to the appended code (after the code loads the library, it jumps to OEP - some AV software might not be to happy about it, but who cares, just turn on the ignore on this file)
7. The forged brand new _cmd.exe is stored
So, after running the patch (I suggest running the patch in a console), there should be a new file in the directory called _cmd.exe. Now, one should execute this file, and enter the tests directory, and run some tests, for example slogo.bat. If a colorful logo shows up, then everything went correct. In any other case, one can debug it a little, or write me an e-mail ;>
Now one can copy the _cmd.exe to the system directory (remember to copy both DLL files!), and either replace the cmd.exe (I would not recommend it, make a copy if you insist, and remember that Windows loves to replace this file at update or finding out that it has changed), or use the following registry "hack":
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\cmd.exe]
"Debugger"="c:\\windows\\system32\\_cmd.exe %*"This causes the _cmd.exe to be run when someone wants to execute cmd.exe.
And thats all for today. Have fun with setting up a colorful prompt ;>
One more thing. This patch allows using ANSI Escape Codes only IN THE CONTEXT OF CMD.EXE (including BAT/CMD scripts). Making a global ANSI Escape Codes support would require a patch for CSRSS.exe, or one of it's DLLs - basesrv.dll/csrsrv.dll/winsrv.dll (excuse my memory, I don't remember where is the console window implementation placed).
cmd_ansihack_004c.zip (46kb, sources + binaries) !!! USE AT YOUR OWN RISK ! YOU HAVE BEEN WARNED !!!


Comments:
Glad u like it ;>
The system cannot find message text for message number 0x2350 in the message fil
e for Application.
The system cannot find message text for message number 0x2334 in the message fil
e for Application.
This is normal on Vista and Win7 systems - afaic it is related to the localized string mechanics on these systems, that are bound to both exe name and path.
When you copy the _cmd.exe to c:windowssystem32 and rename it as cmd.exe, everything should work OK (if it doesn't, let me know) ;>
or copy cmd.exe.mui to _cmd.exe.mui
either way, _cmd.exe must reside in %windir%system32
I'm having troubles making your hack work with anything but your examples.
Looking through the code I think I found something which *could* be causing trouble:
In the file AnsiSupport.c, at line 27 you say:
... && i + 2 < nNumberOfCharsToWrite && ...
I'm wondering what's going to happen if someone decides to write in smaller (say, 1 byte) chunks to the console...?
Maybe that's what wrong, maybe not.
The program I'm trying to run is "hoogle" (http://haskell.org/haskellwiki/Hoogle) with its colour option on.
Thank you for a great hack, please let me know if there's a way around this (I'll be checking this page regularly)
Regards.
Hi!
Hmm, you are saying that you are trying to run an external program, and that is the problem. As I've written before, this hack is for cmd.exe only, and it adds the ANSI support only to cmd.exe, not to the entire console. So I guess you won't be able to use this hack with Hoogle, unless you apply it directly to Hoogle or to the entire console (CSRSS). However in the current state non of this is supported by my patcher or the hack itself (maybe in the future).
Take care!
Help?!
Output from ansihack
$ ansihack.exe
cmd.exe Ansi Patch ver.0.00c by gynvael.coldwind//vx (2009)
Checking DllSpoof.dll... OK
Checking AnsiSupport.dll... OK
Getting system directory... C:Windowssystem32
Acquiring a copy of cmd.exe... OK
Opening _cmd.exe... OK
Getting OEP... 0000921A
Adding IMAGE_FILE_RELOCS_STRIPPED flag... OK
Resizeing last section and changing EP... OK
Getting address of LoadLibraryA in IAT... 00833838
Injecting AnsiSupport.dll loader... OK
Saving... OK
Done.
Hmm, that's strange. I've tested it on Windows 7, and it seemed to work. I'll look into the issue later, thank you for the report ;>
Could you tell me what Windows 7 version do you have (language / type).
Add a comment: