zoukankan      html  css  js  c++  java
  • 学破解 <三> PE格式之 区块表与区块

    _______________________________ 
      | IMAGE_DOS_HEADER     |   <-- Dos部首 
      ------------------------------- 
      | PE,0,0           |   <-- PE文件标志 
      ------------------------------- 
      | IMAGE_FILE_HEADER    |   <-- 映像文件头 
      ------------------------------- 
      | IMAGE_OPTIONAL_HEADER32 |   <-- 映像可选头 
      ------------------------------- 
      | Section Table      |   <-- 节表 
      ------------------------------- 
      | .text          |   <-- 代码区段 
      ------------------------------- 
      | .data          |   <-- 数据区段 
      ------------------------------- 
      | .idata          |   <-- 输入表 
      ------------------------------- 
      | .edata          |   <-- 输出表 
      ------------------------------- 
      | .reloc          |   <-- 重定位表区段 
      ------------------------------- 
      |  ....          | 
      ------------------------------- 
      |  调试信息         | 
      ------------------------------- 
    根据这个结构表IMAGE_OPTIONAL_HEADER下面紧接着就是区块表和各种区块,也可以叫做节表和节英文是SECTION。
    节表是由一大堆的IMAGE_SECTION_HEADER排列成的一个数据结构。其数量由IMAGE_NT_HEADERS结构中的FileHeader.NumberOfSections成员来决定。
    IMAGE_SECTION_HEADER的结构如下
     
    typedef struct _IMAGE_SECTION_HEADER  

            BYTE Name[IMAGE_SIZEOF_SHORT_NAME];     // 节表名称,如“.text”  
            //IMAGE_SIZEOF_SHORT_NAME=8 
            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;  
    Name 里面存的是区块的名字
    .text code 什么的就是放代码用的
    .data 就是放数据,已经初始化好的
    .idata 就是输入表 ,很多加壳程序会修改输入表,hook api 在程序运行api时,让壳取得一定时间的权限来反跟踪,脱壳的一大步骤就是还原输入表。
    .edata 输出表
    .bbs 未初始化的数据
    VirtualSizes是一个非常牛逼的成员,其中的值是区块没有按FileAlignment对其前的大小,通过它可以推算出区块中还有多少没有被使用,很多病毒会在未被是用的空间里
    插入自己的代码。
    Characteristics 表示该区块的属性 可读啊 可写啊什么的
     
    //   IMAGE_SCN_TYPE_REG        0x00000000 // Reserved. 
    //   IMAGE_SCN_TYPE_DSECT       0x00000001 // Reserved. 
    //   IMAGE_SCN_TYPE_NOLOAD       0x00000002 // Reserved. 
    //   IMAGE_SCN_TYPE_GROUP       0x00000004 // Reserved. 
    #define IMAGE_SCN_TYPE_NO_PAD       0x00000008 // Reserved. 
    //   IMAGE_SCN_TYPE_COPY        0x00000010 // Reserved. 
     
    #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_MEM_FARDATA       0x00008000 
    //   IMAGE_SCN_MEM_SYSHEAP - Obsolete 0x00010000 
    #define IMAGE_SCN_MEM_PURGEABLE      0x00020000 
    #define IMAGE_SCN_MEM_16BIT        0x00020000 
    #define IMAGE_SCN_MEM_LOCKED       0x00040000 
    #define IMAGE_SCN_MEM_PRELOAD       0x00080000 
     
    #define IMAGE_SCN_ALIGN_1BYTES      0x00100000 // 
    #define IMAGE_SCN_ALIGN_2BYTES      0x00200000 // 
    #define IMAGE_SCN_ALIGN_4BYTES      0x00300000 // 
    #define IMAGE_SCN_ALIGN_8BYTES      0x00400000 // 
    #define IMAGE_SCN_ALIGN_16BYTES      0x00500000 // Default alignment if no others are specified. 
    #define IMAGE_SCN_ALIGN_32BYTES      0x00600000 // 
    #define IMAGE_SCN_ALIGN_64BYTES      0x00700000 // 
    #define IMAGE_SCN_ALIGN_128BYTES     0x00800000 // 
    #define IMAGE_SCN_ALIGN_256BYTES     0x00900000 // 
    #define IMAGE_SCN_ALIGN_512BYTES     0x00A00000 // 
    #define IMAGE_SCN_ALIGN_1024BYTES     0x00B00000 // 
    #define IMAGE_SCN_ALIGN_2048BYTES     0x00C00000 // 
    #define IMAGE_SCN_ALIGN_4096BYTES     0x00D00000 // 
    #define IMAGE_SCN_ALIGN_8192BYTES     0x00E00000 // 
    // Unused                 0x00F00000 
     
    #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. 
                               //该区段可写 
     
    最后写个程序把这个结构读出来
    由于我比较懒就只读了Name这个成员,有些加壳软件会修改Name这个字段使读出来的东西乱七八糟,比如UPX的压缩壳,会把Name字段改成UPX0,UPX1这样
     
    #include "windows.h" 
    #include "stdio.h" 
     
    int main(int argc, char* argv[]) 

        FILE *p; 
        int i; 
        unsigned long Signature; 
        IMAGE_FILE_HEADER myfileheader; 
        IMAGE_DOS_HEADER mydosheader; 
        IMAGE_OPTIONAL_HEADER myoptionalheader; 
        IMAGE_SECTION_HEADER mysectionheader; 
     
        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结构的偏移 
        fread(&myfileheader,sizeof(myfileheader),1,p); 
     
        fseek(p,mydosheader.e_lfanew+sizeof(Signature)+sizeof(myfileheader)+sizeof(myoptionalheader),SEEK_SET); 
        printf("Signature          : %04X\n",Signature); 
        printf("IMAGE_SECTION_HEADER       结构:\n"); 
        for(i=0;i<myfileheader.NumberOfSections;i++){ 
            fread(&mysectionheader,sizeof(mysectionheader),1,p); 
            printf("Name               : %s\n",mysectionheader.Name); 
        } 
        fclose(p); 
        return 0; 

  • 相关阅读:
    前端性能优化
    技术从业者的未来(二)
    微服务架构
    SpringCloud 微服务最佳开发实践
    架构师之路
    SpringBoot开发秘籍
    架构设计方法论
    消息架构的设计难题以及应对之道
    SpringCloud 中如何防止绕过网关请求后端服务?
    微服务架构授权是在网关做还是在微服务做?
  • 原文地址:https://www.cnblogs.com/tk091/p/2456175.html
Copyright © 2011-2022 走看看