Ошибка базы изображений в Delphi EXE - PullRequest
0 голосов
/ 03 января 2012

Я пишу обертку EXE (своего рода упаковщик), чтобы защитить мой EXE, и, в свою очередь, он будет запущен непосредственно в память.В приведенном ниже примере показано выполнение калькулятора в памяти.

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
begin
  FS := TFileStream.Create('calc.exe', fmOpenRead or fmShareDenyNone);
  SetLength(eu, FS.Size);
  FS.Read(eu[0], FS.Size);
  FS.Free;
  SInfo.cb := Sizeof(TStartupInfo);
  CreateProcess(nil, Pchar(paramstr(0)), nil, nil, FALSE, CREATE_SUSPENDED, nil,
    nil, SInfo, PInfo);
  IDH := @eu[0];
  INH := @eu[IDH^._lfanew];
  imgbase := DWORD(VirtualAllocEx(PInfo.hProcess,
    Ptr(INH^.OptionalHeader.ImageBase), INH^.OptionalHeader.SizeOfImage,
    MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE));
  ShowMessage(IntToHex(imgbase, 8));
  WriteProcessMemory(PInfo.hProcess, Ptr(imgbase), @eu[0],
    INH^.OptionalHeader.SizeOfHeaders, SIZE_T(btsIO));
  for i := 0 to INH^.FileHeader.NumberOfSections - 1 do
  begin
    ISH := @eu[IDH^._lfanew + Sizeof(TImageNtHeaders) + i *
      Sizeof(TImageSectionHeader)];
    WriteProcessMemory(PInfo.hProcess, Ptr(imgbase + ISH^.VirtualAddress),
      @eu[ISH^.PointerToRawData], ISH^.SizeOfRawData, SIZE_T(btsIO));
  end;
  CONT.ContextFlags := CONTEXT_FULL;
  GetThreadContext(PInfo.hThread, CONT);
  CONT.Eax := imgbase + INH^.OptionalHeader.AddressOfEntryPoint;
  WriteProcessMemory(PInfo.hProcess, Ptr(CONT.Ebx + 8), @imgbase, 4,
    SIZE_T(btsIO));
  ShowMessage('Press ok on ENTER');
  SetThreadContext(PInfo.hThread, CONT);
  ResumeThread(PInfo.hThread);
  CloseHandle(PInfo.hThread);
  CloseHandle(PInfo.hProcess);
end;

Я изменил код, добавив дополнительный ресурс.На данный момент, к моему удивлению, база изображений становится нулевой!

    {$R *.dfm}
    {$R test.res}  //extra resourse added

        procedure TForm1.Button1Click(Sender: TObject);
        var
          i: Integer;
        begin
          FS := TFileStream.Create('calc.exe', fmOpenRead or fmShareDenyNone);
          SetLength(eu, FS.Size);
          FS.Read(eu[0], FS.Size);
          FS.Free;
          SInfo.cb := Sizeof(TStartupInfo);
          CreateProcess(nil, Pchar(paramstr(0)), nil, nil, FALSE, CREATE_SUSPENDED, nil,
            nil, SInfo, PInfo);
          IDH := @eu[0];
          INH := @eu[IDH^._lfanew];
          imgbase := DWORD(VirtualAllocEx(PInfo.hProcess,
            Ptr(INH^.OptionalHeader.ImageBase), INH^.OptionalHeader.SizeOfImage,
            MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE));
          ShowMessage(IntToHex(imgbase, 8));
.....
.....
  • В первом примере я получил Imagebase = 01000000 (код работает отлично)
  • Во втором примере (где я добавил дополнительный ресурс в свой проект) яполучение Imagebase = 00000000 (код не выполняется ..)

Может ли кто-нибудь объяснить, почему это так? ..

1 Ответ

3 голосов
/ 04 января 2012

Это просто удача, что вы сработали в первый раз: lpStartupInfo - это параметр in для CreateProcess, вы должны инициализировать его члены:

..
FillChar(SInfo, SizeOf(SInfo), 0);
SInfo.cb := Sizeof(TStartupInfo);
CreateProcess(...
..
...