Murat ERDEM - Personal Research Blog




PE Files - 0x03

July 23, 2020

Bir önceki bölümde bilgilerine erişmek istediğimiz PE dosyamızı ayırdığımız bellek alanına yüklemeyi başarmıştık şimdi kolaylıkla parçalayıp ilgili bilgileri alabiliriz.

İlk olarak PE dosya yapısına gene olarak bakalım ve içerisindeki bölümlere bir göz atalım.

(PE dosyaları genel yapısı)

Burada bir exe dosyasının genel yapısını görebiliriz yukarıdan aşağı ilk alanımız MZ Header alanı bu alan içerisinde MZ başlığını ve dosya ile ilgili bazı bilgileri saklar. Bir exe dosyasını CFF ile açarsak bu alanın içerisinde sakladığı bilgileri görebiliriz.

Bu alan 64 bayt büyüklüğündedir ve bizim için iki önemli bilgiyi sağlar birisi MZ başlığı bu exe dosyasının olmazsa olmazlarındandır ve hexadecimal karşılığı olarak 0x5A4D değerine eşittir. Bir diğer önemli bilgi ise e_flanew verisidir bu bizim PE imzasının bulunduğu alana erişimimiz için gereklidir. Biz PE file imzasının bulunduğu alana erişmek için Image Base adresine e_lfanew değerini ekleyerek PE imzamıza ulaşabiliriz. Burada Image Base adresi bizim bilgilerini elde etmek için hafıza alanımıza yüklediğimiz PE dosyasının başlangıç adresi yani fileData pointeri ile gösterilmektedir.

Biz bu verileri nasıl elde ederiz konusunda bizim kullanacağımız yapı PIMAGE_DOS_HEADER yapısıdır. Burada ben visual stdio kullandığım için herhangi bir hata almadım ancak siz bir hata alırsanız projenize winnt.h kütüphanesini ekleyebilirsiniz. PIMAGE_DOS_HEADER yapısının tanımlanması aşağıdaki gibidir.

Biz tip dönüşümü ile bu yapıyı kolay bir şekilde dosyamızın MZ Header alanına eşitleyebilir ve içerisindeki verilere erişebiliriz.

    
        PIMAGE_DOS_HEADER PImageHeader = (PIMAGE_DOS_HEADER)fileData;
        PImageHeaderWriter(PImageHeader);
    

Burada aldığımız verileri PIMageHeaderWriter fonksiyonu ile ekrana yazdırdık. Bu fonksiyonlar kodlarımızı daha anlaşılır kılmak açısından önemli olmaktadır. PImageHeaderWriter fonksiyonu aşağıdaki gibidir.

    
        void PImageHeaderWriter(PIMAGE_DOS_HEADER PImageHeader) {
            cout << endl << "______PIMAGE_DOS_HEADER______" << endl;
            cout << "e_magic : " << hex << PImageHeader->e_magic << endl;
            cout << "e_cblp : " << hex << PImageHeader->e_cblp << endl;
            cout << "e_cp : " << hex << PImageHeader->e_cp << endl;
            cout << "e_crlc : " << hex << PImageHeader->e_crlc << endl;
            cout << "e_cparhdr : " << hex << PImageHeader->e_cparhdr << endl;
            cout << "e_minalloc : " << hex << PImageHeader->e_minalloc << endl;
            cout << "e_maxalloc : " << hex << PImageHeader->e_maxalloc << endl;
            cout << "e_ss : " << hex << PImageHeader->e_ss << endl;
            cout << "e_sp : " << hex << PImageHeader->e_sp << endl;
            cout << "e_csum : " << hex << PImageHeader->e_csum << endl;
            cout << "e_ip : " << hex << PImageHeader->e_ip << endl;
            cout << "e_cs : " << hex << PImageHeader->e_cs << endl;
            cout << "e_lfarlc : " << hex << PImageHeader->e_lfarlc << endl;
            cout << "e_ovno : " << hex << PImageHeader->e_ovno << endl;
            cout << "e_res : " << hex << PImageHeader->e_res[3] << endl;
            cout << "e_oemid : " << hex << PImageHeader->e_oemid << endl;
            cout << "e_oeminfo : " << hex << PImageHeader->e_oeminfo << endl;
            cout << "e_res2 : " << hex << PImageHeader->e_res2[9] << endl;
            cout << "e_lfanew : " << hex << PImageHeader->e_lfanew << endl;
            cout << endl << endl << endl;
        }
    

Kodumuzu derleyip çalıştırsak aşağıdaki gibi bir çıktı verecektir. Bu çıktı bizim ilk başta CFF’teki değerler ile aynı olduğunu görebiliriz.

Bu alanın bilgilerini elde etmeyi başardık, PE dosyası genel yapısını gösteren resmimizdeki Real Mode Stub Program alanı ise aslında önemsiz bir alandır ancak bir dosyanın exe dosyası olup olmadığının anlaşılmasında kullanılabilir. Bu alanın amacı PE dosyamız eski işletim sistemlerinden olan DOS sisteminde çalıştırılmak istenirse PE dosyamız uyumsuzluk nedeniyle çalışmayacağı için bu alan çalışır ve ekrana küçük bir hata mesajı basar. hex kodlarına bakarsak bu mesajı görebiliriz.

(This program cannot be run in DOS mode.)