PE文件查看学习

PE练习:

#include<Windows.h>
#include"resource.h"
#include<iostream>

#pragma comment(lib,"Msimg32.lib")
#define FILEBUFF "C:/LenovoSoftstore/Install/xxx/xxx.exe"//文件路径

#define fileBuff "C:/LenovoSoftstore/Install/xxx/副本xxx.exe"//保存文件路径

#define DEBUG 1//测试:打印输出

//初始化GDI
#include<objidl.h>
#include<gdiplus.h>
#include<gdiplusgraphics.h>
using namespace Gdiplus;
#pragma comment(lib,"Gdiplus.lib")

#define CLASSNAME "Mode" 
#define WINDOW_NAME "小模块"
#define WINDOW_W 960
#define WINDOW_H 580

static HMENU g_mwnu = NULL; //主菜单

//模块遍历:PE
class ModuleTraversal {
private:
	const int m_mistake = 0xFFFFFFFF;//失败
	PVOID m_Buffer = NULL;//缓冲区指针
	unsigned int m_ModeSize;//模块总和
private:
	PIMAGE_DOS_HEADER pDosMode;//DOS头
	PIMAGE_NT_HEADERS32 pNtMode;//NT头
	PIMAGE_FILE_HEADER pFileHeaderMode;//标准PE头
	PIMAGE_OPTIONAL_HEADER32 pOptionalMode;//可选PE头
	PIMAGE_DATA_DIRECTORY pDataDirectoryMode;//目录表
	PIMAGE_SECTION_HEADER pSectionMode;//节表
private:

public:
	/***************************************************************************************
	** 函数:OpenFile
	** 参数:hwnd	(窗口句柄:不用可以设置为NULL)
	** 参数:name	(文件路径:要传入文件的正确路径)
	** 返回:成功返回缓冲区文件的开始地址,失败返回-1,也就是(0xFFFFFFFF)
	***************************************************************************************/
	PVOID OpenFile(HWND hwnd,const char*nam);
	/***************************************************************************************
	** 函数:ModeSize
	** 返回:成功返回缓冲区文件头的大小(Dos头+Nt(标准PE头、可选PE头)+所有节表)
	***************************************************************************************/
	VOID DosMode();//DOS
	VOID FileMode();//标准PE头
	VOID OptionalHeaderMode();//可选PE头
	VOID SectionHeaderMode();//节表
	VOID UnfoldStretch();//文件--》展开	
};
#include "modepe.h"
/***************************************************************************************
** 函数:OpenFile
** 参数:hwnd	(窗口句柄:不用可以设置为NULL)
** 参数:name	(文件路径:要传入文件的正确路径)
** 返回:成功返回缓冲区文件的开始地址,失败返回-1,也就是(0xFFFFFFFF)
***************************************************************************************/
PVOID ModuleTraversal::OpenFile(HWND hwnd,const char*name){
	FILE* pFile = NULL;
	DWORD FileSize = 0;
	PVOID pFileBuffer = NULL;
	pFile = fopen(name, "rb");
	if (pFile == NULL) {
		if (DEBUG) {
			MessageBox(hwnd, "打开文件失败", "提示", MB_OK);
		}
		return (PVOID)this->m_mistake;
	}
	fseek(pFile, 0, SEEK_END);
	FileSize = ftell(pFile);
	fseek(pFile, 0, SEEK_SET);
	pFileBuffer = malloc(FileSize);
	if (pFileBuffer == NULL) {
		if (DEBUG) {
			MessageBox(hwnd, "内存申请失败", "提示", MB_OK);
		}
		fclose(pFile);
		return  (PVOID)this->m_mistake;
	}
	memset(pFileBuffer, 0, FileSize);
	size_t internalBuffer = fread(pFileBuffer, FileSize, 1, pFile);
	if (internalBuffer == NULL) {
		if (DEBUG) {
			MessageBox(hwnd, "读取到缓冲区失败", "提示", MB_OK);
		}
		free(pFileBuffer);
		fclose(pFile);
		pFileBuffer = NULL;
		return (PVOID)this->m_mistake;
	}
	fclose(pFile);
	return (PVOID)pFileBuffer;
}

DWORD ModuleTraversal::ModeSize(){//计算模块的大小
	this->m_Buffer = this->OpenFile(nullptr, FILEBUFF);
	if (this->m_Buffer == NULL) {
		return this->m_mistake;
	}
	this->pDosMode = (PIMAGE_DOS_HEADER)this->m_Buffer;
	if (*((PWORD)this->pDosMode )!= IMAGE_DOS_SIGNATURE) {
		free(this->m_Buffer);
		return this->m_mistake;
	}
	this->pNtMode = PIMAGE_NT_HEADERS32(DWORD(this->m_Buffer )+ this->pDosMode->e_lfanew);
	if (this->pNtMode->Signature != 0x00004550) {
		free(this->m_Buffer);
		return this->m_mistake;
	}
	this->m_ModeSize = sizeof(IMAGE_DOS_HEADER);
	this->m_ModeSize += sizeof(IMAGE_NT_HEADERS32);
	this->m_ModeSize += sizeof(IMAGE_SECTION_HEADER)*this->pNtMode->FileHeader.NumberOfSections;//的到一个节表所使用的内存
	return this->m_ModeSize;
}

VOID ModuleTraversal::DosMode(){
	DWORD DosSize = 0;
	this->m_Buffer = OpenFile(nullptr, FILEBUFF);
	printf("---------------------------------------------------------------------\n");
	if (this->m_Buffer == NULL) {
		if (DEBUG) {
			MessageBox(NULL, "文件缓冲区获取失败", "提示", MB_OK);
		}
		return;
	}
	if (*(PWORD)this->m_Buffer!= IMAGE_DOS_SIGNATURE) {
		if (DEBUG) {
			MessageBox(NULL, "获取到文件开始字节数不匹配", "提示", MB_OK);
		}
		free(this->m_Buffer);
		return ;
	}
	pDosMode = (PIMAGE_DOS_HEADER)m_Buffer;//将缓冲区指针:进行转换
	printf("%x\tMZ标志:e_magic\n", pDosMode->e_magic);
	printf("%x\tPE标记:e_lfanew\n", pDosMode->e_lfanew);
	//将缓冲区的地址(转换为DWORD类型)以此为起点加上DOS头的最后一个属性里的值就等于NT的开始位置
	pNtMode = PIMAGE_NT_HEADERS32((DWORD)m_Buffer + pDosMode->e_lfanew);
	printf("跳转PE标志\t%x\tNT开始处:Signature\n", pNtMode->Signature);
	printf("---------------------------------------------------------------------\n");
	free(this->m_Buffer);
	return ;
}

VOID ModuleTraversal::FileMode(){
	this->m_Buffer = this->OpenFile(nullptr, FILEBUFF);
	if (this->m_Buffer == NULL) {
		return VOID();
	}
	if (*(PWORD)this->m_Buffer != IMAGE_DOS_SIGNATURE) {
		free(this->m_Buffer);
		return VOID();
	}
	pDosMode = (PIMAGE_DOS_HEADER)m_Buffer;//将缓冲区指针--转换为DOS指针
	//将缓冲区的地址(转换为DWORD类型)以此为起点加上DOS头的最后一个属性里的值就等于NT的开始位置
	pNtMode = PIMAGE_NT_HEADERS32((DWORD)m_Buffer + pDosMode->e_lfanew);
	printf("%x\tCPU型号:Machine\n", pNtMode->FileHeader.Machine);
	printf("%x\t节的总数:NumberOfSections\n", pNtMode->FileHeader.NumberOfSections);
	printf("%x\t时间轴:TimeDateStamp\n", pNtMode->FileHeader.TimeDateStamp);
	printf("%x\t可选PE头的大小:SizeOfOptionalHeader\n", pNtMode->FileHeader.SizeOfOptionalHeader);
	printf("%x\t属性:Characteristics\n", pNtMode->FileHeader.Characteristics);
	printf("----------------------------------------------------------------------\n");
	free(this->m_Buffer);
	return VOID();
}

VOID ModuleTraversal::OptionalHeaderMode(){
	this->m_Buffer = this->OpenFile(nullptr, FILEBUFF);
	if (this->m_Buffer == NULL) {
		return VOID();
	}
	pDosMode = (PIMAGE_DOS_HEADER)this->m_Buffer;//将缓冲区指针--转换为DOS指针
	if (*(PWORD)this->m_Buffer != IMAGE_DOS_SIGNATURE) {
		free(this->m_Buffer);
		return VOID();
	}
	//将缓冲区的地址(转换为DWORD类型)以此为起点加上DOS头的最后一个属性里的值就等于NT的开始位置
	pNtMode = PIMAGE_NT_HEADERS32((DWORD)this->m_Buffer + pDosMode->e_lfanew);
	if (pNtMode->OptionalHeader.Magic == 0x10B) {
		printf("%x\t文件的类型:32位的PE格式的文件:Magic\n", pNtMode->OptionalHeader.Magic);
	}
	else if (pNtMode->OptionalHeader.Magic == 0x20B) {
		printf("%x\t文件的类型:64位的PE格式的文件:Magic\n", pNtMode->OptionalHeader.Magic);
	}
	else{
		printf("%x\t文件的类型:Magic\n", pNtMode->OptionalHeader.Magic);
	}
	printf("%x\t所有代码节的和:SizeOfCode\n", pNtMode->OptionalHeader.SizeOfCode);
	printf("%x\t程序入口(OEP):AddressOfEntryPoint\n", pNtMode->OptionalHeader.AddressOfEntryPoint);
	printf("%x\t代码开始的基址:BaseOfCode\n", pNtMode->OptionalHeader.BaseOfCode);
	printf("%x\t数据开始的基址:BaseOfDat\n", pNtMode->OptionalHeader.BaseOfData);
	printf("%x\t内存镜像:ImageBase\n", pNtMode->OptionalHeader.ImageBase);
	printf("%x\t内存对齐:SectionAlignment\n", pNtMode->OptionalHeader.SectionAlignment);
	printf("%x\t文件对齐:FileAlignment\n", pNtMode->OptionalHeader.FileAlignment);
	printf("%x\t整个文件在内存中拉伸后的大小:SizeOfImage\n", pNtMode->OptionalHeader.SizeOfImage);
	printf("%x\t所有头加上所有节表的总和(头的部分):SizeOfHeaders\n", pNtMode->OptionalHeader.SizeOfHeaders);
	printf("%x\t目录项数目(包含多少个表):NumberOfRvaAndSizes\n", pNtMode->OptionalHeader.NumberOfRvaAndSizes);
	printf("----------------------------------------------------------------------\n");
	free(this->m_Buffer);
	return VOID();
}
VOID ModuleTraversal::SectionHeaderMode(){
	this->m_Buffer = this->OpenFile(nullptr, FILEBUFF);
	if (this->m_Buffer == NULL) {
		return;
	}
	this->pDosMode = PIMAGE_DOS_HEADER(this->m_Buffer);
	if ((*(PWORD)this->m_Buffer) != IMAGE_DOS_SIGNATURE) {
		free(this->m_Buffer);
		return;
	}
	this->pNtMode = PIMAGE_NT_HEADERS32((DWORD)this->m_Buffer + this->pDosMode->e_lfanew);
	this->pSectionMode = PIMAGE_SECTION_HEADER(((DWORD)this->m_Buffer) + this->pDosMode->e_lfanew + 0x4 + sizeof(IMAGE_FILE_HEADER) + sizeof(IMAGE_OPTIONAL_HEADER32));
	for (int traversalSection = 0; traversalSection < pNtMode->FileHeader.NumberOfSections; traversalSection++) {//遍历节表
		char arr[9] = { 0 };
		strcpy(arr, (char*)this->pSectionMode->Name);//将节表:的名字拷贝到新定义的 char型数组中 
		for (int arrByte = 0; arrByte < 8; arrByte++) {
			printf("%c", arr[arrByte]);//防止溢出:这里一个一个字符的打印
		}
		printf("\t节的名字\n");
		printf("%x\t内存中的偏移地址:VirtualAddress\n", this->pSectionMode->VirtualAddress);
		printf("%x\t内存中的大小:Misc.VirtualSize\n", this->pSectionMode->Misc.VirtualSize);
		printf("%x\t文件中的偏移:PointerToRawData\n", this->pSectionMode->PointerToRawData);
		printf("%x\t文件中大小:SizeOfRawData\n", this->pSectionMode->SizeOfRawData);
		printf("%x\t节的属性:Characteristics\n", this->pSectionMode->Characteristics);
		this->pSectionMode++;//将节表的指针加一下(跳到到一个节的开始处:是跳一个节表)
		printf("----------------------------------------------\n");
	}
	free(this->m_Buffer);
	return VOID();
}

VOID ModuleTraversal::UnfoldStretch(){
	PVOID FileBuff = NULL;//文件缓存指针
	PVOID ImageBuff = NULL;//内存缓存指针
	DWORD FileCalculateSize = 0;//文件大小
	FILE* pFile = fopen(FILEBUFF, "rb");
	if (pFile == NULL) {
		return VOID();
	}
	fseek(pFile, 0, SEEK_END);
	FileCalculateSize = ftell(pFile);
	fseek(pFile, 0, SEEK_SET);
	if (FileCalculateSize == -1) {
		fclose(pFile);
		return VOID();
	}
	FileBuff = malloc(FileCalculateSize);//FhilBufff 内存
	memset(FileBuff, 0, FileCalculateSize);
	fread(FileBuff, FileCalculateSize, 1, pFile);
	this->m_Buffer = FileBuff;
	if (this->m_Buffer == NULL) {
		fclose(pFile);
		return VOID();
	}
	if (*(PWORD)(this->m_Buffer) != IMAGE_DOS_SIGNATURE) {
		free(this->m_Buffer);
		return VOID();
	}
	this->pDosMode = PIMAGE_DOS_HEADER(this->m_Buffer);
	this->pNtMode = PIMAGE_NT_HEADERS32(DWORD(this->m_Buffer) + this->pDosMode->e_lfanew);
	this->pSectionMode = PIMAGE_SECTION_HEADER(DWORD(this->m_Buffer) + this->pDosMode->e_lfanew + sizeof(IMAGE_NT_HEADERS32));
	PIMAGE_SECTION_HEADER pSectionMode1 = PIMAGE_SECTION_HEADER(DWORD(this->m_Buffer) + this->pDosMode->e_lfanew + sizeof(IMAGE_NT_HEADERS32));
	//计算头部大小:
	DWORD sizeByte = (sizeof(IMAGE_DOS_HEADER)+this->pDosMode->e_lfanew + sizeof(IMAGE_NT_HEADERS32) + (sizeof(IMAGE_SECTION_HEADER)*this->pNtMode->FileHeader.NumberOfSections));
	ImageBuff = malloc(this->pNtMode->OptionalHeader.SizeOfImage);//imageBuff 内存
	memset(ImageBuff, 0, this->pNtMode->OptionalHeader.SizeOfImage);
	memcpy(ImageBuff, FileBuff, this->pNtMode->OptionalHeader.SizeOfHeaders);//拷贝头部数据
	for (int fileBuff_ImageBuff = 0; fileBuff_ImageBuff < this->pNtMode->FileHeader.NumberOfSections; fileBuff_ImageBuff++) {
		//拷贝:节表之后的剩余数据
		memcpy(PVOID((DWORD)ImageBuff + (this->pNtMode->OptionalHeader.SizeOfHeaders + this->pSectionMode->VirtualAddress)),
			PVOID((DWORD)FileBuff + (this->pNtMode->OptionalHeader.SizeOfHeaders + this->pSectionMode->SizeOfRawData)), this->pSectionMode->Misc.VirtualSize);
		this->pSectionMode++;
	}
	PVOID BackTo = NULL;//缩回来
	BackTo = malloc(FileCalculateSize);
	memset(BackTo, 0, FileCalculateSize);
	memcpy(BackTo, ImageBuff, sizeByte);//线拷贝头
	for (int backto = 0; backto < this->pNtMode->FileHeader.NumberOfSections; backto++) {
		memcpy(
			PVOID((DWORD)BackTo + this->pNtMode->OptionalHeader.SizeOfHeaders + pSectionMode1->PointerToRawData),
			PVOID((DWORD)ImageBuff + this->pNtMode->OptionalHeader.SizeOfHeaders + pSectionMode1->VirtualAddress),
			pSectionMode1->Misc.VirtualSize);
		pSectionMode1++;
	}
	//保存文件
	FILE* shrinkFile = NULL;
	shrinkFile = fopen(fileBuff, "wb+");
	fwrite(BackTo, FileCalculateSize, 1, shrinkFile);
	fclose(shrinkFile);
	free(this->m_Buffer);
	shrinkFile = NULL;
	this->m_Buffer = NULL;
	FileBuff = NULL;
	ImageBuff = NULL;
	return VOID();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值