Delphi EXE中的Imagebase错误

时间:2012-01-03 18:34:42

标签: delphi delphi-xe2

我正在编写一个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;

我更改了代码以包含额外资源。在这一点上,令我惊讶的是,Imagebase变为零!

    {$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 个答案:

答案 0 :(得分:3)

祝你好运,你第一次使用它:lpStartupInfo是<{em> in 参数CreateProcess,你必须初始化其成员:

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