PDA

Orijinalini görmek için tıklayınız : Portable Executable (PE) Virüsleri


SUSKUN
02-01-2006, 11:39 PM
Portable Executable formatı aslında Un*x'in COFF (Common Object File Format ) formatını izleyen bir formattır. COFF formatının eski DOS programlarıyla uyumluluğunu sağlamak için biraz değişiklik yapılmış, böylece ortaya PE formatı çıkmış. M$'in işleri işte..

PE formatına geçmeden önce PE programlarının yapısına genel olarak bir bakalım.

DOS 2 Uyumlu EXE Başlığı (Aynı zamanda ImageBase Header)
Kullanılmıyor
OEM tanıtıcısı, OEM Bilgisi ve PE Header'ın ofseti
DOS 2.0 Stub, DOS kodu ve Relocation tablosu (Buraya kadar olan kısım DOS uyumluluğu için konulmuştur)
Kullanılmıyor
Portable EXE (PE) Header
Obje Tablosu
Veri Sayfaları : Import, Export, Fixup,Resource ve Debug Info

Bir portable executable da tıpkı bir DOS executable gibi başlar.

Uzunluk Açıklama
word 'MZ' veya 'ZM', DOS EXE tanıtıcısı
word Programın belleğe yüklenecek miktarı MOD 512
word Programın belleğe yüklenecek miktarı DIV 512
word Yeniden konumlandırılacak adres sayısı
word Exe başlığı oluşturan paragraf sayısı
word Minimum gerekli ek paragraf sayısı
word Maksimum gerekli ek paragraf sayısı
word Program çalıştırılınca SS içeriği
word Program çalıştırılınca SP içeriği
word Checksum
word Program çalışınca IP değeri
word Program çalışınca CS içeriği
word Yeniden konumlandırma tablosunun adresi
word Overlay sayısı
4 byte Ayrılmış
word OEM tanıcıtıcısı
word OEM bilgisi
10 word Ayrılmış
dword NE/PE.. başlığın adresi

Bu klasik DOS başlığından sonra bir kod yer alır. Bu kodun görevi 'Bu programı çalıştırmak için Windows gereklidir' gibi bir mesaj yazmaktır. Bu kodun arkasında yer alan PE header yapısı şu şekildedir.

Uzunluk Açıklama
dword Tanıtıcı Katar (PE+#0+#0)
word Programın çalışması için gerekli en düşük CPU modeli
word Objeler
dword Tarih ve saat bilgisi
2 dword Ayrılmış
word NT Başlık boyutu (Optional header)
word İşaretler (Flags)

Portable executable header arkasından optional header/NT header denen bir tablo daha yer almaktadır. Bu tablo da şu biçimdedir.

Uzunluk Açıklama
word NT Header tanıtıcısı (Optional header)
byte Linker sürümünün noktanın solundaki sayısı
byte Linker sürümünün noktanın sağındaki sayısı
3 dword Ayrılmış
dword EntryPoint RVA
2 dword Ayrılmış
dword Imaj tabanı
dword Object align
dword File align
word İşletim sisteminin noktadan önceki kısmı
word İşletim sisteminin noktadan sonraki kısmı
word User'ın noktadan önceki kısmı
word User'ın noktadan sonraki kısmı
word Subsystem major
word Subsystem minor
dword Ayrılmış
dword Imaj boyu
dword Başlık boyu (MZ header'da dahil olarak)
dword Dosya kontrolü (Checksum)
word Subsystem
word DLL bayrakları
dword Ayrılmış stack boyu
dword stack commit size
dword Ayrılmış heap boyu
dword heap commit size
dword Ayrılmış
dword RVA boyutları
dword EXPORT Tablosunun göreceli konumu
dword EXPORT Datasının toplam boyu
dword IMPORT tablosunun göreceli konumu
dword Toplam IMPORT Data boyutu
dword Resource Table göreceli konumu
dword Toplam Resource Data boyutu
dword Exception table göreceli konumu
dword Toplam Exception data boyutu
dword Security Table göreceli konumu
dword Toplam Secutity data boyutu
dword Fixup table göreceli konumu
dword Toplam Fixup data boyutu
dword Debug table göreceli konumu
dword Toplam debug dizinleri
dword Imaj tanıtım göreceli konumu
dword Toplam tanımlama boyu
dword Makinaya bağlı göreceli konum
dword Makinaya bağlı boyut
dword Thread yerel depo göreceli konumu
dword Toplam TYD boyutu

Not: PE Header içindeki değeri 0 olan göreceli adresler, o alanın kullanılmadığı anlamına gelmektedir.

TANITICI KATAR : Değeri "PE/0/0" şeklindedir.Bu ifade PE Header'ı tanıtır.PE harflerini 2 adet 00 baytı izler.

CPU TiPi : Bu word programın çalışabilmesi için gerekli en düşük CPU modelini bildirir.Buna göre mümkün değerler şunlardır.

0000h : Bilinmiyor
014ch : 80386
014dh : 80486
014eh : 80586 (Pentium)
0162h : MIPS Mark I (R2000, R3000)
0163h : MIPS Mark II (R6000)
0166h : MIPS Mark III (R4000)

SUBSYTEM :

0000h : Bilinmiyor
0001h : Doğal
0002h : Windows GUI
0003h : Windows Karakteri
0004h : OS/2 Karakteri
0005h : Posix Karakteri

Optional headerdan sonra da object table yer alır. Bu tablo portable executable içinde yer alan her objecte ait veriler içerir. Object tablosu şu biçimdedir.

Uzunluk Açıklama
8 byte Object adı
dword Fiziksel adres
dword Sanal boyut
dword Sanal adres
dword RawData boyutu
dword RawData pointerı
dword Yerleşim pointerı
dword Satır numaraları pointerı
word Yerleşim sayısı
word Satır numarası sayısı
dword Karakteristik

Bu objectler genelde aşağıdaki biçimde bulunur. Burada yazdığım bölüm adları kesin değildir. İsimleri farklı olabilir, bazı bölümler hiç olmayabilir veya bunlardan başka bölümler de olabilir.

Çalıştırılabilir kod bölümü .text
Veri bölümleri .data , .rdata , .bss
Resource bölümü .rsrc
Export Data bölümü .edata
Import Data bölümü .idata
DebugInfo bölümü .debug

Portable Executable programları neredeyse tanıdık sayılır. Şimdi de programa giriş noktasını nasıl bulabileceğimizi görelim:

Öncelikle bize Optional header içerisinde yer alan EntryPoint_RVA değeri gerekiyor.

EntryPoint_RVA = 00050200 hex

Bölüm adı Sanal Adresi (RVA) Fiziksel Adresi
.text 00010000 00000600
.icode 00020000 00001C00
.data 00030000 00001DF0
.idata 00040000 00001E50
CODE 00050000 00002000
.debug 00070000 00004000

EntryPoint_RVA sanal bir adres olduğundan bu durumda bizim ilgilenmemiz gereken alan da haliyle sanal adresler olmalıdır. Bu yüzden EntryPoint_RVA adresinin hangi bölümlerin sanal adreslerinin arasında kaldığını tespit etmeliyiz. Sanal adresleri kontrol ettiğimizde 50200 hex adresi 50000 ve 70000 arasında kaldığından programın çalışmaya başlayacağı bölüm CODE bölümüdür. Program, CODE bölümü içerisinde 50200-50000=200 ofsetinden itibaren çalıştırılmaya başlanacaktır.