分享

【Delphi】内存加载并运行EXE程序

 quasiceo 2012-12-13

【Delphi】内存加载并运行EXE程序

Unit MemoryRunUnitTwo;
  
interface
  
{$IMAGEBASE $10000000}
  
uses
   Windows;
  
type
   TSections = array [0..0] of TImageSectionHeader;
  
procedure MemoryRunExe(FileMemory: Pointer);
  
implementation
  
function GetAlignedSize(Size: dword; Alignment: dword): dword;
begin
   if ((Size mod Alignment) = 0) then
   begin
     Result := Size;
   end
   else
   begin
     Result := ((Size div Alignment) + 1) * Alignment;
   end;
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 MemoryRunExe(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;
  
end.
  
{
写了一个简单程序测试通过:)
}
program Test1;
  
//{$APPTYPE CONSOLE}

uses
   SysUtils,
   Classes,
   MemoryRunUnitTwo in 'MemoryRunUnitTwo.pas';
  
var
     ABuffer: array of byte;
     Stream: TFileStream;
     ProcessId: Cardinal;
begin
     Stream := TFileStream.Create('HT.exe', fmOpenRead);
     try
         SetLength(ABuffer, Stream.Size);
         Stream.ReadBuffer(ABuffer[0], Stream.Size);
         MemoryRunExe(@ABuffer[0]);
     finally
         Stream.Free;
     end;
end.

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多