节表

  1. 联合体
  2. 节表数据结构
    1. 成员解释
  3. 编写程序打印节表中的内容

联合体

用于在同一个内存空间中存储不同的数据类型。

union TestUnion	
{	
    char x;
    int y;
};	

特点:

  1. 联合体的成员是共享内存空间的
  2. 联合体的内存空间大小是联合体成员中对内存空间大小要求最大的空间大小
  3. 联合体最多只有一个成员有效

节表数据结构

#define IMAGE_SIZEOF_SHORT_NAME   8					
                    
typedef struct _IMAGE_SECTION_HEADER {					
    BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];					
    union {					
            DWORD   PhysicalAddress;					
            DWORD   VirtualSize;					
    } Misc;					
    DWORD   VirtualAddress;					
    DWORD   SizeOfRawData;					
    DWORD   PointerToRawData;					
    DWORD   PointerToRelocations;					
    DWORD   PointerToLinenumbers;					
    WORD    NumberOfRelocations;					
    WORD    NumberOfLinenumbers;					
    DWORD   Characteristics;					
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;					
成员解释
  1. Name 8个字节 一般情况下是以”\0”结尾的ASCII吗字符串来标识的名称,内容可以自定义
    注意:该名称并不遵守必须以”\0”结尾的规律,如果不是以”\0”结尾,系统会截取8个字节的长度进行处理
  2. Misc 双字 是该节在没有对齐前的真实尺寸,该值可以不准确
  3. VirtualAddress 节区在内存中的偏移地址。加上ImageBase才是在内存中的真正地址
  4. SizeOfRawData 节在文件中对齐后的尺寸
  5. PointerToRawData 节区在文件中的偏移
  6. PointerToRelocations 在obj文件中使用 对exe无意义
  7. PointerToLinenumbers 行号表的位置 调试的时候使用
  8. NumberOfRelocations 在obj文件中使用 对exe无意义
  9. NumberOfLinenumbers 行号表中行号的数量 调试的时候使用
  10. Characteristics 节的属性

PE加载的过程:

  1. 根据SizeOfImage的大小,开辟一块缓冲区(ImageBuffer)
  2. 根据SizeOfHeader的大小,将头信息从FileBuffer拷贝到ImageBuffer
  3. 根据节表中的信息循环讲FileBuffer中的节拷贝到ImageBuffer中

image-20230828201551375

image-20230828201613533

编写程序打印节表中的内容

PIMAGE_SECTION_HEADER pSectionHeader = NULL;

char* fptr = (pFileBuffer + (pDosHeader->e_lfanew) + 4 + IMAGE_SIZEOF_FILE_HEADER + pPEHeader->SizeOfOptionalHeader);
    for (size_t i = 0; i<pPEHeader->NumberOfSections; i++) {
        pSectionHeader = PIMAGE_SECTION_HEADER(fptr);
        printf("--------------------------节表%d--------------------------\n",i+1);
        printf("Name:%s\n", pSectionHeader->Name);
        printf("Misc:%X\n", pSectionHeader->Misc);
        printf("VirtualAddress:%X\n", pSectionHeader->VirtualAddress);
        printf("SizeOfRawData:%X\n", pSectionHeader->SizeOfRawData);
        printf("PointerToRawData:%X\n", pSectionHeader->PointerToRawData);
        printf("PointerToRelocations:%X\n", pSectionHeader->PointerToRelocations);
        printf("PointerToLinenumbers:%X\n", pSectionHeader->PointerToLinenumbers);
        printf("NumberOfRelocations:%X\n", pSectionHeader->NumberOfRelocations);
        printf("NumberOfLinenumbers:%X\n", pSectionHeader->NumberOfLinenumbers);
        printf("Characteristics:%X\n", pSectionHeader->Characteristics);
        fptr = fptr + IMAGE_SIZEOF_SECTION_HEADER;
    }

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1666739907@qq.com
github