我正在编写一个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));
.....
.....
任何人都可以解释一下为什么会这样......?
答案 0 :(得分:3)
祝你好运,你第一次使用它:lpStartupInfo
是<{em> in 参数CreateProcess
,你必须初始化其成员:
..
FillChar(SInfo, SizeOf(SInfo), 0);
SInfo.cb := Sizeof(TStartupInfo);
CreateProcess(...
..