Windows işletim sisteminde çekirdek modu (kernel mode) sürücüleri, sistem kaynaklarını doğrudan yönetme yetkisine sahiptir. Ancak bu kaynakların bir kısmına, kullanıcı modu (user mode) uygulamalarının da erişmesi gerekebilir. Örneğin, çekirdek tarafından oluşturulan bir olay (event) nesnesinin, kullanıcı alanındaki bir uygulama tarafından beklenmesi veya tetiklenmesi istenebilir. Bu durumda, sürücüdeki nesneye ait tanıtıcının (handle) güvenli ve geçerli bir şekilde kullanıcı alanına aktarılması gerekir.

Fakat çekirdek ve kullanıcı modları farklı bellek bağlamlarında çalıştıklarından, çekirdek tarafından oluşturulan bir identifier doğrudan kullanıcı süreci için geçerli değildir. Bu nedenle, identifier’ın hedef sürecin bağlamına uygun olarak multiple olması gerekir.

  1. Handle Aktarımının Temel Gereksinimi
    Kernel modunda oluşturulan bir nesne, driver bağlamında geçerli bir handle’a sahiptir. Ancak kullanıcı alanındaki süreç, bu identifier doğrudan kullanamaz çünkü her sürecin kendisine özgü bir handle tablosu vardır. Bu ayrım, Windows’un güvenlik ve bellek koruma mimarisinin bir parçasıdır.

Bu nedenle, driver tarafından oluşturulan identifier’ın kullanıcı sürecine aktarılabilmesi için, tanıtıcının hedef sürecin bağlamında yeniden oluşturulması gerekir. Bu işlem, ZwDuplicateObject fonksiyonu kullanılarak gerçekleştirilir.

  1. Çekirdek Tarafında Uygulama Adımları
    Handle aktarımı genellikle driver’ın IOCTL işleyicisi (örneğin DeviceIoControl isteğini karşılayan DispatchDeviceControl döngüsü) içinde yapılır.

Süreç şu şekilde ilerler:

Nesne Oluşturma Adımı:
Sürücü, paylaşılmak istenen nesneyi (örneğin bir Event, Mutex veya File nesnesi) ZwCreateEvent, ZwCreateFile vb. bir Native API çağrısıyla oluşturur.

Elde edilen tanıtıcı, sürücü içerisinde saklanır.

Kullanıcı İsteği (IOCTL):

Kullanıcı modu uygulaması, sürücüye belirli bir IOCTL kodu ile bir istek gönderir. Bu istek, sürücüye kullanıcı sürecine tanıtıcı aktarması gerektiğini bildirir.

Handle’ın Çoğaltılması (ZwDuplicateObject):

IOCTL çağrısı geldiğinde, sürücü aşağıdaki parametrelerle ZwDuplicateObject fonksiyonunu çağırır:

Kaynak süreç: Identifier’ın ait olduğu süreç (genellikle NtCurrentProcess() veya çekirdek bağlamı)

Kaynak Handle: Çoğaltılacak Handle değeridir.

Hedef süreç: IOCTL isteğini gönderen kullanıcı süreci (PsGetCurrentProcess() ile elde edilir)

Hedef tanıtıcı: Yeni oluşturulan kullanıcı modu tanıtıcısının adresi

Erişim hakları: Genellikle DUPLICATE_SAME_ACCESS kullanılır, böylece aynı erişim hakları korunur.

Identifier’ın Kullanıcıya Döndürülmesi:

ZwDuplicateObject başarılı olursa, oluşan kullanıcı identifier’ı RtlCopyMemory veya benzeri bir yöntemle IOCTL output tamponuna yazılır.

Bu tampon, DeviceIoControl çağrısı tamamlandığında kullanıcı uygulamasına döndürülür.

  1. Kullanıcı Modu Uygulaması Tarafı
    Kullanıcı uygulaması, driver’dan çoğaltılmış handle’ı almak için aşağıdaki adımları izler:

Aygıta Erişim:

-Uygulama, driver’ın oluşturduğu sembolik bağlantıya (\.\MyDevice veya \??\MyLink) CreateFile ile bağlanır.

IOCTL Gönderimi:

-DeviceIoControl call’u yapılarak sürücüden handle istenir.

-Input buffer boş bırakılır.

-Output buffer, “HANDLE” tipinde bir değişkenin adresi olarak verilir.

-Boyut olarak sizeof(HANDLE) belirtilir.

Handle’ın Alınması ve Kullanımı:
DeviceIoControl başarılı olduğunda, output buffer için geçerli bir kullanıcı modu handle’ı yer alır.

Bu tanıtıcı, WaitForSingleObject, SetEvent, ResetEvent gibi standart Windows API çağrılarında doğrudan kullanılabilir.

Tanıtıcının geçerli olup olmadığı GetHandleInformation veya DuplicateHandle testleriyle doğrulanabilir.

  1. Güvenlik ve Doğruluk Açısından Değerlendirme
    Bu yöntem, Windows çekirdek mimarisinde kullanıcı ve kernel bağlamları arasında güvenli kaynak paylaşımını sağlamanın en doğru ve önerilen yöntemidir.

Yanlış uygulamalarda — örneğin kernel identifier’ının doğrudan kullanıcıya döndürülmesi veya user modunda kullanılmaya çalışılması — sistem kararsızlığına, erişim ihlallerine veya güvenlik açıklarına yol açılabilir.

ZwDuplicateObject işlevinin doğru kullanımı sağlandığında:
Identifier bütünlüğünü korur, süreçler arası bellek alanı ihlallerini önler, nesne erişim haklarının kontrolünü güvenli biçimde sürdürür.

***ZwDuplicateObject fonksiyonunun doğru kullanımı, gelişmiş Windows sürücü geliştirme, hata ayıklama, güvenlik araştırmaları ve sistem mimarisi analizi gibi alanlarda temel bir beceri olarak öne çıkar.