Bebek katili İsrail'in Filistin ve Lübnan'a yapmış olduğu saldırıları kınıyorum. Engin KUZU
Ana Sayfa
Ana Sayfa
Tux
Linux
Programlama
Programlama
Projeler
Projeler
enginkuzu blog
BLOG
Eskiler
Eskiler
Ben
Ben



Windows Altında Win32Assembly Programlama

Artık masm ile nasıl program yazılır bir gözatalım. Aşağıdaki küçük bir windows uygulaması yer almakta:

.386
.model flat, stdcall
option casemap :none
; case sensitive

include
\masm32\include\windows.inc
include
\masm32\include\user32.inc
include
\masm32\include\kernel32.inc

includelib
\masm32\lib\user32.lib
includelib
\masm32\lib\kernel32.lib


.data

baslik db "İlk Assembly Programımız",0
yazi db "Merhaba Dünya",0

.code

start:

push MB_OK
push offset baslik
push offset yazi
push NULL
call MessageBox

push NULL
call ExitProcess

end start

 

; --------------- Data section
.data
baslik db "İlk Assembly Programımız",0
yazi db "Merhaba Dünya",0
; --------------- Code section
.code
; --------------- Program startup
start:

invoke MessageBox,NULL,offset yazi,offset baslik, MB_OK
invoke ExitProcess,0

end start

 

Yukarıdaki ilk örnek qeditor.exe ile derlenebilecek haldedir. Biz eğer notepad kullanmış olsaydık bu şekilde kodlayacak idik. Ben derledim ve boyutu 2.5kbyte olan bir exe dosyası oluştu. Yukarıdaki hem soldaki hemde sağdaki assembly kodu aynı işi yapıyor. Yaptığı iş baslik ismi ile belirtilen başlığa sahip, yazi ismi ile yine data segmentte belirtilen yazıya sahip bir mesaj kutusu gösteriyor. OK'e tıklandıktan sonra program sonlanıyor. İsterseniz hemen açıklamaya başlayayım. İlk üç satıra uzun süre hiç dokunmayacaksınız, burayı geçiyorum. Include satırları ile içinde windows api fonksiyonlarının ve bazı sabit değerlerin isimleri bulunan inc uzantılı dosyaları tanımlıyoruz. Includelib fonksiyonu ile kullandığımız api fonksiyonlarını içeren kütüphaneleri tanımlıyoruz. Windows.inc dosyasında NULL ve MB_OK tanımlamalarının matematiksel eşitlikleri bulunuyor. Birçok özel durumun hangi sayılar ile belirtildiğini ezberlemektense bunların karşılıklarını bilmek daha kolaydır, hemde programın okunurluğunu artırır. .data ile data segment tanımlanıyor ve bu data segment içinde baslik ve yazi adreslerinde ilgili string ifadeler yer alıyor. Dikkat ederseniz stringlerin bittiğini belirtmek için ayrıca 0h degeri ekleniyor. Daha sonra .code ifadesi ile cede segment tanımlanıyor. start: ve end start ifadeleri arasına kodlarımızı yazıyoruz. Dört adet push komutu alt alta yazılmış. PUSH komutu ile stack segmente bazı değerler gönderiyoruz. Bunlar mesaj kutusu ile ilgili özellikler. İlk özellik mesaj kutusunda sadece OK tuşu bulunacağı anlamında. İkinci özellik olan mesajın başlık bölümünde yer alacak yazının adresini stacka yolluyoruz. (adresi anlamına gelen offset terimi kullanılmıştır) Üçüncü yollanan özellik mesaj olarak gösterilecek string ifadenin adresi. Son yollanan ifade NULL yani sıfırdır, buraya bir değer girmemize şu anda gerek yok. Gerekli parametreler stacka yollandıktan sonra fonksiyonumuzu çağırıyoruz. CALL komutu bir fonksiyonun yada bir altprogramın çağırılmasında kullanılır. Çağırılan yerdeki işler bittikten sonra programımız bir sonraki ifade ile devam edecektir. Fonksiyonumuz MessageBox apisidir . Bu api user32.inc içinde tanımlanmış ve ilgi kutuphane user32.lib eklenmiştir. Bu apiyi kullandığımızı belirtmek için yukarıdaki ifadeleri include ile tanımlamaktayız. Daha sonraki bölümde programdan çıkış kodları bulunuyor. Öncelikle çıkış kodu stacka yollanır. Normal sonlanmalarda bu NULL yani sıfırdır. Daha sonra kernel32.inc ve kernel32.lib ile tanımladığımız fonksiyonlardan ExitProcess çağırılıyor.

İşletim sistemimizde user32.dll içinde MesageBox apisi, kernel32.dll içinde ise ExitProcess apisi bulunmaktadır. Dos altında yaptığımız interrup çağrıları gibi windows altında api fonksiyonları bulunur. Bunlar disk erişiminden, ekrana resim çizdirmeye, buttonlar ve kutucuklar hazırlamaya kadar binlerce fonksiyon içeririler. Tabii sadece bu iki dll dosyasıyla sınırlı değil apiler. Ayrıca yukarıdaki komutları yazarken dikkatli olmanız gerekiyor. Derleyicimiz büyük küçük harf ayrımı yapabiliyor. Özellikle api fonksiyonların isimlerini aynen yazın.

Soldaki kod ise işlev olarak aynıdır. Farkı ise MAsmEd altında yukarıdaki gibi yazılması yeterlidir. Include tanımlamalarını programda sol taraftaki ağaç şeklindeki kısımdan ekleyerek yapıyoruz.  Data segmentin içeriği aynı. Code segmentde ise küçük bir değişiklik var. Alt alta yazdiğimiz fonksiyon çağırma işinde call yerine invoke ile tek satırda tüm parametreleri yazdık. Böylece daha kolay okunur oldu. Bunu qeditor.exe içinde de yapabilirdik, yinede eski şekilde kullanılan örnekler daha çok olduğu için ikisini de göstermek istedim. Yoksa yazım farkından başka ikiside aynen ilk örnekteki gibi çalışmaktadır. Birde editörümüz programımız için ikon ve ek bazı versiyon bilgileri eklemektedir. Bu nedenle editör içinden derlenen aynı program 5.5kbyte  boyuta sahip olacaktır.