【THM】Dissecting PE Headers(剖析PE标头)-学习
本文相关的TryHackMe实验房间链接:https://tryhackme.com/room/dissectingpeheaders
本文相关内容:了解可移植可执行(PE)文件及其标头的工作原理。
简介
在 Windows 操作系统中,你可能经常会看到扩展名为.exe的文件,这里的.exe扩展名代表可执行(executable)文件。顾名思义,可执行文件包含可以被执行的代码,任何需要在Windows操作系统上运行的东西都是通过使用可执行文件来实现被执行的。
可执行文件也可以被称为PE(可移植可执行)文件,因为它是可移植的,可以在任何Windows系统上运行。PE文件是一个具有通用对象文件格式(COFF)的数据结构,此处的COFF(Common Object File Format)包括了Windows PE文件、DLLs文件、Linux中的共享对象以及ELF文件,在本文内容中,我们仅讨论WIndows PE文件。
了解PE文件对于学习恶意软件分析至关重要,在本文中,我们将简单介绍以下概念:
- 了解PE文件中的不同标头;
- 学习如何读取PE标头;
- 怎样识别加壳的可执行文件;
- 如何使用PE标头中的信息来分析恶意软件。
在学习本文内容之前,建议先阅读或复习以下内容:
PE标头概述
在计算机磁盘上,PE可执行文件看起来与任何其他形式的数字数据相同,都是bit(位)的组合。如果我们在Hex(十六进制)编辑器中打开一个PE文件,我们将看到一堆随机的十六进制字符,这堆十六进制字符即是WIndows操作系统执行该二进制文件所需的指令。
tips:在通常情况下,"计算机磁盘" 指的是硬盘,也被称为硬盘驱动器(Hard Disk Drive,HDD);硬盘是一种用于存储数据的非易失性存储设备,它使用磁性表面来存储数据,硬盘通常是计算机中的主要存储设备,主要用于存储操作系统、应用程序和用户数据等。
在下文中,我们将尝试理解以上截图中的十六进制数,并按照WIndows理解的方式描述它们,然后我们还将讨论如何利用这些信息来进行恶意软件分析。
当我们在Hex编辑器中查看PE文件时,我们会发现手动解释所有数据过于乏味,因此,我们可以使用pe-tree
工具来帮助我们分析PE标头。使用pe-tree
工具打开PE文件时,我们将看到如下图所示的类似内容:
tips:pe-tree redline
,redline是某个可疑文件的名称。
在上图的右侧面板中,我们可以看到一些树状结构下拉菜单,而上图的左侧面板则是右侧下拉菜单的快捷方式。
我们将在下文内容中讨论的重要PE标头包括:
- IMAGE_DOS_HEADER:DOS头
- IMAGE_NT_HEADERS:NT头
- Signature:标识(签名)
- FILE_HEADER:文件头
- OPTIONAL_HEADER:可选头(扩展头)
- IMAGE_SECTION_HEADER:区段头(节表头)
- IMAGE_IMPORT_DESCRIPTOR:导入表(导入描述符)
所有这些PE标头的数据类型都是STRUCT,struct是一种由用户定义的数据类型,它能将多种不同类型的数据元素组合在一个变量中,由于它是用户定义的,所以我们需要查看文档来了解每个STRUCT(结构体)变量的类型。每个PE标头的文档都可以在MSDN上找到,我们可在相关文档中查看到这些标头内不同字段的数据类型。
请记住,虽然我们在了解FE格式时会使用一些工具,这些工具往往也有很多替代方案,但是我们的目标并不是了解工具,而是了解PE格式,以便我们可以在需要的时候使用任何相关工具来执行相同的分析。
接下来,让我们继续阅读下文内容,并简单了解PE文件的每个组成部分。
答题
阅读本小节内容,并回答以下问题。
IMAGE_DOS_HEADER和DOS_STUB
部署并访问实验虚拟机
我们可以在与本文相关的THM实验房间中一键部署实验环境:
完成环境部署之后,我们可以使用浏览器内置分页访问实验虚拟机,或者使用以下凭据通过本地Kali攻击机远程登录到实验虚拟机:
- Username:
ubuntu
- Password:
123456
我们在实验虚拟机的桌面上可以找到一个名为Samples的目录,在此目录下有一些PE文件,我们可以使用十六进制编辑器(如wxHexEditor)来打开名为redline的文件,从而查看该PE文件的十六进制内容。在实验虚拟机中,我们可以使用以下方式找到 wxHexEditor
实用程序:
tips:点击虚拟机左上角的菜单,搜索wxHexEditor即可。
redline示例PE文件在十六进制编辑器中的显示内容如下所示:
由于上述十六进制内容看起来有点太复杂而且难以理解,因此我们可以尝试使用pe-tree工具来查看redline示例PE文件的PE标头,具体命令如下所示:
#使用pe-tree工具查看redline的PE标头信息
pe-tree Desktop/Samples/redline
tips:pe-tree的输出结果可能需要我们等待几分钟才能加载完成。
如上图的pe-tree输出界面所示,我们可以在pe-tree的右侧面板中看到关于示例PE文件的一些基本信息。
在pe-tree输出界面的右侧面板的开头部分,我们可以看到PE文件的大小、文件哈希值、熵值、体系结构和编译日期,这些信息是从PE标头的不同部分经过计算或提取才得到的;紧随右侧面板开头信息之后的才是PE标头的内容,第一个是IMAGE_DOS_HEADER。
IMAGE_DOS_HEADER
IMAGE_DOS_HEADER(DOS头)由PE文件的前64个字节组成,我们将在下面分析IMAGE_DOS_HEADER中发现的一些有价值的信息。下面的屏幕截图突出显示了十六进制编辑器中的IMAGE_DOS_HEADER。
在上述截图中,我们可以看到最前面的两个字节 4D 5A
,它们可以被转换为ASCII格式的字符MZ
(这会在上面的十六进制编辑器中的右侧窗格显示)。
MZ字符所表示的是Mark Zbikowski的首字母缩写,他是创建MS-DOS文件格式的Microsoft架构师之一。MZ字符是可移植可执行(PE)格式的标识符,当这两个字符出现在文件所对应的Hex内容的开头时,Windows操作系统就会将该文件视为可移植可执行(PE)格式文件。
我们可以在pe-tree输出界面中展开示例PE文件所对应的IMAGE_DOS_HEADER下拉菜单:
请注意上图中的IMAGE_DOS_HEADER下拉菜单中的第一个条目,它显示了e_magic
所对应的值为0x5a4d MZ
,这与我们在十六进制编辑器中所看到的相同,但是由于endianness(字节序)的原因,PE Tree中的字节值将与十六进制编辑器中的字节值顺序相反。
tips:Intel x86架构使用的是little-endian(小端字节序)格式,而ARM架构使用的是big-endian(大端字节序)格式。
IMAGE_DOS_HEADER中最后一个条目是e_lfanew
,在上述PE Tree报告中,它的值为0x000000d8
,表示的是IMAGE_NT_HEADERS的开始地址。因此,我们可以得知在上述示例PE文件中,IMAGE_NT_HEADERS将从地址0x000000d8
处开始。下面的十六进制编辑器将突出显示IMAGE_NT_HEADERS的起始地址值。
tips:因为endianness(字节序)的原因,我们在pe-tree 实用程序报告中看到的字节顺序会与我们在十六进制编辑器中看到的字节顺序不同。
除了上文提及的这些字段之外,IMAGE_DOS_HEADER通常没有多大用处,特别是在针对恶意软件进行逆向工程期间。
注:IMAGE_DOS_HEADER存在的唯一原因是为了维护MS-DOS和Windows之间的向后兼容性。
DOS_STUB
在pe-tree实用程序的报告中,我们可以看到IMAGE_DOS_HEADER之后的下拉菜单是DOS STUB,让我们展开一下该下拉菜单的内容:
DOS STUB会包含我们在十六进制编辑器中看到的信息 !This program cannot be run in DOS mode
,请注意,pe-tree在此部分(DOS STUB)中所显示的大小(Size)、哈希值和熵(Entropy)与示例PE文件无关,这些信息只适用于我们正在分析的特定部分,而且这些值是根据特定标头中的数据计算得出的,不包含在PE标头内。
在pe-tree报告中,DOS STUB中的Size值表示的是此部分的大小(以字节为单位),然后MD5、SHA1和SHA256所对应的是此部分的不同哈希值,而熵值所代表的则是数据的随机性大小,熵值越高,数据的随机性就越强。
DOS STUB(DOS存根)是一小段代码,仅当PE文件与当前正在运行的系统不兼容时才会出现,它会显示“!This program cannot be run in DOS mode”消息。由于我们在上文中所介绍的示例PE文件是一个WIndows可执行文件,所以如果此示例文件在MS-DOS中运行,那么该文件将会通过DOS STUB显示提示消息,然后立即退出执行。
答题
阅读本小节内容,并回答以下问题。
使用实验虚拟机,在终端界面使用pe-tree工具分析Desktop/Samples/zmsuz3pinwl样本文件,然后找到示例PE文件中的IMAGE_NT_HEADERS的起始地址值。
#先使用pe-tree分析样本文件,然后再检查IMAGE_DOS_HEADER中e_lfanew所对应的值,即可得到示例PE文件的IMAGE_NT_HEADERS的开始地址。
cd Desktop/Samples/
pe-tree zmsuz3pinwl
等待一段时间......
在pe-tree分析报告中,检查IMAGE_DOS_HEADER
中的e_lfanew
字段值:
PE文件zmsuz3pinwl的IMAGE_NT_HEADERS的开始地址是:0x000000f8
IMAGE_NT_HEADERS
在本小节中,我们将讨论IMAGE_NT_HEADERS的不同组成部分,我们可以在相关微软文档中找到关于IMAGE_NT_HEADERS的详细信息。
此标头(IMAGE_NT_HEADERS)将包含与PE文件相关的大部分重要信息,在pe-tree实用程序中,IMAGE_NT_HEADERS下拉菜单将如下所示:
NT_HEADERS
在深入了解NT_HEADERS的详细信息之前,让我们先概述一下它,NT_HEADERS由以下部分组成:
- Signature:签名
- FILE_HEADER:文件头
- OPTIONAL_HEADER:可选头
我们将在本小节中主要讨论Signature和FILE_HEADER,而OPTIONAL_HEADER则会在下一小节中进行介绍。
IMAGE_NT_HEADERS的起始地址可以在IMAGE_DOS_HEADER的 e_lfanew
中找到,在示例二进制文件redline中,我们可以看到该地址为0x000000D8
。我们将从这个偏移量开始,来了解IMAGE_NT_HEADERS。
在十六进制编辑器中,我们可以按下Ctrl+G
或者转到Edit>Go to offset,然后通过弹出的GUI窗口来定位具体地址。
在上图的GUI窗口中,我们必须确保在底部的 Type of branch
选项中选择 From beginning
并且将数据类型设置为 Hex
以获得正确的结果。
Signature
NT_HEADERS的前4个字节由签名组成,这部分我们可以在十六进制编辑器中看到,具体的Hex字节为50 45 00 00
(对应的ASCII字符为PE
)。
Signature表示的是NT_HEADER的开始,除了签名之外,NT_HEADER还包含FILE_HEADER和IMAGE_OPTIONAL_HEADER。
FILE_HEADER
FILE_HEADER包含了一些重要信息,以下截图显示了pe-tree实用程序中的FILE_HEADER。
正如我们在上面的屏幕截图中所看到的那样,FILE_HEADER具有以下字段:
- Machine:该字段所提及的是PE文件所写入的架构类型,在上述pe-tree示例中,我们可以看到架构是i386,这意味着此PE文件兼容32位Intel架构。
- NumberOfSections:PE文件包含代码、变量和其他已存储的资源等不同节,IMAGE_FILE_HEADER中的该字段所代表是PE文件的节数,在上述pe-tree示例中,我们的PE文件有五个节。
- TimeDateStamp:该字段包含二进制编译的时间和日期。
- PointerToSymbolTable和NumberOfSymbols:这些字段通常与PE文件无关,它们出现在这里是因为COFF文件头。
- SizeOfOptionalHeader:此字段包含可选标头的大小,在上述示例中,具体的大小为224字节。
- Characteristics:这是另一个关键字段,该字段所提及的是PE文件的不同特征,在上述pe-tree示例中,该字段将告诉我们PE文件已剥离重定位信息、行号和本地符号信息,它是一个可执行映像,与32位计算机兼容。
当我们使用pe-tree实用程序查看FILE_HEADER时,我们可以看到每个字段的十六进制值也会显示在pe-tree实用程序中。这些字段内容我们也可以在下面的十六进制编辑器中找到:
如果想了解有关FILE_HEADER的更多信息,可以查看Microsoft相关文档。
答题
阅读本小节内容,并回答以下问题。
使用实验虚拟机,在终端界面使用pe-tree工具分析Desktop/Samples/zmsuz3pinwl样本文件(和上一小节中的实践操作一样):
cd Desktop/Samples/
pe-tree zmsuz3pinwl
在pe-tree分析报告中,查看FILE_HEADER中的内容:
32BIT_MACHINE
0x62289d45 Wed Mar 9 12:27:49 2022 UTC
OPTIONAL_HEADER
OPTIONAL_HEADER也是NT_HEADERS的一部分,它包含PE标头中存在的一些最重要的信息,让我们看看它在pe-tree实用程序中是什么样子:
在十六进制编辑器中,OPTIONAL_HEADER将在FILE_HEADER末尾之后开始,我们可以在Hex编辑器中看到示例二进制文件redline的OPTIONAL_HEADER的开头。
让我们了解一下OPTIONAL_HEADER中的一些关键字段:
- Magic:Magic数字会表明PE文件是32位应用程序还是64位应用程序,如果值为0x010B,则代表32位应用程序,如果值为0x020B,则代表64位应用程序。
- AddressOfEntryPoint:从恶意软件分析/逆向工程的角度来看,该字段很重要,这是Windows开始执行的地址,换句话说,PE文件要被执行的第一条指令会出现在该地址处;这是一个相对虚拟地址(RVA),意味着一旦文件被加载到内存中,它就位于相对于映象基址(ImageBase)的一定偏移量处。
- BaseOfCode 和 BaseOfData:这些字段分别是相对于ImageBase(基地址)的代码节、数据节的地址。
- ImageBase:ImageBase(基地址)是PE文件在内存中的首选加载地址,通常.exe文件的基地址是0x00400000,我们的PE文件也是如此;由于Windows无法加载此首选地址处的所有PE文件,因此当文件被加载到内存中时,需要按顺序进行一些重定位处理,并且是相对于ImageBase执行这些重定位。
- Subsystem:该字段表示运行映像所需的子系统,可以是原生WIndows、GUI(图形用户界面)、CUI(命令行用户界面)或其他一些子系统;在上述示例中,所显示的Subsystem字段的值为0x0002,代表的是Windows GUI子系统;关于子系统的完整列表,可以在Microsoft相关文档中找到。
- DataDirectory:DataDirectory(数据目录)是一个包含PE文件的导入、导出信息(也被称为导入地址表和导出地址表)的结构体,此信息能让我们了解PE文件可能试图执行的操作,我们将在下文中简单介绍PE文件的import(导入)信息。
tips:虚拟地址(VA)=基地址+相对虚拟地址(RVA)。
虽然OPTIONAL_HEADER中还有更多信息,但我们在此不继续深入研究,如果想了解OPTIONAL_HEADER的更多信息,请查看关于此标头的Microsoft相关文档。
答题
阅读本小节内容,并回答以下问题。
使用实验虚拟机,在终端界面使用pe-tree工具分析Desktop/Samples/zmsuz3pinwl样本文件(和上一小节中的实践操作一样):
cd Desktop/Samples/
pe-tree zmsuz3pinwl
在pe-tree分析报告中,查看OPTIONAL_HEADER中的Subsystem字段:
0x0003 WINDOWS_CUI
IMAGE_SECTION_HEADER
PE文件执行其功能所需的数据,如代码、图标、图像、用户界面元素等,被存储在不同的PE节中;我们可以在IMAGE_SECTION_HEADER中找到有关这些PE节的信息。在pe-tree实用程序界面中,会显示IMAGE_SECTION_HEADER中的每个单独的PE节,具体情况如下图所示:
正如我们在上图中所看到的那样,IMAGE_SECTION_HEADER有不同的节,上图显示了五个节 .text
、.rdata
、.data
、.ndata
和.rsrc
。
在了解每个节标头中的具体信息之前,让我们先了解一下PE文件中有哪些常见的节:
- .text:.text节通常会包含应用程序的可执行代码,如上述pe-tree示例所示,此节的Characteristics字段值包括了CODE、EXECUTE和READ,也就是说该节包含了可执行代码,可以读取但不能写入。
- .data:此节包含应用程序的初始化数据,它具有READ/WRITE(读/写)权限,但没有EXECUTE(执行)权限。
- .rdata/.idata:这些节通常包含了PE文件的导入(import)信息,导入信息是指PE文件将要从其他文件或者WIndows API中导入哪些函数。
- .ndata:.ndata节包含了未初始化的数据。
- .reloc:此节包含了PE文件的重定向信息。
- .rsrc:此节代表的是resource(资源)节,包含了图标、图像或者应用程序UI所需的其他资源。
现在我们知道了PE文件中常见的不同类型的PE节,让我们看看每个节的节标头中包含了哪些重要信息:
- VirtualAddress:此字段表示该节在内存中的相对虚拟地址(RVA-Relative Virtual Address)。
- VirtualSize:此字段表示被加载到内存之后该节的具体大小。
- SizeOfRawData:此字段表示PE文件被加载到内存之前存储在磁盘上的节大小。
- Characteristics:此字段(Characteristics特征)告诉我们该节所具有的权限,例如,该节可能具有READ、WRITE或者EXECUTE权限。
答题
阅读本小节内容,并回答以下问题。
使用实验虚拟机,在终端界面使用pe-tree工具分析Desktop/Samples/zmsuz3pinwl样本文件(和上一小节中的实践操作一样):
cd Desktop/Samples/
pe-tree zmsuz3pinwl
在pe-tree分析报告中,查看IMAGE_SECTION_HEADER
中的内容:
zmsuz3pinwl文件有多少PE节:7个
zmsuz3pinwl文件的.rsrc节有什么特征:0xe0000040 INITIALIZED_DATA | EXECUTE | READ | WRITE
IMAGE_IMPORT_DESCRIPTOR
PE文件不会包含执行其功能所需的所有代码。在WIndows操作系统中,PE文件经常会利用Windows API中的代码来执行许多功能。
IMAGE_IMPORT_DESCRIPTOR结构体会包含有关PE文件在执行时所加载的不同Windows API的信息,此信息有助于识别PE文件可能会执行的潜在活动;例如如果一个PE文件导入了CreateFile API,那么就表明该PE文件在被执行时可能会创建一个文件。
下图是IMAGE_IMPORT_DESCRIPTOR在pe-tree实用程序中的样子。
如上图所示,我们可以看到示例PE文件会从ADVAPI32.dll、SHELL32.dll、ole32.dll、COMCTL32.dll和USER32.dll中导入函数。这些dll是动态链接库文件,可以为了其他PE文件导出Windows函数或API。
上面的截图显示示例PE文件导入了一些可以执行某些注册表操作的函数,如果想了解有关这些函数的更多信息,我们可以查看相关的Microsoft文档;例如,我们可以通过查看Microsoft相关文档,来了解关于RegCreateKeyExW函数的详细信息。
在上述截图中,我们还能看到OriginalFirstThunk和FirstThunk字段的值,操作系统会利用这些值来构建PE文件的导入地址表(IAT-Import Address Table)。
通过研究PE文件的导入函数,我们就可以识别PE文件可能会执行的一些活动。
以实验虚拟机中的redline二进制文件为例,通过查看它的IMAGE_IMPORT_DESCRIPTOR信息,我们可以知道该文件从kernel32.dll中导入了一些值得我们关注的函数,例如CreateProcessW、CreateDirectoryW和WriteFile;这意味着该PE文件打算创建一个进程,创建一个目录,并将一些数据写入文件,同样,我们还可以继续研究其余的导入信息,从而大概地识别此PE文件所试图执行的一些其他活动。
答题
阅读本小节内容,并回答以下问题。
使用实验虚拟机,在终端界面使用pe-tree工具分析Desktop/Samples/redline样本文件:
cd Desktop/Samples/
pe-tree redline
在pe-tree分析报告中,查看IMAGE_IMPORT_DESCRIPTOR
中的信息(找到CreateWindowExW):
USER32.dll
加壳以及识别加壳的可执行文件
由于我们可以使用十六进制编辑器或者pe-tree等工具来轻松地提取PE文件的信息,因此对于那些不希望其代码被逆向工程的人来说,这是他们所不期望的。这个时候,加壳器就有了用武之地,加壳器是一种用于混淆PE文件中数据的工具,经过它处理的文件无法在不脱壳的情况下被读取数据。
简而言之,加壳器会针对PE文件进行混淆处理以实现加壳目的,这在一定程度上能够避免PE文件被逆向工程,并能使针对PE文件的静态分析变得无用。当加壳的PE文件被执行时,它会自动运行脱壳例行程序以提取原始代码,然后再执行它。合法的软件开发人员可以使用加壳来解决盗版问题,恶意软件作者也可以使用加壳来规避检测。那么我们应该如何判断PE文件是否被加壳呢?在本小节中,我们将简单介绍两种用于识别加壳PE文件的方式。
通过节标头识别
在上文中,我们已经了解到,PE文件通常有.text节、.data节和.rsrc节等,其中只有.text节设置了执行标志,因为该节包含代码。
现在以实验虚拟机中的样本文件zmsuz3pinwl为例,当我们使用pe-tree分析这个文件时,我们可以发现该文件具有非常规的PE节名称(例如节名称为空)。
为了排除工具的干扰因素,我们可以使用另一个PE分析工具pecheck来检查上述样本文件。pecheck工具能够提供的信息会与我们从pe-tree工具中收集的信息相同,但是它是一个命令行工具,我们可以在实验虚拟机中使用终端导航到Desktop\Samples目录,然后执行以下命令来运行pecheck:
#cd Desktop\Samples
pecheck zmsuz3pinwl
让我们看看上述命令输出结果中的PE节标头中的信息:
#使用PECheck实用程序
user@machine$ pecheck zmsuz3pinwl
PE check for 'zmsuz3pinwl':
Entropy: 7.978052 (Min=0.0, Max=8.0)
MD5 hash: 1ebb1e268a462d56a389e8e1d06b4945
SHA-1 hash: 1ecc0b9f380896373e81ed166c34a89bded873b5
SHA-256 hash: 98c6cf0b129438ec62a628e8431e790b114ba0d82b76e625885ceedef286d6f5
SHA-512 hash: 6921532b4b5ed9514660eb408dfa5d28998f52aa206013546f9eb66e26861565f852ec7f04c85ae9be89e7721c4f1a5c31d2fae49b0e7fdfd20451191146614a
entropy: 7.999788 (Min=0.0, Max=8.0)
entropy: 7.961048 (Min=0.0, Max=8.0)
entropy: 7.554513 (Min=0.0, Max=8.0)
.rsrc entropy: 6.938747 (Min=0.0, Max=8.0)
entropy: 0.000000 (Min=0.0, Max=8.0)
.data entropy: 7.866646 (Min=0.0, Max=8.0)
.adata entropy: 0.000000 (Min=0.0, Max=8.0)
.
.
.
----------PE Sections----------
[IMAGE_SECTION_HEADER]
0x1F0 0x0 Name:
0x1F8 0x8 Misc: 0x3F4000
0x1F8 0x8 Misc_PhysicalAddress: 0x3F4000
0x1F8 0x8 Misc_VirtualSize: 0x3F4000
0x1FC 0xC VirtualAddress: 0x1000
0x200 0x10 SizeOfRawData: 0xD3400
0x204 0x14 PointerToRawData: 0x400
0x208 0x18 PointerToRelocations: 0x0
0x20C 0x1C PointerToLinenumbers: 0x0
0x210 0x20 NumberOfRelocations: 0x0
0x212 0x22 NumberOfLinenumbers: 0x0
0x214 0x24 Characteristics: 0xE0000040
Flags: IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE
Entropy: 7.999788 (Min=0.0, Max=8.0)
MD5 hash: fa9814d3aeb1fbfaa1557bac61136ba7
SHA-1 hash: 8db955c622c5bea3ec63bd917db9d41ce038c3f7
SHA-256 hash: 24f922c1cd45811eb5f3ab6f29872cda11db7d2251b7a3f44713627ad3659ac9
SHA-512 hash: e122e4600ea201058352c97bb7549163a0a5bcfb079630b197fe135ae732e64f5a6daff328f789e7b2285c5f975bce69414e55adba7d59006a1f0280bf64971c
.
.
.
我们还是能够看到出现了没有名称的PE节,这说明我们用于分析PE文件的工具并没有出现故障。
我们还可能会注意到的另外一件事是,.data节和四个未命名的节中的三个节的熵值都高于7且接近8,更高的熵值代表数据具有更高层次的随机性,而随机数据通常会在原始数据被混淆时生成,因此出现这些值可能就表示了相关可执行文件经过了加壳处理。
除了PE节名称之外,另一个能表示可执行文件被加壳的指标是每个节的权限。对于上述样本文件zmsuz3pinwl,我们可以看到它的第一个PE节(该节无名称)中包含了初始化数据,并具有READ、WRITE和EXECUTE权限,同样,该文件的其他一些节中也具有READ、WRITE和EXECUTE权限;这种情况在普通的未被加壳的PE文件中并不会出现,在正常的PE文件中(例如上文提到的redline样本),只有.text节具有EXECUTE权限。
节标头中可用于识别加壳的可执行文件的另一个有价值的信息是SizeOfRawData和Misc_VirtualSize。如果现在有一个加壳的可执行文件,那么在它具有写入和执行权限的无名PE节中,SizeOfRawData字段值将始终明显小于Misc_VirtualSize字段值,这是因为当PE文件在执行过程中进行脱壳时,文件会将数据写入到此节。
tips:因为加壳的可执行文件在执行时会自动脱壳,此时文件会写入数据到特定的PE节中,所以与磁盘上的size相比,我们需要增加特定PE节在内存中的Size。
通过导入函数识别
我们还可以通过查看PE文件的导入函数来识别加壳的可执行文件。在上文中,我们所分析的PE样本文件redline导入了很多函数,这些函数将表明redline可能会执行的活动。
然而,对于加壳的PE文件zmsuz3pinwl,我们只能看到少量导入信息,同时我们将重点关注GetProcAddress、GetModuleHandleA和LoadLibraryA等函数,这些函数通常会是加壳的可执行文件需要使用的一些导入函数,因为它们提供了在运行时脱壳PE文件的功能。
总而言之,当我们查看某PE文件的PE标头数据时,如果出现以下迹象则表明相关文件为加壳的可执行文件:
- 非常规的PE节名称;
- 多个PE节具有EXECUTE权限;
- 某些PE节的熵(Entropy)值偏高,熵值接近8;
- 某些PE节的SizeOfRawData字段值与Misc_VirtualSize字段值之间存在显著差异;
- PE文件的导入函数很少(同时还具有一些特定的导入函数)。
答题
阅读本小节内容,并回答以下问题。
使用实验虚拟机,在终端界面使用使用PECheck工具分析Desktop/Samples/zmsuz3pinwl样本文件:
cd Desktop/Samples/
pecheck zmsuz3pinwl
在pecheck工具的输出结果中,检查是否存在一些可用于识别加壳的PE文件的指标:
- 非常规的PE节名称(例如名称为空);
- 多个PE节具有EXECUTE权限;
- 某些PE节的熵(Entropy)值偏高,熵值接近8;
- 某些PE节的SizeOfRawData字段值与Misc_VirtualSize字段值之间存在显著差异;
- PE文件的导入函数很少(同时还具有一些特定的导入函数)。
本文小结
通过学习本文相关内容,我们能够了解到:
- 什么是PE标头;
- PE标头有哪些不同组成部分;
- 如何从PE标头中读取信息;
- 如何使用PE标头来识别加壳的可执行文件。
本文相关知识点还停留在比较初级的阶段,读者还需继续进行更加深入的学习和实践。