;***************************************************************************
;                                YAIP
;               Yet Another (pseudoIntelligent!!!) Patcher
;                     Written by Oskar Nurb, 14-4-97
;                        oskar_nurb@nym.alias.net
;       
;  GREETZ: +ORC, +Gthorne, Fravia+ and all the readers of RevEngE
;
;  Please improve and expread this program. I consider I must learn a lot
;  before making good software... I'm on the commercial standards now! :)
;
;  Yeah, I can see your faces... You are surely thinking: Another patcher?
;  Yes, but this patcher is written in ASM, and it isn't based on the file
;  offset method that most pathers out there use. It searches and patches.
;  There is a BIG difference between both metods. Using this code you crack
;  several versions of a program :)
;
;  As it is written in ASM, you can generate a .COM and encrypt it as you
;  wish. Or you can just build a C program that uses this code.
;
;  Enjoy!
;
;***************************************************************************

                .286
		.model small
		.code
                org 100h

bufsize equ     20000
CR      equ     0dh
LF      equ     0ah

; As usual, some directives.


start:
        push    cs
        pop     ds
        mov     ax,3d02h
        mov     dx,offset fname
        int     21h

; Please chech HelpPc for a refference if you are a newbye.

        jc      Erroropening
        mov     word ptr cs:[Fhandle],ax
        jmp     prinbuc

; I love to write odd modules :)
; Why can't you see any procs? Because I wrote this in order to
; be heavily compiler-encrypted... And I thought it would be a
; mess otherwise.

Erroropening:
        mov     dx,offset eamsg
        mov     ah,09
        int     21h

; Don't you think I'm a very user-friendly programmer?

        mov     ah,4ch
        int     21h


; Here starts the search engine. You only have to put that
; search string in little bytes. Or even better, you can
; write a function that only needs a string as arg.

;All the jc stuff is there in order to left the read proc
;as free as possible. If you don't like it, just modify it.
;I personally don't care.

searchbuc:
        call    read
        jc      finalox
prinbuc:
        cmp     ah,54h
        jne     searchbuc
        call    read
        jc      finalox
        cmp     ah,75h
        jne     prinbuc
        call    read
        jc      finalox
        cmp     ah,72h
        jne     prinbuc
        call    read
        jc      finalox
        cmp     ah,62h
        jne     prinbuc

;Bingo. If you are here, you've found the match.

;Let's take our File Pointer

        mov     ax,4201h
        mov     bx,word ptr cs:[Fhandle]
        mov     cx,0
        mov     dx,0
        int     21h

;Let's manage it to point the start of string.

        mov     bx,word ptr cs:[Fhandle]
        mov     cx,dx
        mov     dx,ax
        sub     dx,word ptr cs:[Inbuf]
        add     dx,word ptr cs:[readed]
        sub     dx,3
        mov     ax,4200h
        int     21h

;Let's write the patch

        mov     bx,word ptr cs:[Fhandle]
        mov     ah,40h
        mov     cx,3
        push    cs
        pop     ds
        mov     dx,offset wbuff
        int     21h


;Close file


        mov     bx,word ptr cs:[Fhandle]
        mov     ah,3eh
        int     21h

;Bye dear user!

        mov     dx,offset hecho
        mov     ah,09
        int     21h

        mov     ah,4ch
        int     21h

wbuff   db      90h,90h,90h
hecho   db      'OK!!$'

finalox:
        mov     ah,4ch
        int     21h

; This is our read function, with a little buffer, of course.
; It is free of internal weird/end jumps for easy modification
; pourposes. It just returns CF on EOF, and if not CF the next byte of the
; file (stream??) in AH. You can surely write it better, but, hey,
; I'm not a programmer! :)
; May be some day... :)

read:
        push    si
        mov     si,word ptr cs:[readed]
        cmp     si,word ptr cs:[Inbuf]
        jne     cont
        call    fullbuf
        jnc     cont
        pop     si
        stc
        ret
cont:
        clc
        mov     ah,byte ptr cs:[Buff+si]
        inc     word ptr cs:[readed]
        pop     si
        clc
        ret

fullbuf:
        mov     bx,word ptr cs:[Fhandle]
        mov     ah,3fh
        mov     cx,bufsize
        push    cs
        pop     ds
        mov     dx,offset Buff
        int     21h
        jc      error
        cmp     ax,0
        je      error
        mov     word ptr cs:[Inbuf],ax
        mov     word ptr cs:[readed],0
        clc
        ret
error:
        stc
        ret


fname   db      'test.exe',0
eamsg   db      'Error opening file',CR,LF,'$'

readed  dw      0
Fhandle dw      ?
Inbuf   dw      ?
Buff    dw      bufsize dup(?)

end start