Execute from stream

just write whatever you want
Post Reply
ThievingSix
Posts: 5
Joined: Tue Sep 11, 2007 2:37 am
Location: Southern California
Contact:

Execute from stream

Post by ThievingSix »

Ok madshi, this doesn't really relate to your software but maybe you can help anyway.

@ciuly, if your the same person on EE then congrats I found this piece of code from your link.

Ok, I'm trying to load a executable from a .res file, load it to a memory stream and execute it.

Code: Select all

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;
and that said is gotten from : http://www.experts-exchange.com/Program ... l#14731515

Now, I understand how it works but I'm unsure how it relates to a couple of things. For starters the executable is a 30mb game. When I leave the MAX stack size in the linker properties normal the run program crashes with a Microsoft send, don't send dialog. I change that stack size to a much larger number, and I get no crash just a silent exit.

Any ideas?
ThievingSix
Posts: 5
Joined: Tue Sep 11, 2007 2:37 am
Location: Southern California
Contact:

Post by ThievingSix »

Ok, I did end up fixing it myself.

Through dumb luck I was debugging and found out that some of the edits done to the EXE that I was trying to load, was done outside the file image addressed by the PE header. I used PE Editor to change the Image size that is to be included and it works. =P
Post Reply