C#: Kendi Kendini Kuran Windows Servisi

zztri

Yaşayan Forum Efsanesi
9 Tem 2015
10,053
390
Ankara
Windows servisleri hoş şeylerdir. Interaktif değildirler, mesaj göstermelerini, kullanıcı ile iletişime geçmelerini sağlayamazsınız ama bunun haricinde bütün bilgisayarın kontrolüne sahiptirler ve çalışmaları için birinin login etmiş olması gerekmez.

Tek sorun, standart bir windows servisi kurduğunuzda, onu bir de "install" etmek gerekir. Aslında gerekmez ama Microsoft bu konuda pek açıklama yapmamış, taslaklarına da pek bir opsiyon koymamıştır.

Bu yazıda kendi kendini kurabilen, kaldırabilen bir windows servisi nasıl yazılır onu anlatacağım.

Öncelikle yeni bir windows servisi oluşturalım. Visual Studio'da CTRL+SHIFT+N tuşlarına basarak yeni projemizi oluşturalım:

hpnPZ.jpg


Adını değiştirmeyi unutmayın. Sonradan değiştirmek için bir çok değişiklik yapmak gerekir; assembly name, klasör adları, namespace adları, falan filan.. Servis projemiz servisimizin "Design" görünümü ile açılır. Çok güzel, çünkü buraya hemen bir şey eklemek istiyoruz. Sağ tuşa tıklayıp, "Installer" sisteminin bu servise eklenmesini isteyelim.

4rcx6Z.jpg


Hemen ardından da ServiceInstaller1'i seçim, servis seçeneklerimizi değiştirelim. "Description", yani açıklama yazmadan önce çektim fotoğrafı yanlışlıkla, isterseniz oraya da bir açıklama yazabilirsiniz.

3zZdLY.jpg


Servisin prosesi için bir ayar değişikliğimiz var. Hemen hemen her zaman için servisler LocalService(yönetici olmayan interaktif olmayan kullanıcı) veya LocalSystem(yönetici interaktif kullanıcı) adıyla açılır. Bu hesaplar üstüne açtığınız servislerde bir kullanıcı adı veya şifre sağlamak zorunda da değilsinizdir.

6jqpx9.jpg


Şimdi servisimizin adını değiştirelim. Solution Explorer'da seçin, F2'ye basın, yeni ismi yazın. Size aynı isimdeki kod elemanlarını da değiştirip değiştirmeyeceğini soracak, tabii kabul edin.

Ardından F7'ye basıp, servisin asıl yapması gerekenleri ekleyebilirsiniz. O kısım beni ilgilendirmiyor, benimkini de sonra ekleyeceğim.

Tabii şimdi bir de bu installer class'ları kullanarak, asıl kurulumu yapmamız lazım. Proje'ye referans ekleyelim. Yani aslında zaten eklenmiş olması lazım, ama arada Visual Studio sapıtıyor.
"System.Configuration.Install" namespace'inin referanslar arasında olduğundan emin olalım.

Şimdi işimiz Program.cs ile.. Aslında gayet standart, ServiceBase listesini oluşturup sonra bu servisi çalıştıran bir kısım var. Bazı durumlarda bunu da yapmalı, ne zaman? Servis olarak açıldığında...

Servis olarak açıldığını anlamanın da inanılmaz basit bir yolu var. Servisler, interaktif olarak çalışmaz. Bundan dolayı bu kısmı bir "if" içine alıp, interaktif değilse burayı çalıştıracağından emin olalım...

Sadece "interaftif değilsen, servisi çalıştır, işin bitince de 'return' et" deyiveriyoruz.

Kod:
if (!Environment.UserInteractive)
{
    ServiceBase[] ServicesToRun;
    ServicesToRun = new ServiceBase[] 
    { 
        new ZwService() 
    };
    ServiceBase.Run(ServicesToRun);
    return;
}

Ya interaktifse? O zaman önce yönetici olup olmadığını kontrol edelim. Yönetici olarak çalıştırılmamışsa, programcı bir şeyi test ediyor demektir, Servisimizin "Start()" fonksiyonunu çalıştıralım ki normalde ne yapacaksa onu yapsın servis... Yönetici olarak çalıştırılmışsa, servisin kurulu olup olmadığını kontrol edelim. Kurulu ise kaldırsın, yoksa kendini adam gibi bir yere kopyalayıp kursun.

Kod:
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;

namespace ZwService
{
    static class Program
    {
        static **** Main()
        {
            if (!Environment.UserInteractive)
            {
                ServiceBase[] ServicesToRun;
                ServicesToRun = new ServiceBase[] 
                { 
                    new ZwService() 
                };
                ServiceBase.Run(ServicesToRun);
                return;
            }
[Color="blue"]            //Şu anki identity için Windows Principallarını alıyoruz.[/color]
[Color="blue"]            //Eğer giriş yapılan kullanıcı "admin" ise, "Yönetici Olarak Çalıştır" seçerek çalıştırılmıştır.[/color]
            if (new System.Security.Principal.WindowsPrincipal(System.Security.Principal.WindowsIdentity.GetCurrent()).IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator))
            {
[Color="blue"]                //Appdata klasörü altına yeni bir klasör açıyorum, buraya kuracak veya zaten kurulmuşsa bu klasörü kaldıracağım.[/color]
                string kurulumKlasoru = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "ZwUpdate");
[Color="blue"]                //Dosyamız da bu klasörün hemen altında olacak.[/color]
                string kurulumYeri = System.IO.Path.Combine(kurulumKlasoru, "ZwUpdate.exe");
[Color="blue"]                //Servis kontrolörü oluşturmaya çalışıyorum. Kurulu muyum, değil miyim buradan anlayacağım.[/color]
                System.ServiceProcess.ServiceController kontrol = new System.ServiceProcess.ServiceController("ZwUpdateServer");
[Color="blue"]                //Eğer servis aslında kurulmamışsa, burası InvalidOperationException verecek.[/color]
                try
                {
[Color="blue"]                    //Status'u "Stopped" yani durmuş değil ise, durdurmaya çalışalım.[/color]
[Color="blue"]                    //Aslında o anda servis "durmaya hazırlanıyor" da olabilir, n'olur n'olmaz bu stop komutunu da[/color]
[Color="blue"]                    //try..catch içine alalım.[/color]
                    if (kontrol.Status != ServiceControllerStatus.Stopped) try
                        {
                            kontrol.Stop();
                        }
                        catch { }
[Color="blue"]                    //Bu noktaya gelmişsek kesinlikle servisimiz kuruludur. Şimdi kaldıralım.[/color]
                    System.Configuration.Install.ManagedInstallerClass.InstallHelper(new string[] { "/u", kurulumYeri });
[Color="blue"]                    //Bu kadar.. /u ve kurulu olduğu yeri parametre olarak veriyoruz, yetiyor.[/color]
[Color="blue"]                    //Şimdi de recursive olarak kurulum klasöründe ne varsa silelim, klasörü de kaldıralım.[/color]
                    System.IO.Directory.Delete(kurulumKlasoru, true);
                    Console.WriteLine("Servis başarıyla kaldırıldı.");
                }
                catch (InvalidOperationException)
                {
[Color="blue"]                    //Buraya düşmüşse, servis kurulu değildir, bizim kurmamız gerekir.[/color]
[Color="blue"]                    //Önce gerekli klasörü açalım..[/color]
                    System.IO.Directory.CreateDirectory(kurulumKlasoru);
[Color="blue"]                    //Sonra kendimizi kopyalayalım.[/color]
[Color="blue"]                    //Biz şu anda çalışan prosesin, ana modülünün dosyasıyız. Ondan eminiz çünkü şu anda bir dll'den çalışmıyoruz.[/color]
                    System.IO.File.Copy(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName, kurulumYeri);
[Color="blue"]                    //Şimdi kuralım.. Gene tek komutluk bir işlem...[/color]
                    System.Configuration.Install.ManagedInstallerClass.InstallHelper(new string[] { kurulumYeri });
[Color="blue"]                    //Servisimiz kuruldu. Şimdi bu yeni kurulan servisi çalıştıralım.[/color]
                    using (System.ServiceProcess.ServiceController kontroller = new System.ServiceProcess.ServiceController("ZwUpdateService")) kontroller.Start();
[Color="blue"]                    //Servisimiz kuruldu ve çalışıyor.[/color]
                }
                return;
            }
[Color="blue"]            //Burada isek, yönetici değiliz demektir. O zaman programcının yapmak istediği "debug" olmalı..[/color]
[Color="blue"]            //Bazı programlarımda, bu noktada "ayar penceresi" gibi şeyleri gösteririm, ayarları değiştirtirim. Seçim sizin.[/color]
[Color="blue"]            //Siz istediğiniz işlemi bu noktaya koyun.[/color]
        }
    }
}

İşte bu kadar.. Legal programlar için tatlı bir özelliktir bu ama, tabii ki kendini servis olarak çabucak kuruveren bir trojan da aynı derecede tatlıdır.
 

mert215

Yeni üye
28 Tem 2008
49
0
Eline sağlık ilgilendiğin için teşekkür ederim
 
Son düzenleme:

Jeav

Katılımcı Üye
15 Mar 2018
384
0
Adana

Bu programa istediğini yaptırmak gibi birşeymi? Yani sistem programın sistem dosyalarında değişiklik yapmasına falan karışmayacak. Böyle bir şey ise çok ihtiyacım vardı teşekkürler.
 
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.