Я пишу обертку 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 (код не выполняется ..)
Может ли кто-нибудь объяснить, почему это так? ..