-
-
[原创]解析PE结构之-----导出表
-
发表于: 2010-10-19 14:15 17235
-
在PE结构中最复杂的就是PE结构中的16个目录,如导入目录,导出目录,重定位目录,资源目录等等。对于病毒分析来说,最为重要的是导入目录和导出目录。在我的手写可执行程序的文章中已经介绍了导入目录。此篇文章将介绍导出目录。
我们知道,一个Windows程序,它所实现的所有功能最终几乎都是调用系统DLL提供的API函数。通过我先前文章手写的Hello World程序可以看出,要使用任何一个DLL所提供的函数,我们需要将它导入,也就是用到了导入表。然而对于那些提供了被导出的函数的DLL程序来说,他们必须使用导出表将函数导出,之后别的程序才可以使用。无论是系统提供的标准DLL还是个人编写的DLL,只要想提供自己的函数给别人使用就必须建立导出表。一般使用任何开发环境编写具有导出功能的程序,导出表都是由链接器自动建立的。程序员只需指定被导出的函数名称或序号即可。在这里我不打算自己构造导出表(对于导入表的学习,我选择了自己构造------在先前手写可执行程序文章中。在此不再使用此方法,而是直接分析现成的导出表进行学习。)这里我们将分析一个自己编写的DLL文件的导出表,从而学习他。
一个函数被导出通常有两种方法:一、仅以序号的方式导出 二、同时以序号和名称的方式导出。
首先使用VC++6.0编写一个DLL程序,该程序导出了两个函数,fnDll1和fnDll2。其中第一个函数使用序号导出,导出序号是1,第二个函数同时使用序号和名称导出,导出序号为2,导出函数名称为fnDll2。该DLL程序导出模块名为DLL.dll。编写的vc代码如下:
#include "stdafx.h"
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
return TRUE;
}
void fnDll1()
{
}
void fnDll2()
{
}
其中的def文件的内容如下:
LIBRARY DLL
EXPORTS
fnDll1 @ 1 NONAME
fnDll2 @ 2
下面我们分析一下这个DLL文件的导出表是如何构造的。首先使用十六进制编辑工具将这个文件打开,这里我们使用VC++6.0自带的十六进制编辑工具将其打开。如图1所示:
图1 用十六进制编辑器打开DLL文件
由图1所示可以看到DLL.dll程序内容。根据先前手写可执行程序学习的PE结构的知识,我们定位到PE结构中的导出目录,如图1中被选中的部分即为导出目录。从中可以得知导出表的位于偏移0x2e070处,大小为0x152字节。然后在编辑器中按快捷键Ctrl+G,即出现Go To对话框,如图2所示:
图2 搜索地址
输入0x0002e070,然后单击Go To按钮即可到达0x0002e070地址处,如图3所示:
图3 导出表
如图3所示被选中的部分即为该程序的导出表。下面我们开始解析它。导出表对应一个IMAGE_EXPORT_DIRECTORY结构体。该结构体的定义如下:
typedef struct _IMAGE_EXPORT_DIRECTORY {
DWORD Characteristics;
DWORD TimeDateStamp;
WORD MajorVersion;
WORD MinorVersion;
DWORD Name;
DWORD Base;
DWORD NumberOfFunctions;
DWORD NumberOfNames;
DWORD AddressOfFunctions; // RVA from base of image
DWORD AddressOfNames; // RVA from base of image
DWORD AddressOfNameOrdinals; // RVA from base of image
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
第一个成员(Characteristics)是个DWORD类型,占四个字节。通常该值为零。
第二个成员(TimeDateStamp)DWORD类型,表示输出表创建的时间,该时间是自1970年1月1日至今的秒数。这个值通常不会影响程序执行,可以是零。
赞赏
- [原创]计算机病毒对消息钩子的利用与对抗 26907
- [推荐]病毒分析工具新版本MyMonitor3.0发布了,需要的自己去下载吧! 11734
- [原创]解析PE结构之-----导出表 17236
- [原创]再写手工打造可执行程序 138914
- [求助]Softice的问题 5360