#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>

void main( VOID )

{

	STARTUPINFO 			si;
    PROCESS_INFORMATION 	pi;

//  Gate (event) condition 2nd layer EP address
	DWORD       GateAddress[] = {0x00807593};

//  Gate (event) condition 2nd layer EP search byte
	BYTE	    gatebyte[] = {0x55};

//  Note the patch info below is for demonstration purposes only
//  Patch Address info: # elements in following arrays must be syncronized for Address/scan/replace
	DWORD 		AddressOfPatch[] = {0x0072FD28, 0x0072FD29}; //...etc..etc..
//  Patch byte info:
//  Search (read) byte
	BYTE 		scanbyte[] = {0x8B, 0xF9}; //...etc..etc..
//  Found  (write) byte
	BYTE        replbyte[] = {0xE9, 0x92}; //...etc..etc..

	BYTE 		DataRead[] = {0};
	char 		FileName[] = "Target.exe";
	char		b[1024] = " ";
	BOOL		gatefound;
	DWORD		nPatches;
	DWORD		dwRead;
	DWORD		dwWritten;
	unsigned 	int i;

	ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);
    ZeroMemory( &pi, sizeof(pi) );

	// Start the child process.
    if(!CreateProcess( FileName, // If No module name (then use command line).
        NULL, 				// Command line.
        NULL,             	// Process handle not inheritable.
        NULL,             	// Thread handle not inheritable.
        FALSE,            	// Set handle inheritance to FALSE.
        NORMAL_PRIORITY_CLASS,     	// creation flags.
        NULL,             	// Use parent's environment block.
        NULL,             	// Use parent's starting directory.
        &si,              	// Pointer to STARTUPINFO structure.
        &pi ))             	// Pointer to PROCESS_INFORMATION structure.

 	{
		MessageBox(0,"Unexpected load error","Create Process Failed",MB_OK+MB_TASKMODAL+MB_ICONERROR);
		return;
	}

	WaitForInputIdle(
		pi.hProcess,
		1000		//initial time out value (1 second) can be adjusted as required!!
	);

	gatefound = FALSE;

	while (!gatefound)

	{

	SuspendThread(
	    pi.hThread 		// handle to the thread
   	);

	// Test for existence of EP byte in memory address
	ReadProcessMemory(pi.hProcess, (LPVOID) GateAddress[0], DataRead,
		sizeof(BYTE), &dwRead);

	// if found; then continue.
	if(DataRead[0] == gatebyte[0])
	{
		gatefound = TRUE;

		// apply the patches to the *.exe
		// Calculate number of patches / addresses
    	nPatches = sizeof(AddressOfPatch) / sizeof(AddressOfPatch[0]);

		for ( i = 0; i < nPatches; i++ )
		{

			ReadProcessMemory(pi.hProcess, (LPVOID) AddressOfPatch[i], DataRead,
				sizeof(BYTE), &dwRead);

			if(DataRead[0] == scanbyte[i])
			{
				WriteProcessMemory (pi.hProcess, (LPVOID) AddressOfPatch[i], &replbyte[i],
					sizeof(BYTE), &dwWritten);
				//sprintf( b, "address:%08X", AddressOfPatch[i]);
				//MessageBox(0, b,"Patch applied",MB_OK+MB_TASKMODAL+MB_ICONINFORMATION);
			}

		}

		//we are done. get out!!
		ResumeThread(
    		pi.hThread 		// identifies thread to restart
		);

		break;

	}

	else

	{
		gatefound = FALSE;
	}

	ResumeThread(
    	pi.hThread 		// identifies thread to restart
   	);

	Sleep (100);    //sleep for 1/10 second; can be adjusted as required

	}//end while

	// Close process and thread handles.
    CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );

	ExitProcess(0);

	return;

	}

