how to find what to patch

using a recent version of IDA, it is quite easy to find where to patch cmd.exe since IDA uses the .pdb file available from microsoft to name most functions, you get a very readable disassembly.

get rid /avoid/prevent the "Terminate Batch job (Y/N)?" prompt

tip on how to get rid of the annoying "Terminate Batch job (Y/N)?" question after typing break. why wouldn't I want to break, if I just hit 'break' ? and besides pressing 'Y' at that moment gives unpredictable results.

in cmd.exe, search for the hex string "68 7B 23 00 00"

.text:4AD1B2F9 83 3D C4 CA D2 4A+                cmp     dword_4AD2CAC4, 0
.text:4AD1B300 74 34                             jz      short loc_4AD1B336

......  fill this with NOPS ( byte value 0x90 ):
.text:4AD1B302 68 28 23 00 00                    push    2328h     ; "NY"
.text:4AD1B307 68 7B 23 00 00                    push    237Bh     ; "Terminate batch job (Y/N)? "
.text:4AD1B30C 6A 00                             push    0
.text:4AD1B30E E8 2D 03 00 00                    call    sub_4AD1B640
.text:4AD1B313 83 F8 01                          cmp     eax, 1
.text:4AD1B316 0F 85 11 7B FE FF                 jnz     sub_4AD02E2D

.text:4AD1B31C 56                                push    esi
.text:4AD1B31D 8B 35 C4 CA D2 4A                 mov     esi, dword_4AD2CAC4
.text:4AD1B323 EB 0C                             jmp     short loc_4AD1B331
the offsets displayed here are dependend on the exact os version, this is winxp.

You may have some trouble replacing cmd.exe because of the "Windows File Protection". What I do, is put it in a different location, and put that in my COMSPEC environment variable.

improving filename completion

in the function
, at offset 110FEh, where ctrl-c is checked, i added a jump to my patch. the patch itself is located at the end of the import descriptors, where there were a few bytes unused still.

assemble the following piece of assembly code using Microsoft Macro assembler ( ml.exe ), then use a hexeditor to copy over the bytes from the resulting .obj, and patch them back into cmd.exe

; this changes cmd.exe, such that filename completion no longer
;    checks the old dos filenames.
;  such that when a dir contains '.config'  and 'config.h'
;  trying to complete 'con'   will not result in .config

; these are the actual patches:
; 4AD110FE
; 4AD205C0
; fileofs 000001d8 .text(vsize) :=   0001f600

.model flat

org 110FEh
   jmp  my_patch

org 111C5h

org 1110Ah

org  205c0h
; eax = free to use
; ebx == 0
; ecx = free to use
; edx = free to use
; esi = ptr to list object
; edi = ptr to listitem
    mov eax, [ebp-224h]     ; p_wildcard
    mov ecx, [eax]
    lea edx, [edi+30h]      ; +struct_listitem.fd.cFilename
    mov ax, word ptr [ecx]
    cmp ax, '*'
    jz  continue
    cmp ax, 0
    jz continue
    xor ax, word ptr [edx]
    and ax, not 20h
    jnz try_next
    add edx, 2
    add ecx, 2
    jmp @@loop


fix 'dir /s' aborts on error

todo: fix bug in "dir /s", where it aborts when it encounters an error. for instance when listing files from a network mounted non-windows disk

add feature to change \ to / in commandline

this is not yet complete
4AD0BA6B ReadConsole is where cmd.exe is when waiting for input
-> so we need to change the kernel, instead of cmd.exe
-> kernel forwards call to rpc server in winsrv.dll ( which executes in csrss.exe )
nt4 source : ./nt4/private/ntos/w32/ntcon/server/stream.c
SrvReadConsole -> ReadChars -> CookedRead
-> GetChar
-> nt4/private/ntos/w32/ntcon/server/cmdline.c ProcessCommandLine : handles VK_ESCAPE, VK_UP, etc .. all editting keys
-> ProcessCookedReadInput
rpc call is through:
-> nt4/private/csr/server
filename completion is handled in cmd.exe, ReadConsole returns a 'dwControlKeyState' and then calls 'DoComplete' so, either i add 'ctrl-\' and handle /-\ translation in cmd.exe in DoComplete or i do this in winsrv.dll, where 'VK_F8' etc is handled.