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番目の例では
- ました)..
誰でも私はそれなぜそうですか教えてください。
あなたがメモリから実行するとであることを認識していますサポートされていません? –
あなたのコメントのためにDavidに感謝します。 私が知る限り、合法で許可されています。 UPXが圧縮されたexeをどのように実行しているかを見てください。まず、元のコードがメモリに解凍されてから実行されます。これは、有名なexeパッカーのほとんどに当てはまります。 ASPackも同じことをしますが、UPXのクラッカーよりもはるかに優れた暗号化と保護メカニズムを備えています。ここでは悪質なコードを実行しようとしているのではなく、UPXやASPackとまったく同じように動作する正当なラッパーを作成しようとしています。これにより、より良い方法でシナリオが明確になることを願っています。 – jimsweb
まあ、私の主張は、MSがメモリから画像を読み込むことをサポートしていないことと、将来のリリースやOSアップデートの中で壊れる可能性があるコードだということだけです。なぜあなたはこれをやりたいのか理解しています。私はあなたがそれを行うことができないということを知っていることを確認したかっただけです。 –