[comp.sys.ibm.pc] Patch COMMAND.COM to take "=" into BAT files

scott@ubvax.UB.Com (Scott Scheiman) (06/24/88)

A few weeks ago someone asked if there was a way to teach COMMAND.COM 
to accept the equal sign in batch file parameters.  I posted that I had 
a patch to PC DOS 3.10 which did this.  A few people mailed that they 
were interested in the info.  I've decided to post this information 
(hopefully those who mailed me are still perusing this group).

[[[  For those who don't know what this is about, all versions of DOS 
that I know of treat tab, equal, comma, and semicolon all as if they 
were just a space when passing parameters into a batch file.  For 
example, if you wanted to write a batch-file pre-processor for the MAKE 
program (call it BUILD.BAT), you'd like to be able to pass parameters 
to MAKE as %1, %2, %3 etc. by typing 

            BUILD -flag MAKEPARM1=VALUE1 MAKEPARM2=VALUE2 ...

but DOS would interpret this as if you'd typed

            BUILD -flag MAKEPARM1 VALUE1 MAKEPARM2 VALUE2 ...

i.e., the equal signs are gone--but MAKE *needs* those equal signs.  
Besides, now this is *five* parameters and there's no good way for the 
batch file to re-insert the equal signs at the right place(s).  ]]] 

All who requested this info said they had DOS 3.3, but wanted to see my 
3.10 patch since they're willing to try to hack it into 3.3.  So I'm 
going to give a lot of context here--this posting is LONG.  (Which is 
also why this posting is late--I needed to reverse-engineer my old 
patch, and I've been very busy recently.  Sorry.) 

(To the fellow who said his bugaboo was "semicolon" instead of "equal", 
read on!  A variation of this may very likely work for you.)

When I did this, I was only trying to get the equal sign into batch 
files.  I sat down with DEBUG on DOS 3.10 COMMAND.COM and looked for 
CMP AL,3D.  I struck Paydirt!  (What follows is a disassembly from 
DEBUG--the comments are mine.) 

xxxx:29D8 CD21          INT     21
xxxx:29DA 72DC          JB      29B8
xxxx:29DC 0E            PUSH    CS
xxxx:29DD 1F            POP     DS
xxxx:29DE C3            RET
xxxx:29DF 52            PUSH    DX
xxxx:29E0 BA7F39        MOV     DX,397F
xxxx:29E3 1E            PUSH    DS
xxxx:29E4 0E            PUSH    CS
xxxx:29E5 1F            POP     DS
xxxx:29E6 E8B01A        CALL    4499
xxxx:29E9 1F            POP     DS
xxxx:29EA 5A            POP     DX
xxxx:29EB C3            RET
xxxx:29EC AC            LODSB
xxxx:29ED E80400        CALL    29F4                <-- [4] --SEE TEXT
xxxx:29F0 74FA          JZ      29EC
xxxx:29F2 4E            DEC     SI
xxxx:29F3 C3            RET
xxxx:29F4 3C20          CMP     AL,20   ( ) SPACE   <-- SUBR. ENTRY [1]
xxxx:29F6 74FB          JZ      29F3
xxxx:29F8 3C3D          CMP     AL,3D   (=) EQUALS                  [2]
xxxx:29FA 74F7          JZ      29F3
xxxx:29FC 3C2C          CMP     AL,2C   (,) COMMA
xxxx:29FE 74F3          JZ      29F3
xxxx:2A00 3C3B          CMP     AL,3B   (;) SEMI
xxxx:2A02 74EF          JZ      29F3
xxxx:2A04 3C09          CMP     AL,09       TAB
xxxx:2A06 74EB          JZ      29F3
xxxx:2A08 3C0A          CMP     AL,0A       LINE FEED (NEWLINE)
xxxx:2A0A C3            RET

That subroutine [1] sure looked like the key to all this!  It appears 
to return with ZERO flag set if the character being tested in AL is one 
of the magic characters!  So, the idea behind the patch is to change 
the order of the tests here, and then find the appropriate call(s) to 
this subroutine and jump into the MIDDLE of it, bypassing the test for 
the character wanted into batch file parameters.  For my case, I just 
needed to exchange the space-test and the equals-test (exchange the 20 
and 3D at [1] and [2] above). 

Now, which call(s) needed to be changed???  There are at least a dozen 
calls to this subroutine (I remember it more like 20).  I wound up 
trying changing them one by one.  The fourth (or so) which I checked 
seemed to have an effect: 

xxxx:19B4 E83510        CALL    29EC
xxxx:19B7 3C0D          CMP     AL,0D
xxxx:19B9 741D          JZ      19D8
xxxx:19BB E306          JCXZ    19C3
xxxx:19BD 26            ES:
xxxx:19BE 893F          MOV     [BX],DI
xxxx:19C0 83C302        ADD     BX,+02
xxxx:19C3 AC            LODSB
xxxx:19C4 E82D10        CALL    29F4    <-- HERE IT IS  [3]
xxxx:19C7 7407          JZ      19D0
xxxx:19C9 AA            STOSB
xxxx:19CA 3C0D          CMP     AL,0D
xxxx:19CC 740A          JZ      19D8
xxxx:19CE EBF3          JMP     19C3
xxxx:19D0 B00D          MOV     AL,0D
xxxx:19D2 AA            STOSB
xxxx:19D3 E3DF          JCXZ    19B4
xxxx:19D5 49            DEC     CX
xxxx:19D6 EBDC          JMP     19B4
xxxx:19D8 32C0          XOR     AL,AL
xxxx:19DA AA            STOSB
xxxx:19DB 8D5D0F        LEA     BX,[DI+0F]
xxxx:19DE B104          MOV     CL,04
xxxx:19E0 D3EB          SHR     BX,CL
xxxx:19E2 B44A          MOV     AH,4A
xxxx:19E4 CD21          INT     21

In my case, since I only interchanged the leading CMP instructions in 
that magic subroutine, all that was needed was to have the CALL go 4 
bytes further (i.e., change the 2D to a 31 in instruction [3]). 

It turns out that the CALL at [4] also needs to be changed (interesting 
that it's just in front of the magic subroutine).  Change the 04 to an 
08 in instruction [4]. 

That's it.  In PC DOS 3.10, only four bytes needed to be changed!  
Hopefully the contexts I've included will be helpful in doing this for 
DOS 3.3.  Good luck!

(Note:  In reverse-engineering my patch for this posting, I tried 
undoing the patches in the two CALLs.  I was looking to see if I got an 
interesting behavior I got when I originally searched for the above.  
Originally, I had a patched version of COMMAND.COM which seemed fine--
for a day or so.  Then a batch file containing an    IF "" == ""...    
failed!  Well, this old behavior *did not* appear today as I backed out 
my patches one-by-one.  Therefore, I had done something different back 
then.  My guess is that I first tried changing *all* the calls to jump 
to the middle of that magic subroutine.  It turns out that that routine 
is also used in an obscure way to parse IF statements and bypassing 
the test for the equal sign broke it!!!  My recommendation is to change 
the *minimum* number of things to achieve your goals.) 

Would whoever gets this into DOS 3.3 please mail me the resulting patch 
(or post it)?  Thanks!

(No warranty is expressed or implied.  Use this info at your own risk.  
I'm posting this stuff as an individual on the off chance someone may 
find it useful.  This has nothing to do with my employer.)

Remember to keep a backup copy of COMMAND.COM if you hack at it!
-- 
"Ribbit!"         Scott Scheiman   (408) 562-5572        Ungermann-Bass, Inc.
  ` /\/@\/@\/\           scott@ubvax.UB.com          2560 Mission College Blvd.
   _\ \ -  / /_         ...uunet!ubvax!scott            Santa Clara, CA 95054