PE文件格式詳解,第三講,可選頭文件格式,以及節表


          PE文件格式詳解,第三講,可選頭文件格式,以及節表

 

作者:IBinary
出處:http://www.cnblogs.com/iBinary/
版權所有,歡迎保留原文鏈接進行轉載:)

一丶可選頭結構以及作用

 

 
         

typedef struct _IMAGE_OPTIONAL_HEADER {


    WORD    Magic;                  /*機器型號,判斷是PE是32位還是64位*/
    BYTE    MajorLinkerVersion;          /*連接器版本號高版本*/
    BYTE    MinorLinkerVersion;          /*連接器版本號低版本,組合起來就是 5.12 其中5是高版本,C是低版本*/
    DWORD   SizeOfCode;               /*代碼節的總大小(512為一個磁盤扇區)*/
    DWORD   SizeOfInitializedData;        /*初始化數據的節的總大小,也就是.data*/
    DWORD   SizeOfUninitializedData;       /*未初始化數據的節的大小,也就是 .data ? */
    DWORD   AddressOfEntryPoint;          /*程序執行入口(OEP) RVA(相對偏移)*/
    DWORD   BaseOfCode;               /*代碼的節的起始RVA(相對偏移)也就是代碼區的偏移,偏移+模塊首地址定位代碼區*/
    DWORD   BaseOfData;               /*數據結的起始偏移(RVA),同上*/
    DWORD   ImageBase;               /*程序的建議模塊基址(意思就是說作參考用的,模塊地址在哪里)*/
DWORD SectionAlignment;           /*內存中的節對齊*/ DWORD FileAlignment;             /*文件中的節對齊*/ WORD MajorOperatingSystemVersion;    /*操作系統版本號高位*/ WORD MinorOperatingSystemVersion;    /*操作系統版本號低位*/ WORD MajorImageVersion;          /*PE版本號高位*/ WORD MinorImageVersion;          /*PE版本號低位*/ WORD MajorSubsystemVersion;        /*子系統版本號高位*/ WORD MinorSubsystemVersion;        /*子系統版本號低位*/ DWORD Win32VersionValue;          /*32位系統版本號值,注意只能修改為4 5 6表示操作系統支持nt4.0 以上,5的話依次類推*/ DWORD SizeOfImage;             /*整個程序在內存中占用的空間(PE映尺寸)*/ DWORD SizeOfHeaders;            /*所有頭(頭的結構體大小)+節表的大小*/ DWORD CheckSum;               /*校驗和,對於驅動程序,可能會使用*/ WORD Subsystem;              /*文件的子系統 :重要*/ WORD DllCharacteristics;         /*DLL文件屬性,也可以成為特性,可能DLL文件可以當做驅動程序使用*/ DWORD SizeOfStackReserve;        /*預留的棧的大小*/ DWORD SizeOfStackCommit;         /*立即申請的棧的大小(分頁為單位)*/ DWORD SizeOfHeapReserve;        /*預留的堆空間大小*/ DWORD SizeOfHeapCommit;         /*立即申請的堆的空間的大小*/ DWORD LoaderFlags;            /*與調試有關*/ DWORD NumberOfRvaAndSizes;       /*下面的成員,數據目錄結構的項目數量*/ IMAGE_DATA_DIRECTORY DataDirectory[16];/*數據目錄,默認16個,16是宏,這里方便直接寫成16*/ } IMAGE_OPTIONAL_HEADER32,
*PIMAGE_OPTIONAL_HEADER32;

需要注意的成員:

1.PE類型

這個有宏定義了

#define IMAGE_NT_OPTIONAL_HDR32_MAGIC      0x10b    /*32位PE*/
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC      0x20b    /*64位PE*/
#define IMAGE_ROM_OPTIONAL_HDR_MAGIC       0x107    /*其它,單片機*/

 

2丶.OEP,程序執行入口位置.

我們利用昨天寫的程序,可以完成一個反調試.

思路:

1.修改OEP偏移,置為0位置處(也就是MZ的位置)

2.在MZ位置后面添加我們自己的代碼

3.添加完成之后,繼續跳到以前OEP的位置.

 

首先,看PE文件的值,OEP的偏移位置是00001008偏移,那么OD調試,看下位置在哪里.

我們知道了入口偏移是00401008位置,那么我們就知道了模塊首地址是00400000

公式  00401008 - 1008 = 00400000  因為我們知道1008是相對於模塊地址來的所以可以求出模塊地址,我們跳轉過去

可以看出,前邊正好是4D5A,那么我們可以修改一下,添加自己的代碼,首先4D5A正好是匯編代碼

那么我們可以去平棧,然后跳轉到我們以前的OEP位置.

修改成下邊那樣

 

首先,我們以前講DOS頭的時候說過,如果這個EXE文件運行在32位系統下,那么DOS頭中就地一個和最后一個成員有用,那么后面我們隨便修改.

上面代碼很簡單,首先棧平衡,然后跳轉到我們以前代碼執行位置.

文件中(PE)我們把后面的二進制都修改為我們的代碼

入后偏移(RVA)修改為0000000

運行我們的程序,和調試我們的程序

運行程序:

可以正常運行

調試程序:

程序出錯,反調試了

二丶數據目錄

數據目錄,主要是存放各種表格的,看下

typedef struct _IMAGE_DATA_DIRECTORY {
    DWORD   VirtualAddress;        虛擬地址(表格位置)
    DWORD   Size;              大小
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

關於表格,這里有很多宏定義.

#define IMAGE_DIRECTORY_ENTRY_EXPORT          0   // Export Directory
#define IMAGE_DIRECTORY_ENTRY_IMPORT          1   // Import Directory
#define IMAGE_DIRECTORY_ENTRY_RESOURCE        2   // Resource Directory
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION       3   // Exception Directory
#define IMAGE_DIRECTORY_ENTRY_SECURITY        4   // Security Directory
#define IMAGE_DIRECTORY_ENTRY_BASERELOC       5   // Base Relocation Table
#define IMAGE_DIRECTORY_ENTRY_DEBUG           6   // Debug Directory
//      IMAGE_DIRECTORY_ENTRY_COPYRIGHT       7   // (X86 usage)
#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE    7   // Architecture Specific Data
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR       8   // RVA of GP
#define IMAGE_DIRECTORY_ENTRY_TLS             9   // TLS Directory
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG    10   // Load Configuration Directory
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT   11   // Bound Import Directory in headers
#define IMAGE_DIRECTORY_ENTRY_IAT            12   // Import Address Table
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT   13   // Delay Load Import Descriptors
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14   // COM Runtime descriptor

它是按照位來計算的.    

 三丶節表

在NT頭下面,緊跟着的是節表

節表是什么意思? 可以理解為分區,就是幾個區

那么意思就是保存了區

那么我們猜想一下,都需要什么成員

地址

地址大小

文件中的地址

文件大小

等等....

看下節表的信息吧

typedef struct _IMAGE_SECTION_HEADER {
    BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];  /*節區的名字*/
    union {
            DWORD   PhysicalAddress;
            DWORD   VirtualSize;        /*節區的尺寸*/
    } Misc;
    DWORD   VirtualAddress;          /*虛擬地址 節區的RVA地址(偏移)*/
    DWORD   SizeOfRawData;           /*在文件中對齊的尺寸*/
    DWORD   PointerToRawData;         /*在文件中的偏移*/
    DWORD   PointerToRelocations;      /*在OBJ文件中使用*/
    DWORD   PointerToLinenumbers;      /*行號表位置,調試使用*/
    WORD    NumberOfRelocations;      /*在OBJ文件中使用*/
    WORD    NumberOfLinenumbers;      /*行號表的數量*/
    DWORD   Characteristics;        /*節的屬性*/
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

重要成員

1.節的尺寸

2.虛擬地址,RVA(偏移)

3.文件中的大小

4.文件中的偏移

5.節的屬性

其中節的屬性有很多,(表達這個分區是一個什么樣的分區,代碼區,常量區等等)

看下宏定義(按位來的,可以看下第二講的最后關於文件屬性的講解,其中講解了這個怎么按位來)

#define IMAGE_SCN_CNT_CODE                   0x00000020  // Section contains code.
#define IMAGE_SCN_CNT_INITIALIZED_DATA       0x00000040  // Section contains initialized data.
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA     0x00000080  // Section contains uninitialized data.

#define IMAGE_SCN_LNK_OTHER                  0x00000100  // Reserved.
#define IMAGE_SCN_LNK_INFO                   0x00000200  // Section contains comments or some other type of information.
//      IMAGE_SCN_TYPE_OVER                  0x00000400  // Reserved.
#define IMAGE_SCN_LNK_REMOVE                 0x00000800  // Section contents will not become part of image.
#define IMAGE_SCN_LNK_COMDAT                 0x00001000  // Section contents comdat.
//                                           0x00002000  // Reserved.
//      IMAGE_SCN_MEM_PROTECTED - Obsolete   0x00004000
#define IMAGE_SCN_NO_DEFER_SPEC_EXC          0x00004000  // Reset speculative exceptions handling bits in the TLB entries for this section.
#define IMAGE_SCN_GPREL                      0x00008000  // Section content can be accessed relative to GP

#define IMAGE_SCN_LNK_NRELOC_OVFL            0x01000000  // Section contains extended relocations.
#define IMAGE_SCN_MEM_DISCARDABLE            0x02000000  // Section can be discarded.
#define IMAGE_SCN_MEM_NOT_CACHED             0x04000000  // Section is not cachable.
#define IMAGE_SCN_MEM_NOT_PAGED              0x08000000  // Section is not pageable.
#define IMAGE_SCN_MEM_SHARED                 0x10000000  // Section is shareable.
#define IMAGE_SCN_MEM_EXECUTE                0x20000000  // Section is executable.
#define IMAGE_SCN_MEM_READ                   0x40000000  // Section is readable.
#define IMAGE_SCN_MEM_WRITE                  0x80000000  // Section is writeable.

其中保留的沒有寫.

作者:IBinary
出處:http://www.cnblogs.com/iBinary/
版權所有,歡迎保留原文鏈接進行轉載:)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM