This is a tool I made with FASM that allows users to place a copy write on any COM file specified. The default copy write is set to FreeDOS, but you can edit the source to put what ever you like! I suppose this could also be done for patching programs, just along as your code is adjusted to the new offset.
org 100h
mov bx, 82h ; all command line parameters are saved to offset 82h in the PSP
mov di, filen
mov ah, 1ah
mov dx, hide_dta
int 21h
start: ; routine for receiving CMD line parameters
cmp byte[bx], 0dh
jz done
cmp byte[bx], 0
jz serror
cont:
mov al, [bx]
stosb
inc bx
jmp start
serror:
mov ah, 09h
mov dx, emsg
int 21h
int 20h
emsg db "Syntax: stub <filename>$"
error:
mov ah, 09h
mov dx, emsg2
int 21h
int 20h
emsg2 db "File not found$"
done: ; file is found!
mov ah, 4eh ;find first matching file (direct 3d02h messes up)
mov dx, filen ; file found earlier
xor cx, cx ; write/read only!
int 21h
jc error
mov ax, 3d02h
lea dx, [hide_dta+1eh] ; file name in the new DTA placed after the code
int 21h
jc error
xchg ax, bx
mov ah, 3fh ; lets read the initial 3 bytes
mov dx, bytes
mov cx, 3
int 21h
check:
mov ax, word [hide_dta+1ah]
mov cx, word [bytes+1]
add cx, vend-vstart+3
cmp ax, cx ; is the jump/size equal to our program plus the other
jz alinf ; if so, then the file is already changed
newoffs:
sub ax, 3 ; you must subtract 3 from the size (see note after code)
mov word [newjump+1], ax ; put new offset after first byte
mov ax, 4200h
xor cx, cx
cwd ; convert word(CX) to double word (CX) (DX) therefore xoring both
int 21h
mov ah, 40h ; write our jump
mov dx, newjump
mov cx, 3
int 21h
mov ax, 4202h
xor cx, cx
cwd
int 21h
mov ah, 40h ;write our program
mov dx, vstart
mov cx, vsize
int 21h
mov ah, 3eh
int 21h
success:
mov ah, 09h ; were we successful? if so then print it!
mov dx, smsg
int 21h
int 20h
alinf:
mov ah, 09h ; all files have been patched!
mov dx, fmsg
int 21h
int 20h
smsg db "File successfully copyrighted$"
fmsg db "File already copyrighted$"
newjump db 0e9h, 0, 0 ; 0e9h = jmp short
filen db 20 dup (0) ; 20 byte buffer for file name
vsize = vend-vstart ; size of our patch
vstart:
call begin ; obtains BP
begin:
pop bp ; pops BP
sub bp, begin ; adjusts BP to current offset
restore:
mov di, 100h ; beginning of the COM file
lea si, [bp+bytes] ; restore the bytes saved
push di ; save it for the jump later on
movsw ; move 3 bytes total (jmp = 3 bytes)
movsb
display_msg: ; let's do what we need to
mov ah, 09h
lea dx, [bp+msg]
int 21h
return:
ret
bytes db 0cdh, 20h, 0
msg db "DOSemu 1.4.0.0 FreeDOS(C) Copyright 1995-2006", 0ah, '$'
vend:
hide_dta db 42 dup (?)