• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Tiany 's Blog

            奮斗的路上肯定會(huì)遇到很多困難 該不該繼續(xù)?

              C++博客 :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
              15 Posts :: 1 Stories :: 28 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(1)

            我參與的團(tuán)隊(duì)

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            這個(gè)IMAGE_NT_HEADERS其實(shí)就是PE相關(guān)結(jié)構(gòu)的映像頭,NT據(jù)我揣測(cè)應(yīng)該是New Technology的縮寫,區(qū)分于DOS WIN9X的新技術(shù),您老要是非覺(jué)得是NTR什么的也沒(méi)關(guān)系。

            IMAGE_NT_HEADERS的結(jié)構(gòu)是這個(gè)樣子的

            IMAGE_NT_HEADERS STRUCT 

            +0h        DWORD    Signature
            +4h          IMAGE_FILE_HEADER    FileHeader
            +18h        IMAGE_OPTIONAL_HEADER32    OptionalHeader
            }
             IMAGE_NT_HEADERS ENDS

             


            其中包含兩個(gè)子結(jié)構(gòu)體,和一個(gè)標(biāo)志。
            其中Signature字段被設(shè)置成00004550h ,ASCII碼為PE00 ,標(biāo)志著PE頭文件的開(kāi)始。上一篇中 DOS頭結(jié)構(gòu)體中的e_lfanew正是指向這里。

             


            IMAGE_FILE_HEAD

            ER這個(gè)結(jié)構(gòu)是這樣的

            typedef struct _IMAGE_FILE_HEADER
            {
            +04h WORD Machine; // 運(yùn)行平臺(tái)
            +06h WORD NumberOfSections; // 文件的區(qū)塊數(shù)目
            +08h DWORD TimeDateStamp; // 文件創(chuàng)建日期和時(shí)間
            +0Ch DWORD PointerToSymbolTable; // 指向符號(hào)表(主要用于調(diào)試)
            +10h DWORD NumberOfSymbols; // 符號(hào)表中符號(hào)個(gè)數(shù)(同上)
            +14h WORD SizeOfOptionalHeader; // IMAGE_OPTIONAL_HEADER32 結(jié)構(gòu)大小
            +16h WORD Characteristics; // 文件屬性
            }
            IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

            Machine 代表了CPU的類型 ,定義在windows.h中

            #define IMAGE_FILE_MACHINE_UNKNOWN   0
              
            #define IMAGE_FILE_MACHINE_I386    0x014c // Intel 386.
              
            #define IMAGE_FILE_MACHINE_R3000    0x0162 // MIPS little-endian, 0x160 big-endian
              
            #define IMAGE_FILE_MACHINE_R4000    0x0166 // MIPS little-endian
              
            #define IMAGE_FILE_MACHINE_R10000   0x0168 // MIPS little-endian
              
            #define IMAGE_FILE_MACHINE_WCEMIPSV2  0x0169 // MIPS little-endian WCE v2
              
            #define IMAGE_FILE_MACHINE_ALPHA    0x0184 // Alpha_AXP
              
            #define IMAGE_FILE_MACHINE_POWERPC   0x01F0 // IBM PowerPC Little-Endian
              
            #define IMAGE_FILE_MACHINE_SH3     0x01a2 // SH3 little-endian
              
            #define IMAGE_FILE_MACHINE_SH3E    0x01a4 // SH3E little-endian
              
            #define IMAGE_FILE_MACHINE_SH4     0x01a6 // SH4 little-endian
              
            #define IMAGE_FILE_MACHINE_ARM     0x01c0 // ARM Little-Endian
              
            #define IMAGE_FILE_MACHINE_THUMB    0x01c2
              
            #define IMAGE_FILE_MACHINE_IA64    0x0200 // Intel 64
              
            #define IMAGE_FILE_MACHINE_MIPS16   0x0266 // MIPS
              
            #define IMAGE_FILE_MACHINE_MIPSFPU   0x0366 // MIPS
              
            #define IMAGE_FILE_MACHINE_MIPSFPU16  0x0466 // MIPS
              
            #define IMAGE_FILE_MACHINE_ALPHA64   0x0284 // ALPHA64
              
            #define IMAGE_FILE_MACHINE_AXP64    IMAGE_FILE_MACHINE_ALPHA64


            NumberOfSection 代表區(qū)塊的數(shù)目,區(qū)塊表緊跟在IMAGE_NT_HEADERS后面,區(qū)塊表大概是一個(gè)鏈表結(jié)構(gòu),鏈表長(zhǎng)度由NumberOfSection的數(shù)值決定。

            TimeDataStamp 表明文件的創(chuàng)建時(shí)間

            SizeOfOptionalHeader 是IMAGE_NT_HEADERS的另一個(gè)子結(jié)構(gòu)IMAGE_OPTIONAL_HEADER的大小,32位的PE文件這個(gè)值一般是00E0,64位的PE文件一般是00F0

            Characteristics 代表文件的

            屬性EXE文件一般是0100h DLL文件一般是210Eh,多種屬性可以用或運(yùn)算同時(shí)擁有。

            #define IMAGE_FILE_RELOCS_STRIPPED      0x0001 // 重定位信息被移除
            #define IMAGE_FILE_EXECUTABLE_IMAGE     0x0002 // 文件可執(zhí)行
            #define IMAGE_FILE_LINE_NUMS_STRIPPED    0x0004 // 行號(hào)被移除
            #define IMAGE_FILE_LOCAL_SYMS_STRIPPED    0x0008 // 符號(hào)被移除
            #define IMAGE_FILE_AGGRESIVE_WS_TRIM     0x0010 // Agressively trim working set
            #define IMAGE_FILE_LARGE_ADDRESS_AWARE    0x0020 // 程序能處理大于2G的地址
            #define IMAGE_FILE_BYTES_REVERSED_LO     0x0080 // Bytes of machine word are reversed.
            #define IMAGE_FILE_32BIT_MACHINE       0x0100 // 32位機(jī)器
            #define IMAGE_FILE_DEBUG_STRIPPED      0x0200 // .dbg文件的調(diào)試信息被移除
            #define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP  0x0400 // 如果在移動(dòng)介質(zhì)中,拷到交換文件中運(yùn)行
            #define IMAGE_FILE_NET_RUN_FROM_SWAP     0x0800 // 如果在網(wǎng)絡(luò)中,拷到交換文件中運(yùn)行
            #define IMAGE_FILE_SYSTEM          0x1000 // 系統(tǒng)文件
            #define IMAGE_FILE_DLL            0x2000 // 文件是一個(gè)dll
            #define IMAGE_FILE_UP_SYSTEM_ONLY      0x4000 // 文件只能運(yùn)行在單處理器上
            #define IMAGE_FILE_BYTES_REVERSED_HI     0x8000 // Bytes of machine word are reversed.

            下面來(lái)編寫一個(gè)程序來(lái)顯示一下這個(gè)結(jié)構(gòu)體
            #include "windows.h" //PE的那一套結(jié)構(gòu)體大多都是定義在這個(gè)頭文件里的
            #include "stdio.h"

            int main(int argc, char* argv[])
            {
                FILE
            *p;
                LONG e_lfanew; 
            //指向IMAGE_NT_HEADERS32結(jié)構(gòu)在文件中的偏移
                IMAGE_FILE_HEADER myfileheader;
               
                p
            = fopen("test.exe","r+b");
                
            if(p == NULL)return -1;

                fseek(p,
            0x3c,SEEK_SET);
                fread(
            &e_lfanew,4,1,p);
                fseek(p,e_lfanew
            +4,SEEK_SET); //指向IMAGE_FILE_HEADER結(jié)構(gòu)的偏移 PE的標(biāo)志位是DWORD占4字節(jié)
                fread(&myfileheader,sizeof(myfileheader),1,p);

                printf(
            "IMAGE_FILE_HEADER結(jié)構(gòu):\n");
                printf(
            "Machine       : %04X\n",myfileheader.Machine);
                printf(
            "NumberOfSections   : %04X\n",myfileheader.NumberOfSections);
                printf(
            "TimeDateStamp    : %08X\n",myfileheader.TimeDateStamp);
                printf(
            "PointerToSymbolTable : %08X\n",myfileheader.PointerToSymbolTable);
                printf(
            "NumberOfSymbols   : %08X\n",myfileheader.NumberOfSymbols);
                printf(
            "SizeOfOptionalHeader : %04X\n",myfileheader.SizeOfOptionalHeader);
                printf(
            "Characteristics   : %04X\n",myfileheader.Characteristics);
                getch();
                
            return 0;
            }


            總的來(lái)說(shuō)IMAGE_FILE_HEADER是記錄文件的各種信息的

             

            下面說(shuō)一下IMAGE_OPTIONAL_HEADER結(jié)構(gòu),他是一個(gè)可選結(jié)構(gòu),是對(duì)IMAGE_FILE_HEADER的一個(gè)補(bǔ)充,當(dāng)然很多情況下它是必須的。


            typedef struct _IMAGE_OPTIONAL_HEADER
            {
            //
            // Standard fields.
            //
            +18h WORD Magic; // 標(biāo)志字, ROM 映像(0107h),普通可執(zhí)行文件(010Bh)
            +1Ah BYTE MajorLinkerVersion; // 鏈接程序的主版本號(hào)
            +1Bh BYTE MinorLinkerVersion; // 鏈接程序的次版本號(hào)
            +1Ch DWORD SizeOfCode; // 所有含代碼的節(jié)的總大小
            +20h DWORD SizeOfInitializedData; // 所有含已初始化數(shù)據(jù)的節(jié)的總大小
            +24h DWORD SizeOfUninitializedData; // 所有含未初始化數(shù)據(jù)的節(jié)的大小
            +28h DWORD AddressOfEntryPoint; // 程序執(zhí)行入口RVA
            +2Ch DWORD BaseOfCode; // 代碼的區(qū)塊的起始RVA
            +30h DWORD BaseOfData; // 數(shù)據(jù)的區(qū)塊的起始RVA
            //
            // NT additional fields. 以下是屬于NT結(jié)構(gòu)增加的領(lǐng)域。
            //
            +34h DWORD ImageBase; // 程序的首選裝載地址
            +38h DWORD SectionAlignment; // 內(nèi)存中的區(qū)塊的對(duì)齊大小
            +3Ch DWORD FileAlignment; // 文件中的區(qū)塊的對(duì)齊大小
            +40h WORD MajorOperatingSystemVersion; // 要求操作系統(tǒng)最低版本號(hào)的主版本號(hào)
            +42h WORD MinorOperatingSystemVersion; // 要求操作系統(tǒng)最低版本號(hào)的副版本號(hào)
            +44h WORD MajorImageVersion; // 可運(yùn)行于操作系統(tǒng)的主版本號(hào)
            +46h WORD MinorImageVersion; // 可運(yùn)行于操作系統(tǒng)的次版本號(hào)
            +48h WORD MajorSubsystemVersion; // 要求最低子系統(tǒng)版本的主版本號(hào)
            +4Ah WORD MinorSubsystemVersion; // 要求最低子系統(tǒng)版本的次版本號(hào)
            +4Ch DWORD Win32VersionValue; // 莫須有字段,不被病毒利用的話一般為0
            +50h DWORD SizeOfImage; // 映像裝入內(nèi)存后的總尺寸
            +54h DWORD SizeOfHeaders; // 所有頭 + 區(qū)塊表的尺寸大小
            +58h DWORD CheckSum; // 映像的校檢和
            +5Ch WORD Subsystem; // 可執(zhí)行文件期望的子系統(tǒng)
            +5Eh WORD DllCharacteristics; // DllMain()函數(shù)何時(shí)被調(diào)用,默認(rèn)為 0
            +60h DWORD SizeOfStackReserve; // 初始化時(shí)的棧大小
            +64h DWORD SizeOfStackCommit; // 初始化時(shí)實(shí)際提交的棧大小
            +68h DWORD SizeOfHeapReserve; // 初始化時(shí)保留的堆大小
            +6Ch DWORD SizeOfHeapCommit; // 初始化時(shí)實(shí)際提交的堆大小
            +70h DWORD LoaderFlags; // 與調(diào)試有關(guān),默認(rèn)為 0
            +74h DWORD NumberOfRvaAndSizes; // 下邊數(shù)據(jù)目錄的項(xiàng)數(shù),這個(gè)字段自Windows NT 發(fā)布以來(lái) // 一直是16
            +78h IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
            // 數(shù)據(jù)目錄表
            }
            IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

            這個(gè)結(jié)構(gòu)東西各種多啊···非常蛋疼,不過(guò)很多都是optional的,可以不用管他們,重要的就那么幾個(gè)。

            AddressOfEntryPoint 指出文件執(zhí)行時(shí)的入口地址,是一個(gè)RVA地址,就是大家常說(shuō)的OEP,常常各種尋找的OEP,如果你有什么代碼要先于程序主體執(zhí)行,只需要將這個(gè)入口指向這段代碼就行啦~

            ImageBase 指向文件的優(yōu)先裝入地址,一般情況EXE文件不需要重定位,DLL文件可能需要重定位。

            Se

            ctionAlignment 和 FileAlignment 確定了內(nèi)存中的節(jié)對(duì)齊單位和在磁盤中的節(jié)對(duì)齊單位。

            DataDirectory 成員是一個(gè)比較牛逼的成員,它由16個(gè)IMAGE_DATA_DIRCTORY結(jié)構(gòu)組成,用來(lái)定義多種不通用處的數(shù)據(jù)塊。

            這個(gè)結(jié)構(gòu)體的內(nèi)容很簡(jiǎn)單

            typedef struct _IMAGE_DATA_DIRECTORY {
              DWORD  VirtualAddress; 相對(duì)虛擬地址
              DWORD  Size;      大小
            }
            IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

            只有相對(duì)虛擬地址和大小兩個(gè)成員。

            IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];

            IMAGE_NUMBEROF_DIRECTORY_ENTRIES 的值代表了數(shù)據(jù)塊的用途

            #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
            #defin e IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT  13  // Delay Load Import Descriptors
            #define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14  // COM Runtime descriptor


            最后把這些結(jié)構(gòu)·讀出來(lái)看一看。

            #include "windows.h"
            #include
            "stdio.h"

            int main(int argc, char* argv[])
            {
            FILE
            *p;
            unsigned
            long Signature;
            IMAGE_FILE_HEADER myfileheader;
            IMAGE_DOS_HEADER mydosheader;
            IMAGE_OPTIONAL_HEADER myoptionalheader;

            p
            = fopen("test.exe","r+b");
            if(p == NULL)return -1;

            fread(
            &mydosheader,sizeof(mydosheader),1,p);
            fseek(p,mydosheader.e_lfanew,SEEK_SET);
            fread(
            &Signature,sizeof(Signature),1,p);

            fseek(p,mydosheader.e_lfanew
            +sizeof(Signature),SEEK_SET);//指向IMAGE_FILE_HEADER結(jié)構(gòu)的偏移
            fread(&myfileheader,sizeof(myfileheader),1,p);

            fseek(p,mydosheader.e_lfanew
            +sizeof(Signature)+sizeof(myfileheader),SEEK_SET);
            fread(
            &myoptionalheader,sizeof(myoptionalheader),1,p);

            printf(
            "%X\n",mydosheader.e_lfanew);

            printf(
            "Signature : %04X\n",Signature);
            printf(
            "IMAGE_FILE_HEADER結(jié)構(gòu):\n");
            printf(
            "Machine : %04X\n",myfileheader.Machine);

            printf(
            "IMAGE_OPTIONALHEADER_HEADER結(jié)構(gòu):\n");
            printf(
            "Magic       : %04X\n",myoptionalheader.Magic);
            由于這個(gè)IMAGE_OPENTIONAL_HEADER結(jié)構(gòu)成員太多,我就不都打出來(lái)了,Magic的值一般為010bH,由此可以判頓讀取出的結(jié)構(gòu)是否正確。
            posted on 2012-04-11 15:09 Tiany 閱讀(636) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 逆向破解
            一本久久知道综合久久| 精品久久久久久国产| 久久久久亚洲精品无码蜜桃| 久久久久一本毛久久久| 精品久久久久久无码免费| 久久免费国产精品一区二区| 久久精品无码专区免费东京热| 偷偷做久久久久网站| 久久久WWW成人| 青青久久精品国产免费看 | 亚洲日本久久久午夜精品| 国产综合成人久久大片91| 97精品国产97久久久久久免费| 99久久精品国产麻豆| 国产欧美一区二区久久| 97久久天天综合色天天综合色hd| 97久久香蕉国产线看观看| 狠狠色婷婷综合天天久久丁香 | 精品久久香蕉国产线看观看亚洲| 97久久久精品综合88久久| 99久久国语露脸精品国产| 久久久久免费精品国产| 国产成人精品久久亚洲高清不卡 | 久久青草国产手机看片福利盒子| 久久99精品国产麻豆宅宅| 国产精品狼人久久久久影院 | 久久人人爽人人爽人人AV东京热 | 午夜精品久久久久成人| 伊人久久大香线蕉精品不卡| 亚洲国产精品成人久久| 99久久99久久| 久久无码人妻精品一区二区三区| 三级片免费观看久久| 人妻少妇久久中文字幕一区二区| 久久ww精品w免费人成| 久久国产综合精品五月天| 久久精品国产久精国产果冻传媒| 7777久久亚洲中文字幕| 欧美日韩中文字幕久久久不卡 | 久久九九精品99国产精品| 爱做久久久久久|