;;---------------------------------------------------------------------------------
;;- Simple Offsetpatcher generated by COGEN II - WIN 32 PATCH GENERATOR (C) by tE -
;;---------------------------------------------------------------------------------

.386
.MODEL FLAT,STDCALL
locals
jumps
UNICODE=0
BOOL			typedef DWORD		;boolean variable
NULL			equ	0		;null
FALSE			equ	0		;boolean false
TRUE			equ	1		;boolean true
PAGE_READWRITE		equ	00000004h
MEM_COMMIT		equ	00001000h
MEM_DECOMMIT		equ	00004000h
WM_SETICON		equ	0080h
WM_INITDIALOG		equ	0110h
WM_COMMAND		equ	0111h
HWND			typedef	DWORD		;window handle
UINT			typedef	DWORD		;unsigned integer
WPARAM			typedef	DWORD		;word parameter
WM_CLOSE		equ	0010h
WM_DESTROY		equ	0002h
HANDLE			typedef DWORD		;unspecified handle
LPCSTR			typedef DWORD		;long ptr to string
LPARAM			typedef	DWORD		;long parameter
LPDWORD			typedef	DWORD		;long ptr to dword
LPVOID			typedef	DWORD		;long ptr to buffer
LPCVOID			typedef	DWORD		;long ptr to buffer
LPDWORD			typedef	DWORD		;long ptr to dword
OVERLAPPED		STRUCT
Internal		DWORD	?
InternalHigh		DWORD	?
_Offset			DWORD	?
OffsetHigh		DWORD	?
hEvent			HANDLE	?
OVERLAPPED		ENDS
LPOVERLAPPED		TYPEDEF	PTR OVERLAPPED
HINSTANCE		typedef	DWORD		;instance handle
LPSECURITY_ATTRIBUTES	TYPEDEF	PTR SECURITY_ATTRIBUTES

SECURITY_ATTRIBUTES_	equ	  4+4+4
SECURITY_ATTRIBUTES	struct
sa_nLength		DWORD	  SECURITY_ATTRIBUTES_ ;structure size
sa_lpSecurityDescriptor	LPVOID	  0		;security descriptor
sa_bInheritHandle	BOOL	  FALSE		;handle inheritance flag
SECURITY_ATTRIBUTES	ends

VirtualAlloc		PROCDESC	WINAPI	:LPVOID, :DWORD, :DWORD, :DWORD
VirtualFree		PROCDESC	WINAPI	:LPVOID, :DWORD, :DWORD
SetWindowTextA		PROCDESC	WINAPI	:HWND, :LPCSTR
MessageBoxA		PROCDESC	WINAPI	:HWND, :LPCSTR, :LPCSTR, :UINT
DialogBoxParamA		PROCDESC	WINAPI	:HINSTANCE, :LPCSTR, :HWND, :DWORD, :LPARAM
SetDlgItemTextA		PROCDESC	WINAPI	:HWND, :SDWORD, :LPCSTR
EndDialog		PROCDESC	WINAPI	:HWND, :UINT
ExitProcess		PROCDESC	WINAPI	:DWORD
GetFileSize		PROCDESC	WINAPI	:HANDLE, :LPDWORD
WriteFile		PROCDESC	WINAPI	:HANDLE, :LPCVOID, :DWORD, :LPDWORD, :LPOVERLAPPED
ReadFile		PROCDESC	WINAPI	:HANDLE, :LPVOID, :DWORD, :LPDWORD, :LPOVERLAPPED
CloseHandle		PROCDESC	WINAPI	:HANDLE
SetFilePointer		PROCDESC	WINAPI	:HANDLE, :DWORD, :LPDWORD, :DWORD
CreateFileA		PROCDESC	WINAPI	:LPCSTR, :DWORD, :DWORD,\
					:LPSECURITY_ATTRIBUTES,\
					:DWORD, :DWORD, :HANDLE
GetModuleHandleA	PROCDESC	WINAPI	:DWORD
LoadIconA		PROCDESC	WINAPI	:HINSTANCE, :LPCSTR
SendMessageA		PROCDESC	WINAPI	:HWND, :UINT, :WPARAM, :LPARAM




.DATA
;-------------------------------------------------------------------------------------
;########### CHANGE FILENAME, WINTITLE AND INTRO MESSAGE - THAT'S ALL! ###############
;-------------------------------------------------------------------------------------
include lstpatch.inc

err_cap  	db "ERROR!",0
openerr	 	db "CAN'T OPEN FILE!",0
memerr	 	db "NOT ENOUGH MEMORY!",0
readerr		db "READ ERROR!",0
byterr   	db "FILE DOES NOT MATCH OR IS ALREADY PATCHED!",0
writeerr	db "WRITE ERROR!",0
readycap 	db "GREAT!",0
readytxt 	db "FILE PATCHED! HAVE FUN.",0
fsizerr		db "COULDN'T GET FILESIZE - ABORTING!",0

;+---------------------------------------------------------------------------------------+

ICON_SMALL		equ	0
PATCH_ICON              equ     101
DLG_MAIN                equ     103
TEXT_OUT                equ     1001
BTN_CRACK               equ     1007
BTN_EXIT                equ     1008
FILE_ATTRIBUTE_NORMAL	equ 	80h
OPEN_EXISTING		equ 	3
GENERIC_READ		equ 	80000000h
GENERIC_WRITE		equ 	40000000h
len		 	equ	bpatch-borig

hicon		dd 0
hinst_          dd 0
ccnt		dd 0
fhandle  	dd 0
fsize	 	dd 0
memptr	 	dd 0
bread    	dd 0
bwrite   	dd 0

.CODE
Start:	call	GetModuleHandleA, NULL
	test	eax, eax
	jne	gmhok	
	push	large 0
	call	ExitProcess
gmhok:  mov	hinst_, eax
	call	DialogBoxParamA, hinst_, DLG_MAIN, 0, offset DlgProcedure, 0
	push	large 0
	call	ExitProcess
PUBLIC DlgProcedure
DlgProcedure 	PROC STDCALL, hwnd_:DWORD, wmsg:DWORD, wparam_:DWORD, lparam_:DWORD
		USES ebx, edi, esi
	xor	eax, eax
	mov 	ax, word ptr [wmsg]
	cmp	ax, WM_DESTROY
	je	wmdestroy
	cmp	ax, WM_CLOSE
	je	wmdestroy
	cmp	ax, WM_COMMAND
	je	wmcommand
	cmp	ax, WM_INITDIALOG
	je	dlginit
	xor	eax, eax
	RET
wmdestroy:
	call	EndDialog, hwnd_, 0
	push	large 0
	call	ExitProcess

wmcommand:
	xor	ebx, ebx
	mov	eax, dword ptr [wparam_]
	cmp	eax, BTN_CRACK
	je	PatchGo
	cmp	eax, BTN_EXIT
	je	wmdestroy
	RET
dlginit:
	call	LoadIconA, hinst_, PATCH_ICON
	test	eax, eax
	je	@@ierr
	mov	hicon, eax
	call	SendMessageA, hwnd_, WM_SETICON, ICON_SMALL, hicon
@@ierr:
	call	SetWindowTextA, hwnd_, offset wintitle
	call	SetDlgItemTextA, hwnd_, TEXT_OUT, offset intro
	test	eax, eax
	je	wmdestroy
	RET
DlgProcedure ENDP

DisplayError 	PROC NEAR
	Call	MessageBoxA, hwnd_, eax, offset err_cap, 10h
	RET
DisplayError 	ENDP

DisplaySuccess 	PROC NEAR
	Call	MessageBoxA, hwnd_, eax, offset readycap, NULL
	RET
DisplaySuccess 	ENDP

; Patch-Routine works as follows:
; Open File
; Get File Size
; Alloc Memory 
; Read whole File into Mem (don't kill me for this... of course i know about file-mapping, but...who cares ? :-])
; Compare original values at specific offsets
; Write Patched values into file
; Free Memory
; Close File
; Exit
;------ feel free to use and/or change this code until it meets your needs :-] ------

PatchGo:
        Call 	CreateFileA, offset file, GENERIC_READ + GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0
	mov  	fhandle, eax
	inc	eax
	jnz	ffound
	lea	eax, openerr
	Call	DisplayError
	jmp  	theend	
ffound:
	Call	GetFileSize, fhandle, NULL
	mov  	fsize, eax
	inc	eax
	jne	@@gso
	lea	eax, fsizerr
	call	DisplayError
	jmp	ech
@@gso:	call	VirtualAlloc, NULL, fsize, MEM_COMMIT, PAGE_READWRITE
	mov  	memptr, eax
	test  	eax, eax
	jnz  	mem_ok
	lea	eax, memerr
	Call	DisplayError
        jmp  	ech
mem_ok:
	call 	ReadFile, fhandle, memptr, fsize, offset bread, 0
	test	eax, eax
	jne	read_ok
	lea	eax, readerr
	Call	DisplayError
	jmp	eka
read_ok:
        mov  	ecx, len
	xor	ebx, ebx
lo:
        mov  	edi, memptr
	mov	edx, [offse+ebx*4]
	add	edi, edx
	
        lea  	esi, borig
        mov  	al, byte ptr [esi+ebx]

	cmp	al, byte ptr [edi]
	jne	nfound
	inc	ebx
	dec	ecx
	je	wlop
	jmp	lo
wlop:	
	mov	ebx, ccnt
	mov	edx, [offse+ebx*4]
        call 	SetFilePointer, fhandle, edx, 0, 0
	inc	eax
	je	write_error
	lea	esi, bpatch
	add	esi, ccnt
        Call 	WriteFile, fhandle, esi, 1, offset bwrite, 0
	test	eax,eax
	je	write_error
	inc	ccnt
	mov	ebx, ccnt
	sub	ebx, len
	jne	wlop
	lea	eax, readytxt
	Call	DisplaySuccess
        jmp  	eka
write_error:
	lea	eax,writeerr
	Call	DisplayError
       	jmp	eka
nfound:
	lea	eax, byterr
	Call	DisplayError
eka:
	call	VirtualFree, memptr, fsize, MEM_DECOMMIT
ech:
	call 	CloseHandle, fhandle
theend:
	jmp	wmdestroy
ends
end Start
