firstret=0x0040755D;
lib="kernel32.dll";
func="GetModuleHandleA";

oepbreaks=1;
lethalbreaks=5;
unhookarray={};

function UnhookArrayList()
	ClearUnhookList();
	local z=1;
	while true do
		if unhookarray[z]==nil then
			break;
		end;
		AddModuleToUnhookList(unhookarray[z]);
		z=z+1;
	end;
end;

function StartProcessInternal()
	UnhookArrayList();
	Start(false);
	local breaksatoep=0;
	unhook_inaction=true;
	bbreak=GetProcAddress(lib,func);
	AddBreak(bbreak,1,0); EnableBreak(bbreak);
	while true do
		Continue(true);
		if break_where==bbreak then
			if ReadMem(ESP,4)==firstret then
				breaksatoep=breaksatoep+1;
				if breaksatoep==oepbreaks then
					break;
				else
					TraceAndReplace(EIP);
				end;
			else
				TraceAndReplace(bbreak);
			end;
		elseif break_where==0xf00 then
			break;
		end;
	end;
	unhook_inaction=false;
end;

function StartProcess()
	local oepcounter=0;
	while true do
		StartProcessInternal();
		if break_where==0xf00 then
			oepcounter=oepcounter+1;
			WriteEx(string.format("Died while starting process %u of %u",oepcounter,lethalbreaks),true,true,0x0000ff);
			if oepcounter==lethalbreaks then
				WriteEx("Lethally died while starting process",true,true,0x0000ff);
				return -1;
			end;
		else
			break;
		end;
	end;
	SuspendAllOther();
--	WriteMem(0x7c97c0dc,0xffffffff,4);
	return 0;
end;

if is_dll==true and process_relocs==true then
	if StartProcess()==-1 then
		return -1;
	end;
	DumpForRelocs();
	Terminate();
end;

if StartProcess()==-1 then
	return -1;
end;
Dump();
if cut_sections==true then
	ProcessResources();
	CutSections();
	ProcessExport();
	ProcessTLS();
end;
ProcessDelphiInit();
RestoreImportRelocs();
if cut_sections==true then
	SaveResources();
end;
ProcessOverlay();
SaveFile();
Terminate();