.386 
.model flat,stdcall 
option casemap:none 

include		windows.inc 
include		user32.inc 
include		kernel32.inc 
includelib	user32.lib 
includelib	kernel32.lib 

DlgProc		proto		:DWORD,:DWORD,:DWORD,:DWORD
List		proto		:DWORD,:DWORD
Patch		proto		:DWORD
Scan		proto

.data 
TargetName	db		"SuperCleaner.exe",0
BackupName	db		"SuperCleaner.exe.bak",0
Sequence	db		75h,41h,0E8h,7Ah
SeqLen		db		4
WBuffer		db		0EBh,41h,0E8h,7Ah
PatchOffset	dd		2347Fh
StartNfo	db		"Place in same folder as target and click APPLY",0
Backup		db		"Backup made",0
Success		db		"Target patched successfully",0
Already		db		"Target already patched!",0
OpenError	db		"Unable to open target file",0
ReadError	db		"Error reading from target file",0
WriteError	db		"Error writing to target file",0
Version		db		"Incorrect target file version...",0
Searching	db		"Searching for byte sequence to patch...",0
NotFound	db		"Correct byte sequence not found",0
AboutTxt	db		"SuperCleaner 2.84 Patch",10,13
		db		"~Coded by Goppit~",10,13
		db		"Release Date 15/12/05",0
AboutCap	db		"NFO",0

.data? 
hInstance	HINSTANCE	?  
hTarget		HINSTANCE	?
hTargetMap	HINSTANCE	?
RBuffer		dd		?
BytesRead	db		?
BytesWritten	db		?
pMapView	dd		?
FileSize	dd		?
SearchOffset	dd		?

.const
IDD_PATCH	equ		1001
IDC_LISTBOX	equ		1002
IDC_APPLY	equ		1003
IDC_ABOUT	equ		1004
IDC_EXIT	equ		1005
IDC_CHECKBOX	equ		1006
ARIcon		equ		2002

.code 
start: 
    invoke GetModuleHandle, NULL 
    mov    hInstance,eax 
    invoke DialogBoxParam, hInstance, IDD_PATCH, NULL, addr DlgProc, NULL 
    invoke ExitProcess,eax 
    
DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM 
	.if uMsg==WM_INITDIALOG
		invoke LoadIcon,hInstance,ARIcon
		invoke SendMessage,hWnd,WM_SETICON,1,eax
		invoke List,hWnd,addr StartNfo
	.elseif uMsg==WM_COMMAND
		mov	eax,wParam
		.if eax==IDC_APPLY
			invoke Patch,hWnd
		.elseif eax==IDC_ABOUT 
			invoke MessageBox,hWnd,addr AboutTxt,addr AboutCap,MB_ICONINFORMATION
		.elseif eax==IDC_EXIT 
			invoke SendMessage,hWnd,WM_CLOSE,0,0
		.endif
	.elseif	uMsg==WM_CLOSE
		invoke	EndDialog,hWnd,0
	.endif
    xor	eax,eax
    ret 
DlgProc endp 

List proc hWnd:HWND, pMsg:DWORD
	invoke SendDlgItemMessage,hWnd,IDC_LISTBOX,LB_ADDSTRING,0,pMsg 
	invoke SendDlgItemMessage,hWnd,IDC_LISTBOX,WM_VSCROLL,SB_BOTTOM,0
	Ret
List EndP

Patch proc hWnd:HWND
	invoke GetFileAttributes,addr TargetName
	.if eax!=FILE_ATTRIBUTE_NORMAL
		invoke SetFileAttributes,addr TargetName,FILE_ATTRIBUTE_NORMAL
	.endif
	invoke CreateFile,addr TargetName,\
					GENERIC_READ+GENERIC_WRITE,\
					FILE_SHARE_READ+FILE_SHARE_WRITE,\
					NULL,\
					OPEN_EXISTING,\
					FILE_ATTRIBUTE_NORMAL,\
					NULL
	.if eax!=INVALID_HANDLE_VALUE
		mov hTarget,eax
		invoke SendDlgItemMessage, hWnd, IDC_CHECKBOX, BM_GETCHECK, 0, 0
		.if eax==BST_CHECKED
			invoke CopyFile, addr TargetName, addr BackupName, TRUE
			invoke List,hWnd,addr Backup
		.endif
		invoke SetFilePointer,hTarget,PatchOffset,NULL,FILE_BEGIN
		invoke ReadFile,hTarget,addr RBuffer,4,addr BytesRead,NULL
		.if BytesRead==4
			mov eax,dword ptr [RBuffer]
			.if eax==dword ptr [Sequence]
				invoke SetFilePointer,hTarget,PatchOffset,NULL,FILE_BEGIN
				jmp @WRITE
			.elseif eax==dword ptr [WBuffer]
				invoke List,hWnd,addr Already
			.else
				invoke List,hWnd,addr Version
				invoke List,hWnd,addr Searching
				invoke Scan
				.if eax==0
					invoke List,hWnd,addr NotFound
				.else
					invoke SetFilePointer,hTarget,eax,NULL,FILE_BEGIN
					jmp @WRITE
				.endif
			.endif
		.else
			invoke List,hWnd,addr ReadError
		.endif
	.else
		invoke List,hWnd,addr OpenError
	.endif
	invoke CloseHandle,hTarget
	Ret
	
	@WRITE:
		invoke WriteFile,hTarget,addr WBuffer,1,addr BytesWritten,NULL
		.if BytesWritten==1
			invoke List,hWnd,addr Success
		.else
			invoke List,hWnd,addr WriteError
		.endif
		Ret
Patch EndP

Scan proc	;returns offset of byte sequence in eax
	LOCAL ReturnValue	:DWORD
	mov ReturnValue,0
	invoke GetFileSize,hTarget,NULL
	mov FileSize,eax
	invoke CreateFileMapping,hTarget,NULL,PAGE_READWRITE,0,0,NULL
	mov hTargetMap,eax
	invoke MapViewOfFile,eax,FILE_MAP_WRITE,0,0,0
	mov pMapView,eax
	mov edi,pMapView
	mov ecx,FileSize
	mov esi,offset Sequence
	xor eax,eax
	mov al,byte ptr [esi]
	
	@@:	repnz scasb
		cmp ecx,0
		jz @NOTFOUND
		push ecx
		push esi
		push edi
		dec edi
		mov ecx,4
		repz cmpsb 
		cmp ecx,0
		jz @FOUND
		pop edi
		pop esi
		pop ecx
		jmp @b
	
	@FOUND:
		pop edi
		pop esi
		pop ecx
		inc ecx
		mov eax,FileSize
		sub eax,ecx
		mov ReturnValue,eax
		jmp @RETURN
	
	@NOTFOUND:
		mov ReturnValue,0
		jmp @RETURN
	
	@RETURN:
		invoke UnmapViewOfFile,pMapView
		invoke CloseHandle,hTargetMap
		mov eax,ReturnValue
		Ret
Scan EndP

end start