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":
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
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]
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 !!!