.386 
.model flat,stdcall 
option casemap:none 

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

.data? 
ThreadContext		CONTEXT			<>
StartupInfo		STARTUPINFO		<>
ProcessInfo		PROCESS_INFORMATION	<>
StopBuffer		dw			?
ReadBuffer		dd			?
Buffer			dd			?

.data 
TargetName		db			"SuperCleaner.exe",0
ProcError		db			"Error starting target process. Is loader in same folder as target!",0
ReadError		db			"Error reading from target process",0
Version			db			"Incorrect target file version!",0
WriteError		db			"Error writing to target process",0
ContextError		db 			"GetThreadContext failed. Target process terminated?",0
Sequence		db			75h,41h,0E8h,0BAh
StopVA			dd			004863ECh
OEPBytes		db			0E9h,0E9h
StopCode		db			0EBh,0FEh
PatchVA			dd			0042374Fh
PatchByte		db			0EBh

.code
start:
	invoke CreateProcess,addr TargetName,0,0,0,0,CREATE_SUSPENDED,0,0,addr StartupInfo,addr ProcessInfo
	.if eax==0
		invoke MessageBox,0,addr ProcError,0,0
	.else
		invoke ReadProcessMemory,ProcessInfo.hProcess,StopVA,addr StopBuffer,2,addr Buffer
		mov ax,word ptr [StopBuffer]
		.if ax==word ptr [OEPBytes]
			invoke WriteProcessMemory,ProcessInfo.hProcess,StopVA,addr StopCode,2,addr Buffer
			invoke ResumeThread,ProcessInfo.hThread
			invoke Sleep,10
			mov ThreadContext.ContextFlags,CONTEXT_FULL
@@:
			invoke GetThreadContext,ProcessInfo.hThread,addr ThreadContext
			.if eax==0
				invoke MessageBox,0,addr ContextError,0,0
				jmp @Error
			.else
				mov eax,StopVA
				.if eax==ThreadContext.regEip
					invoke SuspendThread,ProcessInfo.hThread
					invoke ReadProcessMemory,ProcessInfo.hProcess,PatchVA,addr ReadBuffer,4,addr Buffer
					mov eax,dword ptr [ReadBuffer]
					.if eax==dword ptr [Sequence]
						invoke WriteProcessMemory,ProcessInfo.hProcess,StopVA,addr OEPBytes,2,addr Buffer
						invoke WriteProcessMemory,ProcessInfo.hProcess,PatchVA,addr PatchByte,1,addr Buffer
						invoke ResumeThread,ProcessInfo.hThread
						jmp @Exit
					.else
						invoke MessageBox,0,addr Version,0,0
						jmp @Error
					.endif
				.else
					invoke Sleep,10
					jmp @b
				.endif
			.endif
		.else
			invoke MessageBox,0,addr Version,0,0
		.endif
@Error:
		invoke TerminateProcess,ProcessInfo.hProcess,0
	.endif
@Exit:	
	invoke ExitProcess,NULL
end start