PE文件(三)节表作业

本次作业以notepad进行演示,如下是其在硬盘上的内存

1.手动解析节表

由标准pe头可知,一共由7个节也就是7个节表,可选pe头的大小是0X00F0,即240字节大小

根据上述我们所获取的信息,找到节表的首地址为0x01F8

.text

#define IMAGE_SIZEOF_SHORT_NAME  8 //宏定义    
typedef struct _IMAGE_SECTION_HEADER{
    BYTE Name[IMAGE_SIZEOF_SHORT_NAME];  0X000000747865742E
    union{
        DWORD   PhysicalAddress;
        DWORD   VirtualSize;
    }Misc;  0X00027D02
    DWORD VirtualAddress;  0X00001000
    DWORD SizeOfRawData;  0X00028000
    DWORD PointerToRawData; 0X00001000
    DWORD PointerToRelocations; 0X00000000
    DWORD PointerToLinenumbers;0X00000000
    WORD NumberOfRelocations; 0X0000
    WORD NumberOfLinenumbers;0X0000
    DWORD Characteristics;  0X60000020
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
 

.rdata

#define IMAGE_SIZEOF_SHORT_NAME 8 
typedef struct _IMAGE_SECTION_HEADER{
    BYTE Name[IMAGE_SIZEOF_SHORT_NAME];  0X000061746164722E
    union{
        DWORD   PhysicalAddress;
        DWORD   VirtualSize;
    }Misc;  0X0000A608
    DWORD VirtualAddress;  0X00029000
    DWORD SizeOfRawData; 0X0000B000
    DWORD PointerToRawData; 0X00029000
    DWORD PointerToRelocations; 0X00000000
    DWORD PointerToLinenumbers; 0X00000000
    WORD NumberOfRelocations; 0X0000
    WORD NumberOfLinenumbers; 0X0000
    DWORD Characteristics;  0X40000040
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
 

.data

#define IMAGE_SIZEOF_SHORT_NAME 8
typedef struct _IMAGE_SECTION_HEADER{
    BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; 0X000000617464642E
    union{
        DWORD   PhysicalAddress;
        DWORD   VirtualSize;
    }Misc;  000026C0
    DWORD VirtualAddress;  0X00034000
    DWORD SizeOfRawData; 0X00001000
    DWORD PointerToRawData; 0X00034000
    DWORD PointerToRelocations; 0X00000000
    DWORD PointerToLinenumbers; 0X00000000
    WORD NumberOfRelocations; 0X0000
    WORD NumberOfLinenumbers;0X0000
    DWORD Characteristics; 0XC0000040
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
 

由于该文件所有节过多,此处不再多演示,具体操作都是一样的。

2.控制台输出解析所有节表

#include<stdio.h>
#include<Windows.h>

char* ReadPEFile(const char* lpszFile)
{
	FILE* pFile = NULL;
	pFile = fopen(lpszFile, "rb");
	DWORD fileSize = 0;
	char* pFileBuffer = NULL;
	if (!pFile)
	{
		printf("无法打开EXE文件");
		return NULL;
	}
	fseek(pFile, 0, SEEK_END);
	fileSize = ftell(pFile);
	fseek(pFile, 0, SEEK_SET);
	pFileBuffer = (char*)malloc(sizeof(char)*fileSize);
	if (!pFileBuffer)
	{
		printf("分配空间失败");
		fclose(pFile);
		return NULL;
	}
	size_t i = fread(pFileBuffer, fileSize, 1, pFile);
	if (!i)
	{
		printf("读取数据失败!");
		free(pFileBuffer);
		fclose(pFile);
		return NULL;
	}
	fclose(pFile);
	return pFileBuffer;
}
BOOL PrintNTHeaders(const char* lpszFile)
{
	IMAGE_DOS_HEADER  *pDosHeader;
	IMAGE_NT_HEADERS *pNTHeader;
	IMAGE_FILE_HEADER *pPEHeader;
	IMAGE_SECTION_HEADER *pSecHeader;
	int i = 0;
	char* pFileBuffer = ReadPEFile(lpszFile);
	pDosHeader = (IMAGE_DOS_HEADER*)pFileBuffer;
	if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
	{
		printf("不是有效MZ标志,打印结束\n");
		free(pFileBuffer);
		pFileBuffer = NULL;
		return FALSE;
	}
	pNTHeader = (IMAGE_NT_HEADERS*)((char*)pFileBuffer + pDosHeader->e_lfanew);
	if (pNTHeader->Signature != IMAGE_NT_SIGNATURE)
	{
		printf("不是有效的PE标志,打印结束\n");
		free(pFileBuffer);
		pFileBuffer = NULL;
		return FALSE;
	}
	pPEHeader = (IMAGE_FILE_HEADER*)((char*)pNTHeader + 4);
	printf("NumberOfSections(节表的数量):%04X\n", pPEHeader->NumberOfSections);
	printf("SizeOfOptionalHeader(可选pe头的大小):%04X\n", pPEHeader->SizeOfOptionalHeader); 
	printf("\n");
	printf("节表信息解析开始");
	pSecHeader = (IMAGE_SECTION_HEADER*)((char*)pPEHeader + sizeof(_IMAGE_FILE_HEADER) + pPEHeader->SizeOfOptionalHeader);
	for (int i = 0; i < pPEHeader->NumberOfSections; i++)
	{	
		char SecName[9] = "\0";
		printf("这是第%d个节表\n", i+1);
		char* Name = (char*)pSecHeader->Name;
		strcpy(SecName, Name);
		printf("Name:%s\n", SecName);
		printf("VirtualSize:%08X\n", pSecHeader->Misc.VirtualSize);
		printf("VirtualAddress:%08X\n", pSecHeader->VirtualAddress);
		printf("SizeOfRawData:%08X\n", pSecHeader->SizeOfRawData);
		printf("PointerToRawData:%08X\n", pSecHeader->PointerToRawData);
		printf("Characteristics:%08X\n", pSecHeader->Characteristics);
		printf("\n");
		pSecHeader++;
	}
	free(pFileBuffer);
	pFileBuffer = NULL;
	return TRUE;
}
int main(int argc, char* argv[])
{
	const char* lpszFile = "C:\\Windows\\notepad.exe";
	PrintNTHeaders(lpszFile);
	return 0;
}

相关推荐

  1. PE文件格式知识点汇总

    2024-04-29 14:54:03       42 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-29 14:54:03       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-29 14:54:03       106 阅读
  3. 在Django里面运行非项目文件

    2024-04-29 14:54:03       87 阅读
  4. Python语言-面向对象

    2024-04-29 14:54:03       96 阅读

热门阅读

  1. 第四章:c语言中的循环结构

    2024-04-29 14:54:03       35 阅读
  2. MATLAB 2016计算NDVI

    2024-04-29 14:54:03       44 阅读
  3. 八、Python+FFmpeg,实战直播推流

    2024-04-29 14:54:03       32 阅读
  4. C语言-嵌入式-STM32:有哪些接口协议?

    2024-04-29 14:54:03       34 阅读
  5. Mac shell 环境变量配置

    2024-04-29 14:54:03       36 阅读
  6. Vue.js(过渡)

    2024-04-29 14:54:03       34 阅读
  7. Linux内核驱动开发-001字符设备开发-002led杂项驱动

    2024-04-29 14:54:03       28 阅读