Tersine mühendislik yapıyorsanız ve makine kodunu analiz etmek için IDA ve Ghidra gibi araçlarla derlenmiş bir yürütülebilir dosyayı analiz etmek için assembly dili hakkında bilgi sahibi olmanız gereklidir.

Assembly x86-64 düşük seviyeli dillerdendir. Bu görevleri gerçekleştirmek için bellekteki kayıtlarla çalışmayı anlamanın ve dahil
etmenin çok daha zor olabileceği anlamına gelmektedir. Yüksek seviyeli dilleri yazılımcı daha kolay anlayabilir. Bilgisayar ise
makine dili olarak bilinen düşük seviyeli dilleri daha kolay yorumlayabilir.

C++ Derleme Süreci

Bir .cpp dosyasının kodunu içeren dosyanın çıktı dosyasını (.o) almak için onu derlemeniz gereklidir. Bu dosyalar, bilgisayarın
talimatları olan işlem kodunu (op-code) içeren makine dili programları olan nesne koduna sahiptir. Kötü amaçlı yazılımlar
genellikle op-code olarak sunulur, bu nedenle işlem kodunu anlamak için tersine mühendislik gereklidir.

Assembly nedir?

Dar anlamda, bir derleyici olan assembler, bir “assembler programı”nın kodunu makine koduna yani sıfırlar ve birlere çeviren bir derleyicidir. Ancak, bir C derleyicisinin aksine, assembler’ın işi çok daha kolaydır çünkü (neredeyse her zaman) bir assembler talimatı tam olarak bir makine kodu talimatına karşılık gelir. Assembler programı, dolayısıyla (biraz daha) insanlar için daha rahat bir temsil olan makine programının yalnızca bir gösterimidir.

01001000 00000101 11101000 00000011 yerine, aynı anlamı taşıyan assembly talimatını kullanılabilir:

add rax,1000.

Bu, (x86_64 işlemciler için) tam olarak aynı şeyi ifade eder.

Sembolik açıklama Makine kodu
rax add 0100100000000101
1000 (dec.) 0000001111101000
Sembolik açıklama Makine kodu
rax ekle 0100100000000101
1000 (aralık) 0000001111101000


Genel dil kullanımında, “assembly” terimi, derleyiciden çok makine dilinin sembolik gösterimi olarak anlaşılır. add rax,1000 ise bir assembler talimatı olarak kabul edilir.

x86 Register

x86 mimarisi, 8 Genel Amaçlı Register (GPR), 6 Segment Register, 1 Bayraklar Register’ı ve 32-bit x86 için bir Komut İşaretçisi içerir.

x86 Mimarisi
  • EAX — Fonksiyon dönüş değerlerini saklar
  • EBX — Veri bölümü için temel işaretçi
  • ECX — Dize ve döngü işlemleri için sayaç
  • EDX — Giriş/Çıkış (Input/Output – I/O) işaretçisi
  • ESI — Dize işlemleri için kaynak işaretçi
  • EDI — Dize işlemleri için hedef işaretçi
  • ESP — Yığın işaretçisi
  • EBP — Yığın çerçeve temel işaretçisi
  • EIP — İlerideki bir sonraki komutun işleneceği adresi gösterir (“komut işaretçisi”), doğrudan “mov” ile değiştirilemez ancak işlemlerle dolaylı olarak değiştirilebilir.

Pointer Registers

İşaretçi kaydedicileri 32-bitlik EIP, ESP ve EBP kaydedicileri ile bunlara karşılık gelen 16-bitlik sağ kısımları IP, SP ve BP’dir. İşaretçi kaydedicilerinin üç kategorisi bulunmaktadır.

  • Instruction Pointer (IP) − 16-bitlik IP kaydedici, yürütülecek sonraki komutun ofset adresini saklar. CS kaydedici ile ilişkili olarak (CS:IP olarak) kod segmentindeki mevcut komutun tam adresini verir.
  • Stack Pointer (SP) − 16-bitlik SP kaydedici, program yığını içindeki ofset değerini sağlar. SS kaydedici ile ilişkili olarak (SS:SP olarak), program yığını içindeki verinin veya adresin mevcut konumuna işaret eder.
  • Base Pointer (BP) − 16-bitlik BP kaydedici, genellikle bir alt programına geçirilen parametre değişkenlerine referans vermede yardımcı olur. SS kaydedicisindeki adres, BP’deki ofsetle birleştirilerek parametrenin konumu elde edilir. BP ayrıca özel adresleme için DI ve SI ile birleştirilebilir.

Control Registers


32-bitlik komut işaretçisi kaydedici ve 32-bitlik bayraklar kaydedicisi bir araya geldiğinde kontrol kaydedicileri olarak kabul edilir.

Birçok talimat karşılaştırmaları ve matematiksel hesaplamalar içerir ve bayrakların durumunu değiştirir; bazı koşullu talimatlar ise bu durum bayraklarının değerini test ederek kontrol akışını farklı bir yere yönlendirir.

Ortak bayrak bitleri şunlardır:

  • Overflow Flag (OF) − İşaretli bir aritmetik işlemden sonra verinin en yüksek sıradaki bitinin (en soldaki bit) taşmasını gösterir.
  • Direction Flag (DF) − Dize verilerini taşımak veya karşılaştırmak için sol veya sağ yönlendirmeyi belirler. DF değeri 0 ise, dize işlemi soldan sağa doğru yapılır; değer 1 ise, dize işlemi sağdan sola doğru yapılır.
  • Interrupt Flag (IF) − Klavye girişi gibi harici kesmelerin dikkate alınıp alınmayacağını belirler. Değeri 0 ise harici kesmeler devre dışı bırakılır, değer 1 ise kesmeler etkinleştirilir.
  • Trap Flag (TF) − İşlemciyi tek adımlı moda ayarlama olanağı sağlar. Kullandığımız DEBUG programı tuzak bayrağını ayarlar, böylece yürütümü adım adım izleyebiliriz.
  • Sign Flag (SF) − Aritmetik bir işlemin sonucunun işaretini gösterir. Bu bayrak, aritmetik işlemin ardından veri öğesinin işaretine göre ayarlanır. İşaret, en soldaki bitin en yüksek sırasında gösterilir. Pozitif bir sonuç, SF değerini 0’a sıfırlar ve negatif bir sonuç 1’e ayarlar.
  • Zero Flag (ZF) − Aritmetik veya karşılaştırma işleminin sonucunu gösterir. Sıfırdan farklı bir sonuç, sıfır bayrağını 0’a sıfırlar; sıfır bir sonuç ise 1’e ayarlar.
  • Auxiliary Carry Flag (AF) − Özel aritmetik işlemleri için, bir aritmetik işlemden bit 3’ten bit 4’e taşma olup olmadığını içerir. AF, bir 1 byte’lık aritmetik işlem bit 3’ten bit 4’e taşıma yaparsa ayarlanır.
  • Parity Flag (PF) − Aritmetik işlemin sonucundaki toplam 1 bitin sayısını gösterir. Çift sayıda 1 bit, çiftlik bayrağını 0’a sıfırlar; tek sayıda 1 bit ise 1’e ayarlar.
  • Carry Flag (CF) − Aritmetik işlemden sonra en yüksek sıradaki bitin (en soldaki) taşımayı içerir. Aynı zamanda bir kaydırma veya döndürme işleminin son bitinin içeriğini de saklar.

Segment Registers

Segmentler, bir programın veri, kod ve yığınları içeren belirli alanlarıdır. Üç ana segment bulunmaktadır.

  • Code Segment − Yürütülecek tüm talimatları içerir. 16-bitlik bir Kod Segmenti kaydedici veya CS kaydedici, kod segmentinin başlangıç adresini saklar.
  • Data Segment − Veri, sabitler ve çalışma alanlarını içerir. 16-bitlik bir Veri Segmenti kaydedici veya DS kaydedici, veri segmentinin başlangıç adresini saklar.
  • Stack Segment − Prosedürlerin veya alt programların verilerini ve dönüş adreslerini içerir. ‘Yığın’ veri yapısı olarak uygulanmıştır. Yığın Segmenti kaydedici veya SS kaydedici, yığının başlangıç adresini saklar.

Basit Komutlar

mov — değişiklik yapmadan veriyi bir yerden başka bir yere taşır.

mov hedef, kaynak

lea — “load effective address,” dolaylı adresi hesaplar ve bu adresi (bellek içeriği değil) hedefte saklar.

lea hedef, değer

jmp — CPU’ya yeni bir konuma atlamasını söyler, yürütüm akışını değiştirerek komut işaretçisi kaydedicisini değiştirir.

jmp hedef

add — Aritmetik toplama, belirtilen değeri hedefteki değere ekler ve hedefi sonuçla değiştirir.

add hedef, değer

sub — Aritmetik çıkarma, toplama işlemine benzer.

sub hedef, değer

inc — Hedefi bir arttırır.

inc hedef

dec — Hedefi bir azaltır.

dec hedef


Or, and, ve xor gibi mantıksal işlemler, add ve sub gibi aynı adresleme modlarına sahiptir.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Bu site, istenmeyenleri azaltmak için Akismet kullanıyor. Yorum verilerinizin nasıl işlendiği hakkında daha fazla bilgi edinin.