seo modüllerin tabloları

2 Temmuz 2013 Salı Unknown 0 yorum

Modüllerin Import ve Export Tabloları


işletim
            Aslında exe ve dll dosyaları arasında ciddi bir fark yoktur. Yani bir exe dosyası dll dosyası gibi kullanılabilir. Dll dosyaları için söz konusu olan herşey exe dosyalar için de geçerlidir.

Export Tablosu

            Bir modüldeki bir fonksiyonun başka bir modül tarafından çağırılabilmesi için o fonksiyonun modülün export tablosuna yazılması gerekir. Örneğin bir dll dosyasının içerisinde 100 tane fonksiyon bulunsun. Eğer bunlardan yalnızca biri export tablosuna yazılmışsa başka bir modül yalnızca bu fonksiyonu çağırabilir. Tabii bu fonksiyon kendi içerisinde kalan 99 fonksiyonu çağırıyor olabilir. Export tablosunun genel yapısı aşağıdaki gibidir:


Export tablosu dışarıdan başka bir modül tarafından çağırılacak fonksiyonlar için fonksiyonların modül içerisindeki başlangıç adreslerini tutar. Örneğin func isimli bir fonksiyon bir dll içerisinde bulunsun ve bir exe dosyasından çağırılmış olsun. İşletim sistemi programın akışının bu fonksiyona geçirilmesi için bu fonksiyonun dll içerisinde nerede olduğunu bilmesi gerekir. işte bu bilgiyi dll dosyasının export tablosundan elde etmektedir.
            Fonksiyon isimleri export tablosuna alfabetik olarak sıralı bir biçimde yerleştirilir. Export tablosunda bir fonksiyonu hızlı bir biçimde bulabilmek için ikili arama(binary search) yöntemi kullanılır.  Tabloda fonksiyon ismi ve sıra numarası bir yapı biçiminde yani ikili kayıtlar biçiminde bulunur. Ancak fonksiyon adresleri sütunu bağımsız bir sütundur.

Export Tablosundaki Fonksiyonun Adreinin Tespit Edilmesi

            İsimden hareketle bir fonksiyonun adresi şöyle bulunur:

1. Fonksiyon ismi ikili arama yöntemi kullanılarak fonksiyon ismi sütununda aranır. Buradan fonksiyon adresinin sıra numarası elde edilir.
2. Bu sıra numarası fonsiyon adresi sütununa index yapılarak fonksiyon adresi çekilir.

            Arama işlemi def dosyası(module definition file) kullanılarak doğrudan sıra numarasına göre de yapılabilir. Bu durumda yalnızca fonksiyonun fonksiyon sütunundaki sıra numarası bilinir. Fonksiyon adresi doğrudan bu sütundan çekilir. Yani bir exportable fonksiyon fonksiyon ismi bilenerek ya da sıra numarası bilinerek aranabilir. Sıra numarası bilinerek yapılan arama çok daha hızlı bir sonuca ulaştırır. Export tablosuna yazılacak fonksiyonların isimleri ve sıra numaraları programcı tarafından belirlenebilmektedir.
            Export tablosundaki fonksiyonların adresleri modülün ilk byte'ın sıfır olacak biçimde göreli olarak düzenlenmiştir.

Import Tablosu

            Bir program içerisinde bir dll çağırılmışsa derleyici bunun makina kodunu CALL [adr] biçiminde yazar. Bu çağırma biçimine sembolik makina dilinde dolaylı çağırma(indirect call) denir. Bu makina komutu şu anlama gelmektedir: "Mikroişlemci adr ile belirtilen adrese git, orada fonksiyonun başlangıç adresi var. O adresi al ve fonksiyona atla".
            Import tablosunun genel biçimi aşağıdaki gibidir:


            Derleyicinin ürettiği köşeli parantez içindeki adresin değeri import tablosunun dolaylı adres sütununun satırlarını göstermektedir. Yani runtime sırasında dolaylı adres sütununda belirtilen adreslere programın akışı geçirilmektedir. Dolaylı adres sütunu yükleyici tarafından modüllerin export tablolarına bakılarak doldurulmaktadır. Bu durumda bir dll yüklenmesinde şunlar yapılmaktadır.

1. Yükleyici exe dosyayı yükler
2. Yükleyici dll dosyalarını yükler.
3. Yükleyici dll'lerin export tablolarına bakarak, fonksiyonların göreli adreslerini elde eder. Bu değerlere dll dosyalarının yükleme adreslerini ekleyerek gerçek adresleri bulur.
4. Yükleyici bu adresleri import tablosunun dolaylı adres sütunlarına yazar.

            Import ve export tablolarının her ikisi de hem dll dosyaları içerisinde hem de exe dosyaları içerisinde vardır. Bir dll dosyası içerisindeki fonksiyon başka bir dll dosyası içerisindeki başka bir fonksiyonu çağırabilir.

dllexport ve dllimport Bildirimleri

            Bir fonksiyonu başka bir modülden çağırabilmek için o fonksiyonun export tablosuna yerleştirilmesi gerekir. Bir fonksiyonu export tablosuna yerleştirmek için fonksiyon prototipinin başına __dllspec(dllexport) ifadesinin yerleştirilmesi gerekir. __declspec(dllexport) fonksiyon tanımlaması sırasında da kullanılabilir(Hem prototipte hem de tanımlama sırasında kullanılabilir). Başka bir modülün export tablosunda belirtilmiş bir fonksiyonun çağırılması için özel bir işleme gereksinim yoktur. Çünkü linker çağırılan fonksyonları programın diğer modüllerinde bulamazsa otomatik olarak dll içerisinde de arar. Ancak bir dll içerisindeki bir fonksiyonun çağırılması söz konusuysa bu fonksiyon prototipinin önüne __declspec(dllimport) ifadesini yerleştirmek linker'ın işini kolaylaştırır.

Bir DLL'in Kullanıma Hazır Hale Getirilmesi


            Bir dll bir kütüphanedir ve içerisinde fonksiyonlar vardır. Bir dll'e ilişkin kaynak dosya C ya da CPP dosyası biçiminde yazılabilir. Bir dll'in oluşturulabilmesi için en iyi yöntem x.h ve x.c biçiminde iki dosya kullanılmasıdır. x.h dosyası dll içerisindeki fonksiyonların prototiplerini barındırır. Bu dosya hem x.c dosyası içerisinden, hem de dll'i kullanan bir modül içerisinden include edilir. Bu dosya içerisindeki prototiplerin başında dll için derleme yapılıyorsa __declspec(dllexport), başka bir modülden kullanılıyorsa __declspec(dllimport) ifadelerinin yazılması gerekir. Bu durumda ön işlemci komutlarıyla x.h dosyasına hiç dokunmadan fonksiyon prototipinin başındaki ifadeyi dışarıdan değiştirebiliriz. Tipik bir dll başlık dosyası şöyle organize edilebilir:



Dll dosyası kendisi derlenirken __MYLIB__ define edilir, kullanım kodunda kullanılmaz.
            Bir dll oluşturabilmek için project menüsünden proje türü olarak "Win32 Dynamic Linked Library" seçilmelidir. Bir dll kendi başına çalışamaz. Oysa bir exe kendi başına WinMain fonksiyonundan çalışır. Bir dll derlendiğinde ve link edildiğinde geliştirme ortamı dll ve lib uzantılı iki dosya oluşturur. Lib dosyasına "Import Library" denir ve normal bir lib formatında değildir. Import library dosyasından dll kullanılırken faydalanılır.

/*-----dll.dsw-----*/

Bir Dll'in Uygulama İçerisinden Kullanılması

            Bir dll'i oluşturduktan sonra dll içerisindeki fonksiyonlar başka bir modülden çağırılabilir. Bir dll sırasıyla şu dizinler içerisinde aranır:
1. Exe dosyasının bulunduğu dizin içerisinde
2. O anda bulunulan dizin içerisinde. O anda bulunulan geçerli dizin eğer prompt içerisindeysek programın çalıştırıldğı dizindir. Ancak prompt içerisinde değilsek yani örneğin masa üstündeki bir simgeyi çift tıklayarak çalıştırmışsak ya da Windows Explorer aracılığıyla programı çalıştırmışsak manuel yöntemle belirlenebilir. Aslında bir exe programını çalıştıran CreateProcess isimli bir API fonksiyonu vardır. Bu API fonksiyonunun bir parametresi de geçerli dizini belirtir. Aslında masa üstünde ya da Windows Explorer içerisinde programı çalıştırmak istesek Windows'un kendisi de programı CreateProcess isimli API fonksiyonuyla çalıştırır. Yani mouse'un sağ tuşuna basılarak geçerli dizin set edildiğinde Windows bu bilgiyi CreateProcess ile programı çalıştırırken kullanır.
3. Windows dizininin altındaki System dizininde
4. Windows dizininde
5. Path ile belirtilen dizinlerde(Bu path autoexec.bat'taki path değildir)
6. Registry içerisinde özel bir yöntemle belirtilerek
            Dll uygun dizin içerisine çekildikten sonra dll'i kullanacak programın proje dosyası oluşturulur. Import Library dosyasını projeye dahil etmek gerekir. Bu sayede linker çağırılan bir fonksiyonun hangi dll içerisinde olduğunu tespit eder. Import Library'nin projeye dahil edilmesi "Add files to project" seçeneğiyle ya da "Project=>Settings=>Link=>Object/library" modules içine yazarak yapılabilir. Sonuş olarak şu işlemlerin yapılması gerekir:

1. Dll’in uygun bir dizine kopyalanması
2. Başlık dosyasının kullanılacak dosyadan include edilmesi
3. Import Library'nin projeye eklenmesi

            Import Library linker için, başlık dosyası derleyici için dll dosyası ise yükleyici için bulundurulmaktadır. Import Library ile aynı görevde olan bir def dosyası da vardır. Dll dosyasından Import Lıbrary ya da def dosyası elde edilemez.

DLL'lerin Sonradan Yüklenmesi

            Normal bir dll import library kullanılarak link edilmişse exe program yüklenirken işletim sistemi tarafından otomatik olarak belleğe yüklenir. Oysa bir dll dosyası programım çalışmasının herhangi bir aşamasında LoadLibrary API fonksiyonuyla yüklenebilir. Bir dll böyle kullanılacaksa projeye import library'i eklenmez.

Fonksiyonun parametresi yüklenecek dll dosyasının ismidir. Fonksiyonun geri dönüş değeri dll dosyasının yüklendiği bellek adresidir. Başarısızlık durumunda NULL değeriyle geri döner. Örneğin dll dosyası WM_CREATE mesajı içerisinde dinamik olarak yüklenebilir. Dosya ismi bir path ifadesi içerebilir. Eğer içeriyorsa dosya yalnızca o dizinde aranır, içermiyorsa daha önce belirtilen sırada aranır. LoadLibrary fonksiyonuyla yüklenen dll istenildiği zaman FreeLibrary fonksiyonuyla hafızadan çıkarılabilir.


Fonksiyon LoadLibrary fonksiyonundan elde edilen geri dönüş değerini parametre olarak alır ve dll dosyasını hafızadan çıkarır. Örneğin bu API fonksiyonu WM_DESTROY mesajında kullanılabilir.
            Bir dll LoadLibrary ile daha sonra yüklenmişse dll içerisindeki bir fonksiyonun çağırılması için o fonksiyonun adresinin runtime sırasında GetProcAddress API fonksiyonuyla elde edilmesi gerekir. Bu biçimde bir fonksiyonun çağırılabilmesi için fonksiyonun isminin ve parametrik yapısının bilinmesi gerekir. Ancak fonksiyon isimleri dll içerisine bazı nedenlerden dolayı değiştirilerek yazılmaktadır. Bu durumda bir fonksiyonun gerçek isminin elde edilmesi gerekir. Bu isim aslında programcı tarafından belirlenebilir, ya da Dumpbin programıyla:
Dumpbin /exports
seçeneğiyle elde edilebilir. Fonksiyon ismi yerine export tablosundaki sıra numarası da kullanılabilir. Sıra numaraları dumpbin programıyla ya da programcı tarafından hazırlanan def dosyası ile elde edilebilir. Dumpbin.exe programı sisteme ilişkin dosya formatlarını anliz etmeye yarayan Visual C++ paketiyle verilen özel bir programdır.

Fonksiyonun birinci parametresi LoadLibrary fonksiyonundan elde edilen handle değeridir. İkinci parametre fonksiyonun dll içerisindeki ismidir. İkinci parametre ile verilen adresin yüksek anlamlı iki byte'ı 0 ise fonksiyon düşük anlamlı iki byte'ında export tablosundaki sıra numarasının bulunduğunu düşünür. Böyle bir durumda bu parametre:


0 yorum: