首页 > 其他分享 >1、PE 初识

1、PE 初识

时间:2024-12-19 19:52:41浏览次数:3  
标签:pFile Windows IMAGE PE 初识 SIGNATURE NT

1、PE 初识

概论

首先 PE头部分主要是学习PE结构的前半部分,每一个是做什么的,以及重点是什么,每一个是做什么用的。并使用Cpp代码来解析该PE头 注意这里用了一个Windows.h的头文件,后面再说。

PE是Windows系统

PE结构(Portable Executable),即可移植可执行文件格式,是Windows操作系统下的一种可执行文件格式。它定义了Windows操作系统中可执行文件(如EXE、DLL、SYS等)的结构和组织方式。PE结构的设计使得这些文件可以在不同的Windows平台上运行,因此得名“可移植”。

这个是比较官方的,其实说白了,就是Windows的可执行程序,

这里说一下可执行文件不仅仅只有exe,dll sys也是哈。这个没啥好说的,网上一堆给你说什么是可执行程序的,又是各种概念我觉得没啥必要学

这里直接开始吧,先说一下PE学了有啥用,说白了就是能更牛逼,能让你准确定位到全局变量到地址,因为全局变量一般都是编译到时候就确定了地址了,所以这里就非常有用了。

对于PE我学的是一个收费到课程,当然网上有很多免费到。可以学一下 比如滴水三期,海哥讲的,这个是都非常推荐到。

我们 先打开一个Pe文件看一下吧。

image

请仔细观察我所标记的。首先0x5A4d(小端存储),是MZ标记,MZ是一个牛逼大佬的名字,其他的没必要知道,这也是判断PE文件的一个标记,如果前两个字节没问题的话,我们就直接去0x3C的位置去找一个四字节数据, 这个是NT头的首地址,也就是PE标记,如果这个没问题的话,就说明这是一个PE文件了。

补充一些基础

首先就是如何打开文件并把文件写入到内存中去。这里直接贴代码吧 就不自己写了。

	FILE* pFile = fopen(FILE_PATH, "rb");
	if (!pFile)
	{
		log_error("open file faild!");
		return NULL;
	}
	log_info("open file success!");
	// 获取文件大小
	fseek(pFile,0, SEEK_END);
	size_t nFileSize = ftell(pFile);
	fseek(pFile, 0, SEEK_SET);
	PCHAR buff = calloc(1, nFileSize);
	if (NULL == buff)
	{
		log_error("calloc faild");
		fclose(pFile);
		return NULL;
	}
	size_t s = fread(buff, nFileSize, 1, pFile);
	if (s <= 0)
	{
		log_error("read file error!");
		fclose(pFile);
		return NULL;
	}

	fclose(pFile);
	return buff;

这个代码是我写的不保证一定对,但是可以看看

日志文件推荐:https://github.com/rxi/log.c

其次就是结构体指针那一块了,我很久之前写过,这里我就不写了

IMAGE_NT_HEAD

首先IMAGE_NT_HEAD 是一个结构体,定义如下

typedef struct _IMAGE_NT_HEADERS {
    DWORD Signature; 							// PE标记 0x0000 4550
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER32 OptionalHeader;		// 标准PE头 大小固定位0x14个字节
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;		// 扩展PE头 32位大小默认位0xE0

typedef struct _IMAGE_NT_HEADERS64 {
    DWORD Signature;
    IMAGE_FILE_HEADER FileHeader;				// 标准PE头 大小固定位0x14个字节
    IMAGE_OPTIONAL_HEADER64 OptionalHeader;		// 扩展PE头 32位大小默认位0xF0
} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;

这里要注意。32位与64位大小不一致。后面深入解析就可以知道了。下面我们继续说。介绍每一项的功能

Signature: PE文件标记,如果该值为0x4050,如果不是该值程序将无法启动

FileHeader :标准PE头 指向 IMAGE_FILE_HEADER 结构体

OptionalHeader: 扩展PE头 指向 IMAGE_OPTIONAL_HEADER32/IMAGE_OPTIONAL_HEADER64结构体

其中标准PE头与扩展PE头在看到这里的时候无需深究。说到这里。其实我们就有了一个大概的印象

当我们把一个二进制文件,使用16位进行读取时。我们首先要查看前两个字节,必须是4D5A如果不是则该文件不是PE。如果是的话 就看3C位置,3C位置指向一个地址,我们直接去到该地址,改地址的值是一个0x4550则说明是一个PE文件代码如下。

BOOL CheckPeFile(PCHAR fileBuff)
{
	PIMAGE_DOS_HEADER pImgDosBuf = (PIMAGE_DOS_HEADER)fileBuff;
	if ((WORD)pImgDosBuf->e_magic != IMAGE_DOS_SIGNATURE)
	{
		return FALSE;
	}
	DWORD dwOffset = pImgDosBuf->e_lfanew;
	PIMAGE_NT_HEADERS pImgNtHead = (PIMAGE_NT_HEADERS)(fileBuff + dwOffset);
	if (pImgNtHead->Signature != IMAGE_NT_SIGNATURE)
	{
		return FALSE;
	}
	return TRUE;
}

代码中用到了两个宏分别位 IMAGE_DOS_SIGNATURE 和 IMAGE_NT_SIGNATURE

他们的意思我们可以看一下

#define IMAGE_DOS_SIGNATURE                 0x5A4D      // MZ
#define IMAGE_OS2_SIGNATURE                 0x454E      // NE
#define IMAGE_OS2_SIGNATURE_LE              0x454C      // LE
#define IMAGE_VXD_SIGNATURE                 0x454C      // LE
#define IMAGE_NT_SIGNATURE                  0x00004550  // PE00

其实就是几个十六进制的数。这里就不说了。

这里要注意一点,先解引用再转换和先转换再解引用的结果不一致,原因这里就不提了,如果不知道的话记得回去复习一下。这里再提一嘴,我再从Cpplinux服务器开发的代码习惯转变为Win32的开发上来,所以代码可能不规范别介意。

标签:pFile,Windows,IMAGE,PE,初识,SIGNATURE,NT
From: https://www.cnblogs.com/blogwr/p/18617842/1-pe-first-knowledge-z13f8bs

相关文章

  • OpenCL 编程步骤 2. 获取设备
    clGetDeviceIDs查询支持OpenCL设备列表:cl_intclGetDeviceIDs(cl_platform_idplatform,cl_device_typedevice_type,cl_uintnum_entries,cl_device_id*devices,......
  • 基于OpenCV和Python的人脸识别系统
    一、系统概述基于OpenCV和Python的人脸识别系统利用先进的算法和工具,提供高效、准确的人脸识别服务。该系统可以应用于安全监控、门禁系统、移动支付、智能设备解锁等多个场景,具有广泛的应用价值和商业价值。二、核心组件OpenCV:OpenCV是一个开源的计算机视觉和机器学习......
  • openGauss 安装记录 lite 版本
    exportLANG=zh_CN.UTF-8#创建用户useraddpostgrespasswdpostgres#12345678mkdir/opt/guassdbtar-zxvfopenGauss-Lite-5.0.2-CentOS-x86_64.tar.gz-C./guassdb/chown-Rguass:guass/opt/guassdbvim/etc/selinux/configSELINUX=disabledsetenforce0......
  • 初识C语言——C语言的常见概念(下)
    初识C语言——C语言的常见概念(下)在上一章,我们认识了C语言的概念、历史、使用方法。在对C语言有了初步的了解之后,我们可以来写下我们的第一个C语言程序啦!......
  • FFmpeg 安装教程(Windows 系统)
    1.前言FFmpeg是一个用于处理视频、音频等多媒体文件的开源工具包。它支持几乎所有的多媒体格式转换、剪辑和编辑,是开发者和多媒体工作者必备的工具。本文详细讲解如何在Windows系统上安装FFmpeg并进行基本配置。2.下载FFmpeg安装包打开DpwnloadFFmpeg官网,选择安......
  • spring boot使用Jwt令牌时出现 java.lang.NoClassDefFoundError: javax/xml/bind/Data
    问题根源    在Java9及更高版本中,Java平台经历了模块化系统(Jigsaw项目)的重大变化。作为这一变化的一部分,某些API被移出了默认的JDK发行版,其中包括JAXB(JavaArchitectureforXMLBinding)API。因此,在使用这些被移除的API时,如果应用程序或库没有适当地包......
  • 查看pom相关的所有properties定义
    要在一个Maven项目中查找所有继承树(parent)中的POM文件下 properties 节点定义的属性,你可以使用IntelliJIDEA开发工具,通过以下步骤实现:方法一:手动检查打开项目:在IntelliJIDEA中打开你的Maven项目。查看当前POM的继承关系:打开项目的 pom.xml 文件。......
  • renben-openstack-keystone操作
    controller节点操作source/root/keystonerc_admin1.查看openstack中keystone的endpointopenstackendpointlist+----------------------------------+-----------+--------------+--------------+|ID|Region|ServiceName|ServiceT......
  • OpenCL 编程步骤 1. 获取平台
    参考OpenCL平台clGetPlatformIDs使用如下函数查询来获得系统平台列表:cl_intclGetPlatformIDs(cl_uintnum_entries,cl_platform_id*platforms,cl_uint*num_platforms)在OpenCL程序中,上述函数可以调用两次:......
  • renben-安装OpenStack报错处理1
    1.执行packstack--gen-answer-file=openstack.txt报错内容如下解决方法:查找computer或者controller节点的源有没有设置正确,源目录只保留OpenStack源其他的备份到bak目录中 2.controller节点操作  source/root/keystonerc_admin查看openstack中keystone的end......