节表

一、PE加载的过程

1、根据SizeOfImage的大小,开辟一块缓冲区(ImageBuffer).

2、根据SizeOfHeader的大小,将头信息从FileBuffer拷贝到ImageBuffer

3、根据节表中的信息循环讲FileBuffer中的节拷贝到ImageBuffer中.

在这里插入图片描述

Q1、如何定位节表

可选PE头后面紧跟着的就是第一个节表.

Q2、如何确定节表个数

标准PE头里面的第二个成员:NumberOfSection 存储的就是一个有几个节表

二、FileBuffer和ImageBuffer结构

在这里插入图片描述

三、节表结构

在这里插入图片描述

typedef struct _IMAGE_SECTION_HEADER {

0x00 BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
    union {
0x08 DWORD PhysicalAddress;
0x08 DWORD VirtualSize;
     } Misc;
0x0c DWORD VirtualAddress;
0x10 DWORD SizeOfRawData;
0x14 DWORD PointerToRawData;
0x18 DWORD PointerToRelocations;
0x1c DWORD PointerToLinenumbers;
0x20 WORD NumberOfRelocations;
0x22 WORD NumberOfLinenumbers;
0x24 DWORD Characteristics;
};

四、编写程序打印节表中的信息.

#include "stdafx.h"
#include "string.h"
#include <malloc.h>
#include <windows.h>


WORD NumberOfSections = 0;
DWORD SizeOfHeaders = 0;
DWORD SizeOfImage = 0;
DWORD SectionAlignment = 0;
int info_Address[10] ;
int info_RawData[10] ;
int info_PointerToRawData[10];

FILE* file_open(char* file_path);
int compute_file_len(FILE* pfile);
char* allocate(int file_buf_size);
char* readfile2mem(FILE* file_address,char* pfile_buffer,int file_buf_size);
void read_PE_info(char* pfile_buffer);


void operate_pe()
{	
	FILE* fp2 = fopen("D:\\Lib\\test3.exe","wb");
	// 打开文件
	char file_path[] = "C:\\Windows\\System32\\notepad.exe";
	FILE* file_address = file_open(file_path);
	// 计算文件长度
	int file_buf_size = compute_file_len(file_address);
	printf("file_buf_size:%d\n",file_buf_size);
	// 分配动态内存用于FILE_BUFFER
	char* pfile_buffer = allocate(file_buf_size);
	printf("===================分配FILE_BUFFER内存成功!内存地址开始:%x=========================\n",pfile_buffer);
	// 将文件内容写入内存
	pfile_buffer = readfile2mem(file_address,pfile_buffer,file_buf_size);
	// 读取PE中的关键信息
	read_PE_info(pfile_buffer);
	// 重新分配一段内存用于IMAGE_BUFFER
	char* pimage_buffer = allocate(SizeOfImage);
	printf("===================分配IMAGE_BUFFER内存成功!内存地址开始:%x=========================\n",pfile_buffer);
	// 往另一段内存中拷贝数据
	//内存拷贝函数 将pfile_buffer指向的地址的内存拷贝SizeOfHeaders个字节到pimage_buffer指向的内存中去
	memcpy(pimage_buffer,pfile_buffer,SizeOfHeaders);
	printf("头部信息填充完毕!\n");
	memset(pimage_buffer+SizeOfHeaders,0,SectionAlignment-SizeOfHeaders);
	for(int j = 0;j<NumberOfSections;j++)
	{	// 向新的内存中拷贝节表
		memcpy(info_Address[j]+pimage_buffer,pfile_buffer+info_PointerToRawData[j],info_RawData[j]);
		if(info_PointerToRawData[j]<SectionAlignment)
			memset(pimage_buffer+SizeOfHeaders,0,SizeOfImage-SizeOfHeaders);	
	}
	fwrite(pimage_buffer,SizeOfImage,1,fp2);

	


	fclose(fp2);
	free(pfile_buffer);
	free(pimage_buffer);
}

FILE* file_open(char* file_path)
{
	FILE* file_address = fopen(file_path,"rb");
	if(!file_address)
	{
		printf("打开文件失败!\n");
		return 0;
	}
	return file_address;
}

int compute_file_len(FILE* pfile)
{
	int len = 0;
	fseek(pfile,0,SEEK_END);
	len = ftell(pfile);
	fseek(pfile,0,SEEK_SET);
	return len;
}
char* allocate(int buf_size)
{
	char* buffer_address = (char*)malloc(buf_size);
	if(!buffer_address)
	{
		printf("分配内存失败!\n");
		return 0;
	}
	memset(buffer_address,0,buf_size);
	return buffer_address;
}

char* readfile2mem(FILE* file_address,char* pfile_buffer,int file_buf_size)
{
	if(!(fread(pfile_buffer,file_buf_size,1,file_address)))
	{
		printf("从文件向内存中读取数据失败!\n");
		return 0;
	}
	return pfile_buffer;
}

void read_PE_info(char* pfile_buffer)
{
	int info_01[10];
	PIMAGE_DOS_HEADER pDosHeader = NULL;	
	PIMAGE_NT_HEADERS pNTHeader = NULL;	
	PIMAGE_FILE_HEADER pPEHeader = NULL;	
	PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
	PIMAGE_SECTION_HEADER pSectionHeader = NULL;

	pDosHeader = (PIMAGE_DOS_HEADER)pfile_buffer;
	// 获取PE头部偏移
	if(*((PDWORD)((DWORD)pDosHeader+pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
	{	
		printf("不是有效的PE标志!\n");
		free(pfile_buffer);
		return;
	}
	pNTHeader = PIMAGE_NT_HEADERS((DWORD)pfile_buffer+pDosHeader->e_lfanew);
	printf("=====================开始查找NT头中信息=============================\n");
	printf("pNTHeader:%X\n",pNTHeader);

	//强制类型转化,指向标准PE头
	pPEHeader = PIMAGE_FILE_HEADER((DWORD)pNTHeader+4);
	printf("=====================开始查找标准PE头中信息=========================\n");
	printf("pPEHeader:%X\n",pPEHeader);
	printf("节的数量:%x\n",pPEHeader->NumberOfSections);
	printf("SizeOfOptionalHeader(可选PE头的大小):%x\n",pPEHeader->SizeOfOptionalHeader);
	NumberOfSections = pPEHeader->NumberOfSections;

	// 强制类型转换,指向可选PE头
	pOptionHeader = PIMAGE_OPTIONAL_HEADER32((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
	printf("====================开始查找可选PE头中信息==========================\n");
	printf("SizeOfImage:%x\n",pOptionHeader->SizeOfImage);
	printf("SizeOfHeaders:%x\n",pOptionHeader->SizeOfHeaders);
	printf("SectionAlignment:%x\n",pOptionHeader->SectionAlignment);
	SizeOfHeaders = pOptionHeader->SizeOfHeaders;
	SizeOfImage = pOptionHeader->SizeOfImage;
	SectionAlignment = pOptionHeader->SectionAlignment;

	// 强制类型转换,指向节表中的信息
	printf("====================开始查找节表中信息==========================\n");
	pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);
	for(DWORD i = 0;i<NumberOfSections;i++,pSectionHeader++)
	{
		printf("VirtualAddress:%08X\n",pSectionHeader->VirtualAddress);
		printf("SizeOfRawData:%08X\n",pSectionHeader->SizeOfRawData);
		printf("PointerToRawData:%08X\n",pSectionHeader->PointerToRawData);
		printf("==============================================\n");
		info_Address[i] = pSectionHeader->VirtualAddress;
		info_RawData[i] = pSectionHeader->SizeOfRawData;
		info_PointerToRawData[i] = pSectionHeader->PointerToRawData;
	}
	printf("获得PE信息结束,准备开始向ImageBuffer存储!!\n");
}


int main()
{	
	operate_pe();
	getchar();
	return 0;
}


在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值