滴水逆向作业——PE03_stage1

在这里插入图片描述

#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;
}

结果如下:
在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值