如何判断一个文件是否是win32可执行文件
2007-04-11 16:26
711 查看
PE格式(Portable Executable)的文件即可移植的执行体,是Win32环境自身所带的执行体文件格式,如exe,dll文件。它的一些特性继承自 Unix 的Coff (common object file format)文件格式。"portable executable"(可移植的执行体)意味着此文件格式是跨win32平台的:即使Windows 运行在非Intel 的CPU 上,任何win32平台的PE装载器都能识别和使用该文件格式。当然,移植到不同的CPU上PE执行体必然得有一些改变。所有 win32执行体 (除了VxD和16位的Dll)都使用PE文件格式,包括NT的内核模式驱动程序(kernel mode drivers)。我们着重讨论的事Win32 平台下的PE文件。
所有常见的PE结构定义在winnt.h头文件中都有。我们一般关心以下几项:
IMAGE_DOS_HEADER
IMAGE_FILE_HEADER
IMAGE_OPTIONAL_HEADER32
IMAGE_SECTION_HEADER
IMAGE_NT_HEADERS
IMAGE_IMPORT_DESCRIPTOR
IMAGE_EXPORT_DIRECTORY
IMAGE_RESOURCE_DIRECTORY
首先我们看到PE文件最开头的是DOS MZ Header部分,有了它一旦程序在DOS下执行,DOS就能识别出这是有效的执行体。并且操作系统中的PE文件装载器可以通过DOS MZ Header 中的内容定位到PE Header 的起始偏移量。在这里我们最关心的部分是IMAGE_DOS_HEADER的e_lfanew这个成员,通过它我们可以找到PE Header。
紧随DOS MZ Header 部分的是DOS stub,这部分我们不关心,因为它只是为了在不支持 PE文件格式的操作系统中,简单显示一个错误提示,如" This program cannot run in DOS mode”。这个部分通常由编译器自动生成,当然程序员也可以自定义该部分的代码。
接下来是最重要的PE Header,PE Header 是PE 相关结构 IMAGE_NT_HEADERS 的简称,其中包含了许多PE 装载器用到的重要域。我们非常关心的入口点AddressOfEntryPoint 就在IMAGE_NT_HEADERS 中IMAGE_OPTIONAL_HEADER32 中。PE Header 后面的内容被称为节表,ection Table(节表)。 每个结构包含对应节的属性、文件偏移量、虚拟偏移量等。如果PE 文件里有5 个节,那么此结构数组内就有5个成员。如此PE装载器就可以根据节表定位每个节的属性和位置。PE文件的真正内容划分成块,称之为Section(节)。每节是一块拥有共同属性的数据,比如代码/ 数据、读/写等。
PE 文件有效性检查
通常的检查利用前面提到过的PE Header。PE Header实际上是一个IMAGE_NT_HEADERS STRUCT结构,定义如下:
其中的Signature属性如果是等于"PE/0/0",那么就是PE格式的文件。所以在检测时只需要先通过DOS MZ Header 中的内容定位到PE Header 的具体位置,然后通过检查Signature 即可断定一个文件是否为PE文件。
当然即使Signature 检测通过了,也可能不是一个有效的PE文件,还有各种可能性导致这个PE文件破损,可以自己分析各种不同的检测点。实际的有效性检测都是经过多年积累的对于错误文件的分析,这是一个长期的过程。
参考链接:http://www.ccwblog.cn/960slj/post/20060928/12173.htm
以下是我的简单例子源码。供参考。
#include "stdafx.h"
#include "windows.h"
int _tmain(int argc, _TCHAR* argv[])
{
HMODULE hMod = ::GetModuleHandle(NULL);
char buf[MAX_PATH];
::GetModuleFileName(hMod, buf, MAX_PATH);
printf("%s/n", buf);
PIMAGE_NT_HEADERS pe = NULL;
try{
if(::PIMAGE_DOS_HEADER(hMod)->e_magic != IMAGE_DOS_SIGNATURE) {
throw;
}
pe = ::PIMAGE_NT_HEADERS(PBYTE(hMod) + ::PIMAGE_DOS_HEADER(hMod)->e_lfanew);
if(pe->Signature != IMAGE_NT_SIGNATURE) {
pe = NULL;
}
}catch(...) {
}
printf("%lX/n", (PBYTE)pe);
return 0;
}
所有常见的PE结构定义在winnt.h头文件中都有。我们一般关心以下几项:
IMAGE_DOS_HEADER
IMAGE_FILE_HEADER
IMAGE_OPTIONAL_HEADER32
IMAGE_SECTION_HEADER
IMAGE_NT_HEADERS
IMAGE_IMPORT_DESCRIPTOR
IMAGE_EXPORT_DIRECTORY
IMAGE_RESOURCE_DIRECTORY
首先我们看到PE文件最开头的是DOS MZ Header部分,有了它一旦程序在DOS下执行,DOS就能识别出这是有效的执行体。并且操作系统中的PE文件装载器可以通过DOS MZ Header 中的内容定位到PE Header 的起始偏移量。在这里我们最关心的部分是IMAGE_DOS_HEADER的e_lfanew这个成员,通过它我们可以找到PE Header。
紧随DOS MZ Header 部分的是DOS stub,这部分我们不关心,因为它只是为了在不支持 PE文件格式的操作系统中,简单显示一个错误提示,如" This program cannot run in DOS mode”。这个部分通常由编译器自动生成,当然程序员也可以自定义该部分的代码。
接下来是最重要的PE Header,PE Header 是PE 相关结构 IMAGE_NT_HEADERS 的简称,其中包含了许多PE 装载器用到的重要域。我们非常关心的入口点AddressOfEntryPoint 就在IMAGE_NT_HEADERS 中IMAGE_OPTIONAL_HEADER32 中。PE Header 后面的内容被称为节表,ection Table(节表)。 每个结构包含对应节的属性、文件偏移量、虚拟偏移量等。如果PE 文件里有5 个节,那么此结构数组内就有5个成员。如此PE装载器就可以根据节表定位每个节的属性和位置。PE文件的真正内容划分成块,称之为Section(节)。每节是一块拥有共同属性的数据,比如代码/ 数据、读/写等。
PE 文件有效性检查
通常的检查利用前面提到过的PE Header。PE Header实际上是一个IMAGE_NT_HEADERS STRUCT结构,定义如下:
typedef struct _IMAGE_NT_HEADERS { DWORD Signature; IMAGE_FILE_HEADER FileHeader; IMAGE_OPTIONAL_HEADER32 OptionalHeader; } IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32; |
当然即使Signature 检测通过了,也可能不是一个有效的PE文件,还有各种可能性导致这个PE文件破损,可以自己分析各种不同的检测点。实际的有效性检测都是经过多年积累的对于错误文件的分析,这是一个长期的过程。
参考链接:http://www.ccwblog.cn/960slj/post/20060928/12173.htm
以下是我的简单例子源码。供参考。
#include "stdafx.h"
#include "windows.h"
int _tmain(int argc, _TCHAR* argv[])
{
HMODULE hMod = ::GetModuleHandle(NULL);
char buf[MAX_PATH];
::GetModuleFileName(hMod, buf, MAX_PATH);
printf("%s/n", buf);
PIMAGE_NT_HEADERS pe = NULL;
try{
if(::PIMAGE_DOS_HEADER(hMod)->e_magic != IMAGE_DOS_SIGNATURE) {
throw;
}
pe = ::PIMAGE_NT_HEADERS(PBYTE(hMod) + ::PIMAGE_DOS_HEADER(hMod)->e_lfanew);
if(pe->Signature != IMAGE_NT_SIGNATURE) {
pe = NULL;
}
}catch(...) {
}
printf("%lX/n", (PBYTE)pe);
return 0;
}
相关文章推荐
- 如何判断一个文件是否被关闭?
- 用WINEXEC调用一个可执行文件,如何判断执行完毕
- 判断一个文件是不是 Win32 可执行文件 VB6源代码
- shell 中如何判断前一个命令是否执行成功
- 在Linux上,如何知道一个可执行文件是否包含调试信息呢?
- 如何在shell脚本中,判断一个基本命令执行是否成功?
- 如何在shell中判断一个文件是否为空
- shell 中如何判断前一个命令是否执行成功
- java如何判断一个linux下的文件是否为链接文件。
- 判断一个文件是不是 Win32 可执行文件 VB6源代码
- bash如何判断一个文件是否存在
- C#中如何判断一个文件是否存在
- makefile中如何判断一个文件是否存在
- golang中如何判断文件是否有可执行权限
- shell 中如何判断前一个命令是否执行成功
- C语言判断一个文件是否存在,以及如何删除
- 在Linux上,如何知道一个可执行文件是否包含调试信息呢?
- makefile中如何判断一个文件是否存在
- 判断本地系统目录下是否存在XML文件,如果不存在就创建一个XMl文件,若存在就在里面执行添加数据
- 【转载】如何在shell中判断一个文件是否为空