- 8 Eyl 2016
- 1,646
- 996
Bu konu da basit bir C programının gdb debugger ile incelemesini yapacağım. Programım test adında çalıştırılabilir formattadır. Bu konuyu daha iyi kavrayabilmek için register, işlemci mimarisi gibi konular hakkında bilgi sahibi olunması önemlidir. Konumuza geçelim Gdb ile programımı açtım ve main fonksiyonuna break koydum. Yani program main fonksiyonuna geçmeyecek. Run diyerek çalıştırdığımda da görüldüğü gibi main içerisinde yer alan ilk kodu işlemediğini söylüyor.
Şimdi main fonksiyonunu disassemble edip ardından rip instruction hangi adresi gösterdiğine bakacağım. Burada bir parantez açmak gerekirse kullandığım sistem 64 bit olduğu için register ismi rip olarak gözüküyor. 32 bitlik bir sistem de eip olarak, 16 bit ise ip olarak görünür. İşlemci mimarisine göre değişiklik göstermektedir. Instruction pointer, program da bir sonraki çalışacak olan adresi gösterir.
Rip register bir sonraki çalışacak komutu tutuyor ve mov komutu ile aynı adresi gösteriyor. Yani bir sonraki çalışacak komut mov. Bu komutun yaptığı şey DWORD PTR [rbp-0x4],0x0 adresine 1 tane 0 atıyor.
Burada rip registerdan 1 byte değer aldığımda mov komutunu işaret ediyor. Yani bir sonraki çalışacak komut. İşaret edilen değerin de hexadecimal karşılığı görüldüğü gibi. "rbp-0x4" bu değer aslında base pointerdan sonra gelen ilk değer, yani bizim programımızda int i = 0 kodunu işaret ediyor. Şimdi bir sonraki instructionı çalıştıralım.
Bir sonraki instruction çalışınca rip instruction bir sonraki çalışacak komutun adresini tutuyor. Main+15 işaret etmiş. Şimdi disassemble edip bir bakalım bu neymiş.
İşaret ettiğim adres cmp instructionı gösteriyor, yani bir sonraki çalışacak yer cmp instruction. CMP, rbp-0x8 değişkenini 4 ile karşılaştırıyor. Peki 4 ne alaka? Şimdi C programımızın kaynak koduna bakalım.
Bizim i değişkenine atadığımız değer 0, yani 4den küçük. List komutu ile kaynak kodu gördüm. Burada i değişkeni 5 den küçük olacak yani cmp burada 4 olma durumuna bakıyor. Şimdi nexti deyip diğer kodumuzu işleme alalım yani karşılaştırmayı yapalım, yani i değişkenimizi karşılaştıralım ve ripyi kontrol edelim nereyi gösteriyor.
Rip, main+19 yani jg komutunun adresini gösteriyor. Jg komutu for döngüsünün koşulunu gerçekleştirecek, çünkü i değişkenimiz for da tanımladığımız şartı sağlıyor. Nexti diyelim ve devam edelim.
Şuan da rip instruction, mov komutunu işaret ediyor. Şuan döngüyü gerçekleştirdi. Daha sonra nexti diyorum ve rip nereyi gösteriyor kontrol ediyorum.
Şimdi main+33 yani call komutunu gösteriyor.
Call komutu da printf yaparak ekrana yazdırma işlemini yapıyor. Program bu şekilde döngüyü devam ettiriyor.
Konumuz bu kadar, bilgisayarım da kendim için hazırlamış olduğum notumu sizlerle paylaştım. Belki çok geniş olmadı, kafanızda oturmayan şeyler de olabilir, ama buradan kendinize bazı şeyler çıkarabilirsiniz. Ayrıca youtube kanalımda çekmiş olduğum intel 8086 assembly serisi de faydalı olabilir.
[ame]https://www.youtube.com/watch?v=ivzHW4n2i98&list=PLRzqj5IrfWN6M2fJXNanxiB93CzFP4jUM[/ame]
Son düzenleme: