Challenge 8

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Challenge 8

Mesaj gönderen thelvaci »

Challange 7 arkadaşlarımıza çıtır çerez gibi geldiği için, bu kadar kısa sürede bir başka challange daha açmak icap etti :)

Bu seferki sorun da, benzer bir sorun ve hemen hemen aynı çerezlik kıvamında ;)

Sorun: Uygulama kodunuz içinde uygulamanızın restart(yeniden başlatılması) ihtiyacı hissedildi. Uygulamanızı yeniden başlatmanız ve yeni başlayan uygulamanın yeniden başladığını bilmeniz gerekiyor. Ne yapardınız, nasıl ? Örneğin; uygulamanızın ana formunda bir button ve label olsun; label'da "Yeni uygulama" yazıyor olsun; button'a bastığınızda uygulamanız kapanacak, yeniden başlayacak ve label'ınızda "Yeniden Başlamış Uygulama" yazacak.

Kurallar: Herhangi bir yere(disk/memory/registry) bir şey yazamaz ve oradan okuyamazsınız. ;)
Kullanıcı avatarı
SimaWB
Üye
Mesajlar: 1316
Kayıt: 07 May 2009 10:42
Konum: İstanbul
İletişim:

Re: Challenge 8

Mesaj gönderen SimaWB »

thelvaci yazdı:Challange 7 arkadaşlarımıza çıtır çerez gibi geldiği için, bu kadar kısa sürede bir başka challange daha açmak icap etti :)
Üstad seni bizi işimizden edeceksin :N)
There's no place like 127.0.0.1
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: Challenge 8

Mesaj gönderen thelvaci »

SimaWB yazdı:
thelvaci yazdı:Challange 7 arkadaşlarımıza çıtır çerez gibi geldiği için, bu kadar kısa sürede bir başka challange daha açmak icap etti :)
Üstad seni bizi işimizden edeceksin :N)
Aman patronlara çaktırmayın :D
xxxjedixxx
Üye
Mesajlar: 216
Kayıt: 10 Ara 2013 03:50

Re: Challenge 8

Mesaj gönderen xxxjedixxx »

En basit çözüm olarak, yeniden çalıştırılırken Parametre kullanılabilir.

if ParamStr(1) = 'ReStart' then label1.caption := 'Yeni uygulama';
ikra
Üye
Mesajlar: 901
Kayıt: 28 Nis 2005 01:26
Konum: Simdilik Topragin Üstü

Re: Challenge 8

Mesaj gönderen ikra »

shellexecute ile parametre göndererek yeni programi start eder, hemen akabinde shellexecute cagiran applikasyonu terminate ederim. :alsana:
kıdemsiz üye
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: Challenge 8

Mesaj gönderen thelvaci »

xxxjedixxx yazdı:En basit çözüm olarak, yeniden çalıştırılırken Parametre kullanılabilir.

if ParamStr(1) = 'ReStart' then label1.caption := 'Yeni uygulama';
:bravo: Güzel çözüm ama beklediğim cevap bu değil ;) Ayrıca elinizi ürkek alıştırmayın, vaktiniz var ise çıtır sorularımıza çıtır cevaplar üretmekten imtina etmeyin lütfen ;)
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: Challenge 8

Mesaj gönderen thelvaci »

ikra yazdı:shellexecute ile parametre göndererek yeni programi start eder, hemen akabinde shellexecute cagiran applikasyonu terminate ederim. :alsana:
:bravo: Bu da olabilir, ama beklediğim bu da değil tam olarak. Çözüm görebilirsem eğer daha net bir şeylar yazabilirim ;)
xxxjedixxx
Üye
Mesajlar: 216
Kayıt: 10 Ara 2013 03:50

Re: Challenge 8

Mesaj gönderen xxxjedixxx »

Sanırım istediğiniz CreateToolhelp32Snapshot yardımı ile parent process'e bakarak bulmak. Yani program başladığında parent process'in exe yolu ile kendi exe yolunu karşılaştırarak yeniden başlayıp başlamadığına karar vermek diye düşünüyorum.
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: Challenge 8

Mesaj gönderen thelvaci »

Yoo aslında o kadar kompleks çözümler beklentisinde değilim. CreateProcess yada ShellExecute 'e parametre yollamak ve yeni açılan uygulamada o parametreyi kontrol etmek de elbette doğru çözümler. Lâkin bakış açınızı genişletmeye çalışıyorum ben esasen ;) O halde biraz daha açık yazayım; Mutex ile yapmak isteseydiniz nasıl yapardınız ;)

İstiyorum ki; senkronizasyon nesnelerini farklı amaçlar için de kullanabileceğimizi keşfedelim ;)
ikra
Üye
Mesajlar: 901
Kayıt: 28 Nis 2005 01:26
Konum: Simdilik Topragin Üstü

Re: Challenge 8

Mesaj gönderen ikra »

mutex ile yapacaksam eger, kapanan programda mutex olurturur (ki bu atom ile de olur), daha sonra silmeden birinci programi kapatir ikincisini calistirir, mutex yada atom var mi kontrol ederim. var ise eger program yeni baslatilmistir diye mesaj verir ve mutexi yada atomu silerim.
kıdemsiz üye
ikra
Üye
Mesajlar: 901
Kayıt: 28 Nis 2005 01:26
Konum: Simdilik Topragin Üstü

Re: Challenge 8

Mesaj gönderen ikra »

ikra yazdı:mutex ile yapacaksam eger, kapanan programda mutex olurturur (ki bu atom ile de olur), daha sonra silmeden birinci programi kapatir ikincisini calistirir, mutex yada atom var mi kontrol ederim. var ise eger program yeni baslatilmistir diye mesaj verir ve mutexi yada atomu silerim.
iyi de, mutex olustururken de sonuc olarak memory'e yaziyoruz. yazmadan gerceklesmiyor bu islem.
kıdemsiz üye
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: Challenge 8

Mesaj gönderen thelvaci »

İlk olarak mutex oluşturursanız bunu memory'e siz yazmazsınız; mutex kernel tarafında allocate edilir ve yönetimi yine kernel tarafında yapılır. Dolayısı ile belirttiğim kuralların dışına çıkılmamış olur. İkinci olarak uygulamanız kapanır iken bu nesne bir kernel nesnesi olduğu için kernel sizin mutex nesnenizi release edip NtClose ile kapatacaktır. Teorik çözüm yerine pratik bir şeyler karalamaya çalışırsanız eğer; çözüme zaten kolaylıkla ulaşacaksınız ;)
Kullanıcı avatarı
G.Arkas
Üye
Mesajlar: 829
Kayıt: 01 Eki 2007 07:16
Konum: İstanbul
İletişim:

Re: Challenge 8

Mesaj gönderen G.Arkas »

Repeat Until ile önce bir döngü kurarım.

TProcessInformation ve TStartupInfo ile kendime bir injection hazırlarım. Ve kendi exe dosyamı Injectable bir process e enjekte ederim. En son olarak Repeat Until olayıma

Kod: Tümünü seç

 while true do begin //Loop for create process
                            StartInfo.cb := SizeOf(StartInfo);
                            if _CreateProcess(nil, fileName, nil, nil, False, 0, nil, nil, StartInfo,ProcessInfo) then begin
                                    fEnd := false;
                                    Repeat
                                      Case _WaitForSingleObject(ProcessInfo.hProcess, 200) Of
                                              WAIT_OBJECT_0 : fEnd := true;
                                              WAIT_TIMEOUT  : ;
                                      End;
İle döndürürüm. Restart etmek istediğimde ise ExitProcess(0) demem yeterli olur. Uygulamam kapanır ve Enjecte ettiğim uygulama (Örn: Notepad.exe) uygulamamı yeniden başlatır.

Bu arada iki defa çalışmaması için

CreateMutex ile

Kod: Tümünü seç

    while true do begin //Loop for MUTEX
      _SetLastError(NO_ERROR);
      H := _CreateMutex(nil, False, sMUTEXNAME);
      if _GetLastError <> ERROR_ALREADY_EXISTS then begin
        //_MessageBox(0,skernel32,skernel32,0);
        _CloseHandle(H);
Sağlama alırım ki her defasında uygulamam notepad'e enjecte olmasın. Biz bu sisteme Persistence diyoruz. :D :D :D

Çok fazla etrafından dolaşmış olabilirim.

Düzeltme Not: Çözüm bu değil. Bende kendimi bir dosyaya yazmış oldum aslında :D
Resim
Kullanıcı avatarı
G.Arkas
Üye
Mesajlar: 829
Kayıt: 01 Eki 2007 07:16
Konum: İstanbul
İletişim:

Re: Challenge 8

Mesaj gönderen G.Arkas »

Cevap 2

Kod: Tümünü seç

function MutextVarMi(MutexName: PChar): boolean;
var handle : THandle;
begin
Result := False;
handle := CreateMutex(nil, true, MutexName);
if GetLastError = ERROR_ALREADY_EXISTS then
Result := True
else
if handle <> 0 then CloseHandle(handle);
end;
Yeni bir mutex oluşturup onunla açılır eski mutexi taratıp varsa TerminateProcess. Her yeni mutex otomatik artalan oluşturur. Kendimden bir önceki mutexi tespit ederim. Ve sonlandırırım.
Resim
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: Challenge 8

Mesaj gönderen thelvaci »

G.Arkas yazdı:Repeat Until ile önce bir döngü kurarım.

TProcessInformation ve TStartupInfo ile kendime bir injection hazırlarım. Ve kendi exe dosyamı Injectable bir process e enjekte ederim. En son olarak Repeat Until olayıma

Kod: Tümünü seç

 while true do begin //Loop for create process
                            StartInfo.cb := SizeOf(StartInfo);
                            if _CreateProcess(nil, fileName, nil, nil, False, 0, nil, nil, StartInfo,ProcessInfo) then begin
                                    fEnd := false;
                                    Repeat
                                      Case _WaitForSingleObject(ProcessInfo.hProcess, 200) Of
                                              WAIT_OBJECT_0 : fEnd := true;
                                              WAIT_TIMEOUT  : ;
                                      End;
İle döndürürüm. Restart etmek istediğimde ise ExitProcess(0) demem yeterli olur. Uygulamam kapanır ve Enjecte ettiğim uygulama (Örn: Notepad.exe) uygulamamı yeniden başlatır.

Bu arada iki defa çalışmaması için

CreateMutex ile

Kod: Tümünü seç

    while true do begin //Loop for MUTEX
      _SetLastError(NO_ERROR);
      H := _CreateMutex(nil, False, sMUTEXNAME);
      if _GetLastError <> ERROR_ALREADY_EXISTS then begin
        //_MessageBox(0,skernel32,skernel32,0);
        _CloseHandle(H);
Sağlama alırım ki her defasında uygulamam notepad'e enjecte olmasın. Biz bu sisteme Persistence diyoruz. :D :D :D

Çok fazla etrafından dolaşmış olabilirim.

Düzeltme Not: Çözüm bu değil. Bende kendimi bir dosyaya yazmış oldum aslında :D
Sondaki düzeltme notunu okumamış olsa idim farklı bir şeyler yazacaktım :) İlk olarak; injection için en basitinden bir RtlAdjustPrivilage ile SE_DEGUG_NAME privilage'ine; OpenProcess çağrımına, bir record yapıya, bunu hedef process'in virtual memory'sine yazmak için bir VirtualAllocEx çağrımına, ardından WriteProcessMemory çağrımına, bir dummy procedure'e bir Thread callback'ine ardından yine bir VirtualAllocEx ve WriteProcessMemory çağrımına ardından da CreateRemoteThread yada daha iyisi NtCreateThreadEx API'sine ihtiyacın olacak ki; sen ne yaptın be Gürkanım diyeyim sana :) Kulağını ayak parmaklarının arasından geçirdiğin elinle sıkıyorsun :)

Daha basit düşünün; mutex ile oluyor işte bu olay. Bir önceki mesajımda dediğim gibi senkronizasyon nesnelerini kullandığınızı biliyorum yeri geldiğinde; sadece daha farklı amaçlar için nasıl kullanabilirsiniz diye farkındalık oluşturma amacını güdüyor bu thread ;)

Bu amaca binaen uygulanabilecek en iyi yöntem mutex'tir demiyorum; kim ne uygulamak isterse elbette onu uygulayabilir; dediğim gibi çeşitlilik ve zenginlik katma gayretidir bu.
Cevapla