2012-01-03 12 views
-1

EXEを保護するためにEXEラッパー(パッカーの一種)を作成していますが、これがメモリに直接実行されます。以下のサンプルはCalculatorをメモリに実行している様子を示しています。Delphi 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(コードを取得しています(私は私のプロジェクトに余分なリソース教材を追加しました)2番目の例では
  • ました)..

誰でも私はそれなぜそうですか教えてください。

+2

あなたがメモリから実行するとであることを認識していますサポートされていません? –

+2

あなたのコメントのためにDavidに感謝します。 私が知る限り、合法で許可されています。 UPXが圧縮されたexeをどのように実行しているかを見てください。まず、元のコードがメモリに解凍されてから実行されます。これは、有名なexeパッカーのほとんどに当てはまります。 ASPackも同じことをしますが、UPXのクラッカーよりもはるかに優れた暗号化と保護メカニズムを備えています。ここでは悪質なコードを実行しようとしているのではなく、UPXやASPackとまったく同じように動作する正当なラッパーを作成しようとしています。これにより、より良い方法でシナリオが明確になることを願っています。 – jimsweb

+2

まあ、私の主張は、MSがメモリから画像を読み込むことをサポートしていないことと、将来のリリースやOSアップデートの中で壊れる可能性があるコードだということだけです。なぜあなたはこれをやりたいのか理解しています。私はあなたがそれを行うことができないということを知っていることを確認したかっただけです。 –

答えて

3

それはあなたがそれが丸い初めての作業持っている純粋な運です:lpStartupInfoCreateProcessからパラメータでで、あなたはそのメンバーを初期化する必要があります。

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

感謝のSertac。それは問題を解決しませんでした。 – jimsweb

+1

同様に、createprocessの戻り値は何ですか? winapiは成功を報告していますか? –

関連する問題