Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!csd4.csd.uwm.edu!cs.utexas.edu!uunet!cs.dal.ca!lane From: lane@cs.dal.ca (John Wright/Dr. Pat Lane) Newsgroups: comp.sys.ibm.pc Subject: Patches to COMMAND.COM for DOS4.0x (LONG) *** CORRECTION *** Summary: My old set of patches updated for several vers of DOS 4.0 Keywords: DOS COMMAND.COM patch environment size echo Message-ID: <1989Aug18.174305.1071@cs.dal.ca> Date: 18 Aug 89 17:43:05 GMT Organization: Math, Stats & CS, Dalhousie University, Halifax, NS, Canada Lines: 451 **** This is a corrected version of my posting of 14 Aug 89 04:56:38 GMT **** (Message-ID: <1989Aug14.045638.26582@cs.dal.ca>). In the original **** posting, there were a couple of typos in the offsets for the ECHO- **** space patch for MSDOS 4.00 and MSDOS 4.01 (arghh!). Sorry to all **** for any inconvenience and thanks to Roger L. Ferrel (ferrel@btni) **** for pointing them out to me. Some time ago I posted a set of patches for COMMAND.COM to do some nice things like increase the default environment size and make ECHO OFF the default for all batch files. All these patches had been posted on Usenet before but usually for a single version of DOS. I presented the patches for several DOS versions 3.10 to 3.30, from IBM, Microsoft and Compaq. In this posting I present the patches for versions: IBM PCDOS 4.00, Microsoft MSDOS 4.00 and Microsoft MSDOS 4.01. In a companion posting to this one, I present patches for IBM PCDOS 3.30, Microsoft MSDOS 3.30 and Compaq MSDOS 3.31. In the companion posting, I explain that these latest versions of DOS provide other means of accomplishing the same things as the patches. With these methods, however, there remain limitations and inconveniences which the patches can circumvent. Users please note that these patches have been tested rather perfunctorily and should be used with some caution. Definitely keep an unpatched copy of COMMAND.COM on a bootable disk. If you mess up your regular copy of COMMAND.COM, you won't be able to boot with it; you'll have to boot from the floppy and copy the original COMMAND.COM over the messed up one before you can reboot normally. Following the presentation of the patches for the various DOS versions, I list a couple of batch files I use for effecting the patches. Following that I list the dis-assembled code around the patched areas so that those with DOS versions other than those shown will be able to find the proper offsets. Remember to add 100h to offsets when patching with DEBUG. OFFSETS for patch to COMMAND.COM for IBM PCDOS 4.00 Default environment size of 512 bytes [1B2A] = 0A 00 -> 20 00 ECHO OFF for AUTOEXEC.BAT [1FE3] = 03 -> 02 Echo off for batch files except AUTOEXEC.BAT [2D09] = 01 -> 00 ECHO produces blank line [543C-5452] -> [543E-5454] (everything moved down two bytes) [5439] = E8 9C 00 72 15 -> 51 E8 9B 00 59 [543F] = 15 -> 16 [5453] = 2C -> 2A [5455] = 00 74 -> 90 E3 [548B] = C4 -> C6 [54CC] = 83 -> 85 The echo-space patch is quite involved and completely different from previous versions. See below for details. OFFSETS for patch to COMMAND.COM for Microsoft MSDOS 4.00 Default environment size of 512 bytes [1B2A] = 0A 00 -> 20 00 ECHO OFF for AUTOEXEC.BAT [1FE3] = 03 -> 02 Echo off for batch files except AUTOEXEC.BAT [2CCE] = 01 -> 00 ECHO produces blank line [540B-5421] -> [540D-5423] (everything moved down two bytes) [5408] = E8 9C 00 72 15 -> 51 E8 9B 00 59 [540E] = 15 -> 16 [5422] = 2C -> 2A [5424] = 00 74 -> 90 E3 [545A] = C4 -> C6 [549B] = 83 -> 85 OFFSETS for patch to COMMAND.COM for Microsoft MSDOS 4.01 Default environment size of 512 bytes [1B2A] = 0A 00 -> 20 00 ECHO OFF for AUTOEXEC.BAT [1FE3] = 03 -> 02 Echo off for batch files except AUTOEXEC.BAT [2CCE] = 01 -> 00 ECHO produces blank line [540C-5422] -> [540E-5424] (everything moved down two bytes) [5409] = E8 9C 00 72 15 -> 51 E8 9B 00 59 [540F] = 15 -> 16 [5423] = 2C -> 2A [5425] = 00 74 -> 90 E3 [545B] = C4 -> C6 [549C] = 83 -> 85 Following are two batch files PATCH.BAT and UNPATCH.BAT for installing and un-installing the patches for IBM PC-DOS 4.00. It should be easy enough to modify this for other DOS 4 versions. ----------------- PATCH.BAT for IBM PCDOS 4.00 -------------------- echo off echo INSTALL COMMAND.COM PATCHS FOR IBM PC-DOS 4.00 rem usage PATCH [filespec] rem Patch 1. Default environment size is 512 bytes rem Patch 2. ECHO OFF default for AUTOEXEC.BAT rem Patch 3. ECHO OFF default for batch files except AUTOEXEC.BAT rem Patch 4. ECHO-space produces blank line if "%1"=="" goto :default set $s=%1 echo About to modify %$s% goto pause :default set $s=COMMAND.COM echo About to modify %$s% in the default drive and directory :pause pause if not exist %$s% goto error echo Creating PATCH.TMP... echo e1C2A >>patch.tmp echo 20 00 >>patch.tmp echo e20E3 >>patch.tmp echo 02 >>patch.tmp echo e2E09 >>patch.tmp echo 00 >>patch.tmp echo m553C,5552,553E >>patch.tmp echo e5539 >>patch.tmp echo 51 E8 9B 00 59 >>patch.tmp echo e553F >>patch.tmp echo 16 >>patch.tmp echo e5553 >>patch.tmp rem note *two* spaces bewtten 2A and 90 below echo 2A 90 E3 >>patch.tmp echo e558B >>patch.tmp echo C6 >>patch.tmp echo e55CC >>patch.tmp echo 85 >>patch.tmp echo w >>patch.tmp echo q >>patch.tmp debug %$s% patch.tmp echo 0A 00 >>patch.tmp echo e20E3 >>patch.tmp echo 03 >>patch.tmp echo e2E09 >>patch.tmp echo 01 >>patch.tmp echo m553E,5554,553C >>patch.tmp echo e5539 >>patch.tmp echo E8 9C 00 >>patch.tmp echo e553D >>patch.tmp echo 15 >>patch.tmp echo e5551 >>patch.tmp rem note *two* spaces between 2C and 80 below echo 2C 80 F9 00 74 >>patch.tmp echo e558B >>patch.tmp echo C4 >>patch.tmp echo e55CC >>patch.tmp echo 83 >>patch.tmp echo w >>patch.tmp echo q >>patch.tmp debug %$s% > 3576:1C2C BA746D MOV DX,6D74 3576:1C2F B104 MOV CL,04 3576:1C31 D3EA SHR DX,CL 3576:1C33 89169F24 MOV [249F],DX Just searching for '0A 00' should find this one. Echo off for AUTOEXEC.BAT -u 20dc l27 3576:20DC A1DA0E MOV AX,[0EDA] 3576:20DF C606300F03 MOV BYTE PTR [0F30],03 <> 3576:20EC 33FF XOR DI,DI 3576:20EE B000 MOV AL,00 3576:20F0 AA STOSB 3576:20F1 B001 MOV AL,01 3576:20F3 AA STOSB 3576:20F4 33C0 XOR AX,AX 3576:20F6 AB STOSW 3576:20F7 AB STOSW 3576:20F8 AA STOSB 3576:20F9 AB STOSW 3576:20FA AB STOSW 3576:20FB B8FFFF MOV AX,FFFF 3576:20FE B90A00 MOV CX,000A 3576:2101 F3 REPZ 3576:2102 AB STOSW Searching for '03 C7 06' works in ver 3.30 and above. Searching for '8E C0 33 FF B0 00' worked in 3.20 and above. All those STOSW/B's should stand out pretty well. Echo off for other batch files -u 2df6 3576:2DF6 26 ES: 3576:2DF7 803E420F01 CMP BYTE PTR [0F42],01 3576:2DFC 7403 JZ 2E01 3576:2DFE E80708 CALL 3608 3576:2E01 E8A420 CALL 4EA8 3576:2E04 26 ES: 3576:2E05 A0300F MOV AL,[0F30] 3576:2E08 2401 AND AL,01 <> 3576:2E0D 26 ES: 3576:2E0E F706DA0EFFFF TEST WORD PTR [0EDA],FFFF 3576:2E14 7414 JZ 2E2A Look for '24 01 50 33 C0'. Echo-blank produces blank line For DOS 4.00, they made some significant changes to the code that processes the ECHO command. It now uses code in common with BREAK and VERIFY and this makes the patch for this area much more complicated. I worked some- thing out which appears to work but I'm still a bit uncomfortable with it and I'm not sure there isn't a better way. As such, I present all the code involved and explain the fix in some detail. If you see a problem or a better way, do let me know. ECHO followed by only blanks and tabs, would normally be interpreted as ECHO without arguments and result in the "ECHO is on|off" message (just like BREAK and VERIFY). ECHO followed by a single arg, "on" or "off", causes a flag to be set or unset (again, same thing for BREAK and VERIFY). ECHO followed by any other text causes the text to be output to stdout (unlike BREAK and VERIFY where an arg. besides "on" or "off" is an error) The code sections that process ECHO, BREAK and VERIFY all call a routine that sets flags and registers to indicate whether there are command line arguments and whether there is only a single "on" or "off". As in previous DOS versions, all three code sections are entered with the contents of [CS:0080], the length of the command line following the command keyword, in CL. Unlike previous DOS versions, the routine that checks arguments changes CX (returning it zero if there are no arguments). What we want to do here is to print the command line argument buffer even when it contains only blanks and tabs. In this case, the argument checking routine will indicate no arguments but [CS:0080] will be non-zero. My solution was to put CX on the stack before calling the routine, restore it after and test the original CX instead of the value returned in CX. In order to save some bytes I had to change CMP CL,0, JZ xxxx to JCXZ xxxx. To insert the PUSH and POP instructions for preserving CX, I had to move a section of code down two bytes and change a couple of jumps that pointed into this code. Pretty hairy! <> <> 3576:5539 E89C00 CALL 55D8 <> 3576:553C 7215 JB 5553 <> 3576:553E 8E1E1C62 MOV DS,[621C] 3576:5542 7506 JNZ 554A 3576:5544 800E300F01 OR BYTE PTR [0F30],01 <> 3576:5549 C3 RET 3576:554A 8026300FFE AND BYTE PTR [0F30],FE <> 3576:554F C3 RET <> 3576:5550 E92CF3 JMP 487F <> 3576:5553 80F900 CMP CL,00 <> 3576:5556 7409 JZ 5561 <> 3576:5558 BA8200 MOV DX,0082 <> 3576:555B E826F0 CALL 4584 3576:555E E9C6EF JMP 4527 <> <> 3576:5561 8E1E1C62 MOV DS,[621C] <> 3576:5565 8A1E300F MOV BL,[0F30] 3576:5569 0E PUSH CS 3576:556A 1F POP DS 3576:556B 80E301 AND BL,01 3576:556E BA3C5A MOV DX,5A3C 3576:5571 EB22 JMP 5595 <> <> 3576:5573 E86200 CALL 55D8 ... 3576:558A 75C4 JNZ 5550 <> ... <> 3576:5595 BE4D5A MOV SI,5A4D ... 3572:55B5 C3 RET <> 3576:55B6 E81F00 CALL 55D8 ... 3576:55CB 7583 JNZ 5550 <> ... 3572:55D6 EBBD JMP 5595 <> 3576:55D8 BE8100 MOV SI,0081 <> ... 3576:562C C3 RET This routine is somewhat involved and I've left out details. It returns flags and registers as follows: echo on CF=0 ZF=1 AX=-1 CX=1 BX=2E20 DX=0 echo off CF=0 ZF=0 AX=-1 CX=1 BX=2E20 DX=0 echo text CF=1 ZF=0 AX= 8 CX=8 BX=2E20 DX=59FD echo CF=1 ZF=1 AX=-1 CX=0 BX=2EB9 DX=59FD Thus if CF is unset, we had an "on" or "off" (indicated by ZF flag), if CF is set, we had other text (in which case AX=8) or no args (AX=-1); As well, CX=1 for "on"/"off", CX=8 for other text or CX=0 for no args. The patched code is as follows: 3572:5539 51 PUSH CX <- inserted 3572:553A E89B00 CALL 55D8 <- moved & offset changed 3572:553D 59 POP CX <- inserted 3572:553E 7216 JB 5556 <- moved & offset changed 3572:5540 8E1E1C62 MOV DS,[621C] \ 3572:5544 7506 JNZ 554C | moved 3572:5546 800E300F01 OR BYTE PTR [0F30],01 | down 3572:554B C3 RET | two 3572:554C 8026300FFE AND BYTE PTR [0F30],FE | bytes 3572:5551 C3 RET / 3572:5552 E92AF3 JMP 487F <- moved & offset changed 3572:5555 90 NOP <- changed 3572:5556 E309 JCXZ 5561 <- changed 3572:5558 BA8200 MOV DX,0082 3572:555B E826F0 CALL 4584 3572:555E E9C6EF JMP 4527 ... 3572:558A 75C6 JNZ 5552 <- offset changed ... 3572:55CB 7585 JNZ 5552 <- offset changed Good luck and let me know if you have problems with these patches. -- John Wright ////////////////// Phone: 902-424-3805 or 902-424-6527 Post: c/o Dr Pat Lane, Biology Dept, Dalhousie U, Halifax N.S., CANADA B3H-4H8 Cdn/Eannet:lane@cs.dal.cdn Uucp:lane@dalcs.uucp or {uunet watmath}!dalcs!lane Arpa:lane%dalcs.uucp@uunet.uu.net Internet:lane@cs.dal.ca