您的位置:首页 > 汽车 > 新车 > 【滴水三期】32/64位——PE文件节表打印与解析

【滴水三期】32/64位——PE文件节表打印与解析

2024/11/16 17:25:06 来源:https://blog.csdn.net/sunqingyu888/article/details/140898653  浏览:    关键词:【滴水三期】32/64位——PE文件节表打印与解析

【作业内容】

1、手动查,画个PE文件图。

2、编写程序打印节表中的信息。

3、根据节表中的信息,到文件中找到所有的节,观察节的开始位置与大小是否与节表中的描述一致

【PE file_buffer文件图】

【IMAGE_SECTION_HEADER解析】

<winNT.h> 头文件定义如下

typedef struct _IMAGE_SECTION_HEADER {BYTE    Name[IMAGE_SIZEOF_SHORT_NAME]; //保存节的名字的数组。union {DWORD   PhysicalAddress;	//该节在文件中的实际大小DWORD   VirtualSize;		//该节在内存中占用的大小,节在内存中的大小会因为对齐或填充而增加} Misc;DWORD   VirtualAddress;		         //该节在进程的虚拟空间中的起始地址,内存偏移。加载器使用这个地址将节的内容映射到内存中相应的虚拟地址上。DWORD   SizeOfRawData;		        //该节在PE文件中对齐后的原始数据大小,由于 SizeOfRawData 字段是四舍五入的,而 VirtualSize 字段不是四舍五入的,因此 SizeOfRawData 字段也可能大于 VirtualSize。DWORD   PointerToRawData;		    //该节在PE文件的实际位置,即相对于文件开始的偏移量。加载器会根据这个偏移量从文件中读取节的内容,并将其加载到内存中。DWORD   PointerToRelocations;		//该节的重定位表在文件中的起始位置,如果节中有重定位项,该字段指出重定位表的文件偏移量。数据节可能需要重定位以修正基于位置的引用;没有重定位的映像,该值设为零。(在obj文件中使用,对exe无意义)。DWORD   PointerToLinenumbers;		//如果节包含源代码行号信息;;已被弃用,改值应为0WORD    NumberOfRelocations;		//该节有多少重定位条目;对于可执行文件,该值设为零。(在obj文件中使用,对exe无意义)。WORD    NumberOfLinenumbers;		//该行有多少行号条目;已被弃用,该值应为0DWORD   Characteristics;			//指定节的属性标志
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
【SECTION_CHARACTERISTICS】节表中Characteristics字段解析

<winNT.h> 头文件定义如下

1. **`IMAGE_SCN_TYPE_NO_PAD`** (`0x00000008`):指示该节不应该在文件中进行填充。 
2. **`IMAGE_SCN_CNT_CODE`** (`0x00000020`):表示该节包含可执行代码。 
3. **`IMAGE_SCN_CNT_INITIALIZED_DATA`** (`0x00000040`):表示该节包含已初始化的数据。 
4. **`IMAGE_SCN_CNT_UNINITIALIZED_DATA`** (`0x00000080`):表示该节包含未初始化的数据(通常是`.bss`节)。 5. **`IMAGE_SCN_LNK_OTHER`** (`0x00000100`):保留,用于非标准链接器特定的节。 
6. **`IMAGE_SCN_LNK_INFO`** (`0x00000200`):表示该节包含链接器信息,如重定位表和行号表。
7. **`IMAGE_SCN_LNK_REMOVE`** (`0x00000800`):指示链接器应该从最终输出中删除此节。 
8. **`IMAGE_SCN_LNK_COMDAT`** (`0x00001000`):表示该节包含COMDAT数据,即在链接时可能与其他节合并的数据。9. **`IMAGE_SCN_NO_DEFER_SPEC_EXC`** (`0x00004000`):表示该节中的代码不应延迟特定异常处理。 10. **`IMAGE_SCN_GPREL`** (`0x00008000`):表示该节中的数据相对于全局页基址(即PE文件的基地址)是相对的。 11. **`IMAGE_SCN_MEM_PURGEABLE`** (`0x00020000`):表示该节在内存中是可丢弃的,即可以由系统在需要时清除。 
12. **`IMAGE_SCN_MEM_16BIT`** (`0x00020000`):表示该节包含16位代码或数据。 
13. **`IMAGE_SCN_MEM_LOCKED`** (`0x00040000`):表示该节在内存中是锁定的,即不能被页面调度器交换出去。 
14. **`IMAGE_SCN_MEM_PRELOAD`** (`0x00080000`):表示该节应该在进程启动时预加载到内存中。 
15. **`IMAGE_SCN_ALIGN_1BYTES`** (`0x00100000`) 至 **`IMAGE_SCN_ALIGN_8192BYTES`** (`0x04000000`):这一系列标志位用于指定节在内存中的对齐方式。 16. **`IMAGE_SCN_LNK_NRELOC_OVFL`** (`0x01000000`):表示该节的重定位溢出,即重定位表中包含了太多重定位条目。 17. **`IMAGE_SCN_MEM_DISCARDABLE`** (`0x02000000`):表示该节中的数据在内存中是可以被丢弃的,即可以由系统在需要时清除。 
18. **`IMAGE_SCN_MEM_NOT_CACHED`** (`0x04000000`):表示该节在内存中不应该被缓存。 
19. **`IMAGE_SCN_MEM_NOT_PAGED`** (`0x08000000`):表示该节在内存中不应该被分页。
20. **`IMAGE_SCN_MEM_SHARED`** (`0x10000000`):表示该节在内存中是可以被共享的。 
21. **`IMAGE_SCN_MEM_EXECUTE`** (`0x20000000`):表示该节在内存中是可以执行的。 
22. **`IMAGE_SCN_MEM_READ`** (`0x40000000`):表示该节在内存中是可以读取的。 
23. **`IMAGE_SCN_MEM_WRITE`** (`0x80000000`):表示该节在内存中是可以写的。 #define IMAGE_SCN_MEM_FARDATA (0x00008000):用于指示一个节是远数据(far data)节,遗留产物,现代程序用不上。
#define IMAGE_SCN_ALIGN_MASK(0x00F00000):定义了一个掩码,用于从`Characteristics`字段中提取对齐属性.它被设计为与`Characteristics`字段进行位与操作(&),以提取出对齐属性。这个掩码的二进制表示中,只有对齐属性位被设置为1,其他位被设置为0。

【PE文件节表打印】

#include <windows.h>
#include <winnt.h>
#include <stdio.h>const char* filename= "C:\\Users\\Administrator\\Desktop\\SunloginClient\\远控项目(1)\\service\\Release\\client.exe";
char* file_buffer;//读文件,返回存储文件内容的缓冲区
int Read_File(){FILE* pfile = NULL;if ((fopen_s(&pfile, filename, "rb"))) {printf("file open error with %d .\n",errno);fclose(pfile);return 0;}//判断文件大小fseek(pfile,0,SEEK_END);int file_size=ftell(pfile);rewind(pfile);file_buffer = (char*)calloc((file_size+1), 1);//读取文件if (!((fread_s(file_buffer, file_size, 1, file_size, pfile)) == file_size)){printf("fread faild with %d.\n",errno);file_buffer = NULL;free(file_buffer);fclose(pfile);return 0;}return 0;
}
int Section_Operator() {/*1、判断DOS 头前word个字节是否为5A4D2、读取e_lfanew3、跳到NT头位置,*/PIMAGE_DOS_HEADER dos_header;dos_header = (PIMAGE_DOS_HEADER)file_buffer;if (!(dos_header->e_magic== IMAGE_DOS_SIGNATURE)){printf("Not PE file!\n"); return 0;}DWORD Pe_sig = dos_header->e_lfanew;//file_temp_buffer==MACHINEchar* file_temp_buffer= (char*)calloc(sizeof(file_buffer), 1);//1、获得 WORD NumberOfSections 判断节的数量//2、获得 WORD SizeofOptionsHeader  此头没有本节课作业相关的数据,先不读取,直接跳过此头。//有个DOWRD signature字节,直接跳过,到FILE_HEADER 部分file_temp_buffer = file_buffer + Pe_sig+4 ; PIMAGE_FILE_HEADER file_header;file_header = (PIMAGE_FILE_HEADER)file_temp_buffer;//1、获得 WORD NumberOfSections 判断节的数量int section_number=file_header->NumberOfSections;//2、获得 WORD SizeofOptionsHeader  此头没有本节课作业相关的数据,先不读取,直接跳过此头。int option_header_size = file_header->SizeOfOptionalHeader;file_temp_buffer = file_temp_buffer + option_header_size+sizeof(IMAGE_FILE_HEADER);PIMAGE_NT_HEADERS;PIMAGE_SECTION_HEADER section_header;section_header = (PIMAGE_SECTION_HEADER)file_temp_buffer;while (section_number--){printf("====================== %s节表信息 =======================\n", section_header->Name);printf("节在内存中的大小:%08X\n",section_header->Misc.VirtualSize);printf("节的内存偏移:%08X\n",section_header->VirtualAddress);printf("节在文件中对齐后的大小:%08X\n",section_header->SizeOfRawData);printf("节在PE文件的偏移:%08X\n",section_header->PointerToRawData);printf("该值应为0:%08X\n",section_header->PointerToRelocations);printf("该值应为0:%08X\n",section_header->PointerToLinenumbers);printf("该值应为0:%08X\n",section_header->NumberOfRelocations);printf("该值应为0:%04X\n",section_header->NumberOfLinenumbers);printf("节的权限:%08X\n",section_header->Characteristics);//section_header 是PIMAGE_SECTION_HEADER类型,(section_header++) 等于 指针向下顺移一个节的位置。//printf("====================== %s节表信息 =======================\n",section_header->Name);section_header++;}file_buffer = NULL;file_temp_buffer = NULL;free(file_buffer);free(file_temp_buffer);
}int main() {Read_File();Section_Operator();return 0;
}

注:如有不正确或可完善的地方请私聊,直接评论也可以。本人在编辑的时候可能会受到自身逻辑限制,无法想到一些重要的情况,欢迎各位一起学习的小伙伴多多批评指正。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com